Как потерять доверенный контекст из события клика - PullRequest
0 голосов
/ 14 января 2019

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

Мне пришла в голову следующая идея:

window.addEventListener('click', function(e) {
  console.log(e.isTrusted);
  if (e.isTrusted) {
    e.stopImmediatePropagation();
    e.preventDefault();
    e.target.dispatchEvent(new e.constructor(e.type, e));
  }
}, true);

button.addEventListener('click', function(e) {
  window.open('about:blank');
});
<button id="button">Test</button>

(В окне сниппета. Open не будет работать из-за песочницы iframe.)

По сути, идея состоит в том, чтобы добавить прослушиватель событий на страницу, которая заменяет любое событие щелчка, которому доверяют, на его копию, которая не является доверенной. Однако это не работает, и всплывающее окно все еще открыто.

Есть ли способ сделать это?

Соответствующая спецификация здесь: https://html.spec.whatwg.org/multipage/interaction.html#triggered-by-user-activation

Ответы [ 2 ]

0 голосов
/ 16 января 2019

Обработка контекстов событий поп-блокировщиком кажется сложной. Даже генерация setTimeout с оцененной строкой не нарушает контекст. В Firefox есть период в одну секунду после щелчка, чтобы выполнить всплывающее окно, позже считается, что щелчок не вызывается.

Однако я мог бы заставить Firefox блокировать всплывающие окна, используя setInterval. Я еще не тестировал его в Chrome.

Мы перезаписываем window.open метод другим:

      window.open = (function()
      {
        const
          openArgs  = [],
          fnOpen    = window.open.bind(window)
        ;

        setInterval( () => { for(let args; args = openArgs.pop(); fnOpen(args)); }, 100);

        return function open(...args) { openArgs.push(args); }  
      })();
<button onclick="window.open('http://example.com');">button</button>
<a href="javascript:window.open('http://www.example.com');">open</a>
0 голосов
/ 14 января 2019

Это просто отвечает на X часть этой XY задачи , потому что я не вижу реального использования для Y .

Если вы хотите заблокировать все всплывающие окна, то window.open = null; уже заблокирует все те, которые сделаны с помощью этого метода, тогда вы также можете заблокировать те из якорных элементов,

document.addEventListener('click', e => {
  if(e.target.nodeName === 'A' && e.target.target === "_blank") {
    e.preventDefault();
  }
});

Теперь вам нужно применить это во всех документах (т.е. в iframes тоже), и вы должны быть хорошими.

Но учтите, что существует множество законных причин, по которым страницы открывают всплывающие окна, и отключение их определенно разрушит многие веб-сайты.

...