Как намеренно заморозить окно браузера (как предупреждение, подтверждение и подсказка)? - PullRequest
0 голосов
/ 02 мая 2019

Есть ли способ намеренно заморозить окно браузера, как это делают alert, confirm и prompt (короче: "acp")?

Я хочу показать модальное диалоговое окно с пользовательскимcss вместо нативных всплывающих окон для «acp», но также хочу иметь возможность заморозить браузер, пока у меня не появятся отзывы пользователей, такие как «acp».

Но человек, почему?Это плохая практика (э-э, я должен понизить голос)!
Итак, когда это плохая практика - тогда почему «acp» фактически предлагает такое синхронное поведение? Потому что в некоторых конкретных сценариях это как раз правильный инструмент для соответствующего UX. Эти нативные модалы выглядят так некрасиво и в то же время очень ограничены.

Вот только один быстрый игрязный пример, где было бы совершенно нормально заморозить браузер, пока пользователь не даст отзыв.Допустим, у нас есть form с input type="reset" -элементом.Поэтому, прежде чем мы действительно позволим сбросить form, мы спрашиваем пользователя что-то вроде: «Вы уверены, что хотите сбросить (данные будут потеряны)?».

Если бы я был в порядке с собственным модальным внешним видом(что я не) я мог бы сделать:

var handleSubmit = function( e ) {
  confirm('Are you sure you want to reset (data will be lost)?') || e.preventDefault()
}
$('form').on( 'reset', handleSubmit ) // just using jQuery here for the sake of shortness
// Edit to make Herohtar hopefully feel much better:
// using jQuery here for the sake of lazyness :)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
  <input placeholder="type something, reset and cancel to keep input value" style="width:100%">
  <input type="reset">
</form>

Так что «все» должны согласиться (отредактируйте: или, по крайней мере, кто-то мог), это неплохая практика, верно?
Но как мы можем достичьто же самое с пользовательским стилем модал / диалоговое окно / всплывающее окно?
Я, конечно же, прошу не часть HTML / CSS, а возможность заморозить окно браузера через JavaScript!

Честно говоря, я действительно ожидаю некоторых отрицательных ответов за это, но, возможно, есть один Убийца ниндзя JavaScript , у которого есть этот специальный взлом, чтобы сделать возможным ...


ПРИМЕЧАНИЕ. Я точно знаю, как добиться того же результата в конце, но мне нужна реальная функция заморозки / синхронного воспроизведения, чтобы код был прямым и менее хакерским.

Ответы [ 2 ]

2 голосов
/ 02 мая 2019

Вы можете поместить все в div, кроме вашего всплывающего окна.Затем вы можете включать / выключать события указателя с помощью css.

Все внутри div больше не будет взаимодействовать.Это создаст впечатление зависания окна браузера.

.freeze { pointer-events: none; }

Примечание: При добавлении pointer-events к элементу это также влияет на все дочерние элементы, поэтому размещение его на телетакже заблокирует всплывающее окно.

После закрытия всплывающего окна мы можем удалить класс freeze из div, и все снова начнет работать.

const content = document.getElementById('content')
const overlay = document.querySelector('.overlay')
const a = document.querySelector('.open-overlay')
const close = document.querySelector('.overlay .close')

// Open a popup and freeze the browser content
a.addEventListener('click', e => {
  e.preventDefault()
  content.classList.add('freeze')
  overlay.classList.remove('hidden')
})

// Close the popup window and unfreeze the browser content
close.addEventListener('click', e => {
  e.preventDefault()
  content.classList.remove('freeze')
  overlay.classList.add('hidden')
})
.freeze { pointer-events: none; }

.hidden { display: none; }

.overlay {
  position: fixed;
  z-index: 100;
  padding: 20px;
  background: white;
  border: solid 1px #ccc;
  width: 300px;
  top: 20px;
  left: 0;
  right: 0;
  margin: auto;
}
<div class="overlay hidden">
  <h1>Overlay</h1>
  <a href="" class="close">Close</a>
</div>

<div id="content">
  <a href="" class="open-overlay">Open Overlay</a>

  <p>Hello World</p>
  <p>Hello World</p>
  <p>Hello World</p>
  <p>Hello World</p>
  <p>Hello World</p>
  <form>
    <input type="text">
  </form>
</div>
1 голос
/ 02 мая 2019

Вы не можете заморозить приложение браузера, как это делают нативные диалоги. Они построены не на JavaScript, а на собственном коде и могут каким-либо образом повлиять на работу браузера. JavaScript не может таким образом влиять на клиентское приложение.

Но вы можете заморозить взаимодействия с содержимым своей страницы в окне браузера ....

Просто поместите окно размером div над страницей с фиксированным расположением. Это не позволит пользователю взаимодействовать с чем-либо на главной странице (за ней). Затем отобразите ваш модальный диалог поверх этого. Когда пользователь очищает модальное окно, скрывает его и размер окна div, что снова делает главную страницу интерактивной.

let modal = document.querySelector(".modal");
let pageCover = document.querySelector(".pageCover");
let main = document.querySelector("main");        

document.getElementById("open").addEventListener("click", function(){
  modal.classList.remove("hidden");
  pageCover.classList.remove("hidden"); 
  main.addEventListener("focus", preventFocus);
});


document.getElementById("close").addEventListener("click", function(){
  modal.classList.add("hidden");
  pageCover.classList.add("hidden"); 
  main.removeEventListener("focus", preventFocus);
});

function preventFocus (evt){
  evt.preventDefault();
}
.hidden { display:none; }

.pageCover { 
  position:fixed; 
  z-index:10; 
  background-color:rgba(0,0,0,.25); 
  width:100vw; 
  height:100vh; 
  top:0; 
  left:0;
}

.modal { 
  position:absolute; 
  z-index:100; 
  background-color:aliceblue;
  border:2px double grey;
  width:200px; 
  height:200px; 
  top:30%; 
  left:30%; 
  text-align:center;
}

.modalTitle {
  margin:0;
  background-color:#00a;
  color:#ff0;
  padding:5px;
  font-weight:bold;
  font-size:1.1em;
}

#close { 
  background-color:#800080;
  color:#ff0;
  border:1px solid #e0e0e0;
  padding:5px 10px;
}

#close:hover { background-color:#c000c0; }
<main>
  <h1>This is some page content</h1>
  <p>And more content</p>
  <button id="open">Click Me To Show Modal</button>
  <div>More content</div>
</main>

<div class="hidden pageCover"></div>

<div class="hidden modal">
  <div class="modalTitle">Modal Title Here</div>
  <p>
    Now, you can only interact with the contents of this "modal".
  </p>
  <button id="close" >Close</button>
</div>
...