HTML-элемент `dialog`: прокрутка контента независимо от фона - PullRequest
2 голосов
/ 04 мая 2019

Я пытаюсь использовать элемент dialog.

Когда диалоговое окно / модальное окно закрыто, тело должно быть прокручиваемым.

Когда диалоговое окно / модальное окно открыто, если оно имеет большое содержание, диалоговое окно / модальное окно должно быть прокручиваемым.

Однако, когда диалоговое / модальное окно открыто, я не хочу, чтобы прокрутка применялась к диалоговому / модальному и фону тела, что, по-видимому, и делается по умолчанию.

Пример: https://output.jsbin.com/mutudop/3.

Как сделать так, чтобы прокрутка применялась только к диалогу / модальному содержанию, когда диалог / модал открыт?

Примечание: меня интересуют только решения, использующие нативный элемент dialog.

Ответы [ 3 ]

0 голосов
/ 08 мая 2019

Простое решение: после отображения mnodel создайте еще один DIV в качестве наложения, охватывающего весь экран, в этом месте css {pointer-events: none} и модель будет размещена поверх него. пользователь не может щелкать содержимое тела, кроме данных модели.

Я создал образец: http://jsfiddle.net/z3sgvnox/

<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>

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:

(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");
    }
  });

})();
0 голосов
/ 08 мая 2019

Так что я тоже попробовал и придумал:

(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");
    }
  });
})();
* {
  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;
}
<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>

Возможно, вы заметили, что я добавил две строки JS, чтобы скрыть / показать overflow body, и вам, вероятно, понадобитсяих, так как вы не можете нацелиться на body с чистым CSS, если вы хотите проверить, открыт ли dialog или нет.

Если вы не хотите, чтобы вы может удалить их, и все работает нормально.Тем не менее, у вас будет две полосы прокрутки на правой стороне.Вот как это выглядит без JS:

(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");
    }
  });
})();
* {
  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;
}
<div class="wrapper">
  <dialog>
    <div>
      <form method="dialog">
        <button value="cancel">Cancel</button>
      </form>
    </div>
  </dialog>

  <button id="open">Open Dialog</button>
</div>

Если вам нужно какое-либо объяснение, дайте мне знать, но я считаю, что код должен быть понятен.

0 голосов
/ 04 мая 2019

Обновление

Я создал еще один пример, в котором ваш основной контент не прокручивается с вашим модальным, если он больше, чем ваш основной контент.Вы можете установить position на fixed в своем контейнере для достижения этого.

(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");
    }
  });

})();
#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%
}
<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>

Исходный ответ

Вы можете установить max-height в своем диалоге и стилизовать содержимоеваш диалог соответственно.Смотрите пример ниже.

(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");
    }
  });

})();
#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%
}
<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>
...