Обнаружить автоматический щелчок на странице

Я пытаюсь разработать библиотеку, которая пытается обнаружить автоматический щелчок на странице. Библиотека будет импортирована на несколько разных страниц, некоторые из них будут иметь jquery, другие - нет или будут иметь другие библиотеки, поэтому мое решение должно быть ванильным javascript.

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

Идея состоит в том, чтобы перехватить все события щелчка и касания, которые происходят на странице, и если эти события сгенерированы сценарием, что-то произойдет (должен быть аякс-вызов или установить значение в форме или установить файл cookie или что-то еще, это не важно на данном этапе).

Я написал очень простой скрипт, который проверяет клики, сгенерированные компьютером:

(function(){
    document.onreadystatechange = function () {
      if (document.readyState === "interactive") {
        try{
            document.querySelector('body').addEventListener('click', function(evt) {    

                console.log("which", evt.which);
                console.log("isTrusted", evt.isTrusted);    
            }, true); // Use Capturing              
        }catch(e){
            console.log("error on addeventlistener",e);
        }
      }
    }   
}());

Я видел, что это работает на html-странице без каких-либо других js в ней, но так как я добавил этот javascript для проверки обнаружения автоматического щелчка, просто "ничего" не происходит, и я ничего не имею в виду как автоклика, так и обнаружения. Тот же код, что и далее, если он используется в консоли, работает нормально, а события перехватываются и эвакуируются. это используемый сценарий:

document.onreadystatechange = function () {
        if (document.readyState === "interactive") {
 //1 try
            el = document.getElementById('target');
            if (el.onclick) {
               el.onclick();
            } else if (el.click) {
               el.click();
            }
            console.log("clicked")
        }
 //2 try
        var d = document.createElement('div'); d.style.position = 'absolute'; d.style.top = '0'; d.style.left = '0'; d.style.width = '200px'; d.style.height = '200px'; d.style.backgroundColor = '#fff'; d.style.border = '1px solid black'; d.onclick = function() {console.log('hello');}; document.body.appendChild(d);
    }

html-страница очень проста:

<body>
    <h1>Hello, world!</h1>
    <div id="target"> aaaaa </div>
</body>

и для тестовых целей я добавил библиотеку обнаружения в голову, а код "autoclick" находится за </body>.

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

У вас есть какое-то представление об этом?

Пример jsfiddle

Ответы

Ответ 1

Использование document.onreadystatechange будет работать, как и ожидалось, в простых сценариях, если не включены никакие другие сторонние библиотеки. Оберните свой код внутри собственного события DOMContentLoaded.

document.addEventListener("DOMContentLoaded",function(){
  document.body.addEventListener('click', function(evt) {
    if (evt.target.classList.contains('some-class')) {} // not used
    console.log("which", evt.which);
    console.log("isTrusted", evt.isTrusted);
  }, true);

  //this is the autoclick code!
  el = document.getElementById('target');
  if (el.onclick) {
    el.onclick();
  } else if (el.click) {
    el.click();
  }
  console.log("clicked")
});
<html>

  <head>
    <title>Hello, world!</title>
  </head>

  <body>
    <h1>Hello, world!</h1>
    <div id="target"> aaaaa </div>
  </body>

</html>

Ответ 2

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

event.originalEvent === undefined

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

$(document).on("click", function(event){
    if(event.originalEvent === undefined){
       //not hooman
    }else{
       //hooman
    }
});

Ответ 3

Можете ли вы проверить, произошли ли как событие click событие mouseup или touchend течение 100 мс друг от друга? Если это не автоматическое событие.

let mouseuportouchend = false;
let click = false;
let timer = null;

const regMouseupOrTouchend = function(){
    mouseuportouchend = true;
    if (!timer) timer = setTimer();
}

const regClick = function(){
    click = true;
    if (!timer) timer = setTimer();
}

const setTimer = function(){
    timer = setTimeout(()=>{
        if (click && mouseuportouchend) console.log("Manual");
        else console.log ("Auto");
        click=false;
        mouseuportouchend=false;
        timer=null;
    }, 100)
}
let el = document.getElementById('target');
el.addEventListener("click",regClick);
el.addEventListener("mouseup", regMouseupOrTouchend);
el.addEventListener("touchend", regMouseupOrTouchend);