2
votes

Élément HTML `dialog`: fait défiler le contenu indépendamment de l'arrière-plan

J'essaye d'utiliser l'élément dialog .

Lorsque la boîte de dialogue / modale est fermée, le corps doit pouvoir faire défiler.

Lorsque la boîte de dialogue / modale est ouverte, si son contenu est volumineux, la boîte de dialogue / modal doit pouvoir faire défiler.

Cependant, lorsque le dialogue / modal est ouvert, je ne veux pas que le scroll s'applique à la fois au dialogue / modal et l'arrière-plan du corps, ce qu'il semble faire par défaut.

/ p>

Exemple: https://output.jsbin.com/mutudop/3 . < / p>

Comment puis-je faire en sorte que le défilement s'applique uniquement au contenu de la boîte de dialogue / modal, lorsque la boîte de dialogue / modale est ouverte?

Remarque: je ne suis intéressé que par les solutions utilisant l'élément natif dialog .


1 commentaires

Hé, je pense que certains commentaires seraient bien. Pour autant que je puisse le voir, vous n'avez pas répondu à 2 réponses jusqu'à présent. Ils ont besoin de savoir si leurs réponses résolvent votre question ou si la réponse / votre question est / n'est plus pertinente.


3 Réponses :


-1
votes

J'ai créé un autre exemple où votre contenu principal ne fait pas défiler avec votre modal s'il est plus grand que votre contenu principal. Vous pouvez définir position sur fixed sur votre conteneur pour y parvenir.

<div id="container">
  <dialog id="my-dialog">
    <div id="my-dialog__content">
      <form method="dialog">
        <menu>
          <button id="cancel-button" value="cancel">Cancel</button>
        </menu>
      </form>
    </div>
  </dialog>

  <menu>
    <button id="open-dialog">Open Dialog</button>
  </menu>
</div>
#my-dialog {
  width: 50%;
  max-height: 50vh;
  overflow-y: auto;
}

#my-dialog__content {
  display: flex;
  flex-direction: column;
  height: 150vh;
}

menu {
  width: 100%;
  padding: 0;
  margin: 0 auto;
}

#cancel-button {
  width: 100%
}
(function() {
  var openBtn = document.getElementById('open-dialog');
  var myDialog = document.getElementById('my-dialog');

  openBtn.addEventListener('click', function() {
    if (typeof myDialog.showModal === "function") {
      myDialog.showModal();
    } else {
      alert("Dialog API not supported by browser");
    }
  });

})();

Réponse d'origine

Vous pouvez définir une hauteur max sur votre boîte de dialogue et styliser le contenu de votre boîte de dialogue en conséquence. Voir l'exemple ci-dessous.

<div id="container">
  <dialog id="my-dialog">
    <div id="my-dialog__content">
      <form method="dialog">
        <menu>
          <button id="cancel-button" value="cancel">Cancel</button>
        </menu>
      </form>
    </div>
  </dialog>

  <menu>
    <button id="open-dialog">Open Dialog</button>
  </menu>
</div>
#container {
  height: 100vh;
  width: 100vw;
  position: fixed;
  top: 0;
  left: 0;
  background: #ccc;
}

#my-dialog {
  margin-top: 1rem;
  margin-bottom: 3rem;
  top: 3rem;
  width: 50%;
  overflow-y: auto;
}

#my-dialog__content {
  display: flex;
  flex-direction: column;
  height: 200vh;
}

menu {
  width: 100%;
  padding: 0;
  margin: 0 auto;
}

#cancel-button {
  width: 100%
}
(function() {
  var openBtn = document.getElementById('open-dialog');
  var myDialog = document.getElementById('my-dialog');

  openBtn.addEventListener('click', function() {
    if (typeof myDialog.showModal === "function") {
      myDialog.showModal();
    } else {
      alert("Dialog API not supported by browser");
    }
  });

})();



-1
votes

Une solution simple est la suivante: une fois que le mnodel est affiché, créez un DIV de plus en superposition qui couvre le plein écran, à cet endroit css {pointer-events: none} et le modèle sera placé dessus. l'utilisateur ne peut pas cliquer sur le contenu du corps autre que les données du modèle.

J'ai créé un exemple: http://jsfiddle.net / z3sgvnox /

(function() {
  var openBtn = document.getElementById('open-dialog');
  var myDialog = document.getElementById('my-dialog');
var bodyData = document.getElementById('content-body');
  openBtn.addEventListener('click', function() {
    if (typeof myDialog.showModal === "function") {
      myDialog.showModal();
      bodyData.classList.add("hideScroll");
    } else {
      alert("Dialog API not supported by browser");
    }
  });

})();

CSS

#container {
  height: 100vh;
  width: 100vw;
  position: fixed;
  top: 0;
  left: 0;
  background: #ccc;
}

#my-dialog {
  margin-top: 1rem;
  margin-bottom: 3rem;
  width: 50%;
  overflow-y: auto;
      max-height: 80%;
}
.hideScroll{
  overflow:hidden;
  pointer-events:none;
}

#my-dialog__content {
  display: flex;
  flex-direction: column;
  height: 200vh;
}

menu {
  width: 100%;
  padding: 0;
  margin: 0 auto;
}

#cancel-button {
  width: 100%
}

JS:

<body id="content-body">


<div id="container">
  <dialog id="my-dialog">
    <div id="my-dialog__content">
      <form method="dialog">
        <menu>
          <button id="cancel-button" value="cancel">Cancel</button>
        </menu>
      </form>
    </div>
  </dialog>

  <menu>
    <button id="open-dialog">Open Dialog</button>
  </menu>
</div>
</body>


0 commentaires

1
votes

Je l'ai donc essayé également et j'ai trouvé ceci:

<div class="wrapper">
  <dialog>
    <div>
      <form method="dialog">
        <button value="cancel">Cancel</button>
      </form>
    </div>
  </dialog>

  <button id="open">Open Dialog</button>
</div>
* {
  box-sizing: border-box;
}

.wrapper {
  height: 10000px;
}

dialog {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  border: 0;
  z-index: 100;
  background: transparent;
  overflow-y: auto;
}

dialog>div {
  width: 50%;
  height: 500px;
  background: white;
  border: 3px solid black;
  margin: 0 auto;
  margin-top: 50px;
}

.overflow-hidden {
  overflow: hidden;
}
(function() {
  var openBtn = document.querySelector("button#open");
  var myDialog = document.querySelector("dialog");

  openBtn.addEventListener('click', function() {
    if (typeof myDialog.showModal === "function") {
      myDialog.showModal();
    } else {
      alert("Dialog API not supported by browser");
    }
  });
})();

Vous avez peut-être remarqué que j'ai ajouté deux lignes de JS pour masquer / afficher le débordement du body et vous en aurez probablement besoin comme vous pouvez ne ciblez pas le body avec du CSS pur si vous voulez vérifier si la boîte de dialogue est ouverte ou non.

Si vous ne le faites pas les voulez, vous pouvez les supprimer et cela fonctionne très bien. Cependant, vous aurez deux barres de défilement sur le côté droit. Voici à quoi cela ressemble sans le JS:

<div class="wrapper">
  <dialog>
    <div>
      <form method="dialog">
        <button onclick='document.body.classList.remove("overflow-hidden");' value="cancel">Cancel</button>
      </form>
    </div>
  </dialog>

  <button id="open">Open Dialog</button>
  <h4>You can scroll the body now but not when the dialog is opened.</h4>
</div>
* {
  box-sizing: border-box;
}

.wrapper {
  height: 10000px;
}

dialog {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  border: 0;
  z-index: 100;
  background: transparent;
  overflow-y: auto;
}

dialog>div {
  width: 50%;
  height: 500px;
  background: white;
  border: 3px solid black;
  margin: 0 auto;
  margin-top: 50px;
}

.overflow-hidden {
  overflow: hidden;
}
(function() {
  var openBtn = document.querySelector("button#open");
  var myDialog = document.querySelector("dialog");

  openBtn.addEventListener('click', function() {
    if (typeof myDialog.showModal === "function") {
      myDialog.showModal();
      document.querySelector("body").classList.add("overflow-hidden");
    } else {
      alert("Dialog API not supported by browser");
    }
  });
})();

Si vous avez besoin d'explications, faites-le moi savoir mais je pense que le code devrait être explicite.


1 commentaires

N'oubliez pas que les boîtes de dialogue peuvent être fermées avec la touche d'échappement, vous devriez donc probablement avoir un code comme celui-ci: myDialog.addEventListener ("keydown", (e) => {if (e.keyCode === 27 ) {document.body.classList.remove ("overflow-hidden");}});