javascript - 为什么一个简单的 JS 自动点击器会破坏页面?

标签 javascript

我正在尝试制作一个在按住鼠标左键单击时运行的自动点击器脚本(例如按住左键单击垃圾邮件),并且希望它不仅仅在特定元素上运行,例如 button-2 ,但鼠标在哪里。我想出了这个小脚本:

var mouseDown = 0;
document.onmouseup = function() {
  --mouseDown;
}

function printMousePos(event) {
    ++mouseDown;
    while(mouseDown){
        document.elementFromPoint(event.clientX, event.clientY).click();
    }
}

document.addEventListener("mousedown", printMousePos);


let clicks = 0;

document.body.onclick = function(){ 
  clicks++; 
  document.body.innerText = clicks; 
 }

但是,如您运行代码段时所示,它似乎破坏了页面(使其无响应)。为什么会发生这种情况?
谢谢!
编辑:
感谢@VLAZ 的评论,我试图修复无法逃避的 while使用 setInterval 循环,但是,它似乎仍然不起作用。为什么会这样?

var mouseDown = 0;
let removeMouse = function() {
    console.log(mouseDown)
  --mouseDown;
}

function click(x,y){
    var ev = document.createEvent("MouseEvent");
    var el = document.elementFromPoint(x,y);
    ev.initMouseEvent(
        "click",
        true, true,
        window, null,
        x, y, 0, 0,
        false, false, false, false,
        0, null
    );
    el.dispatchEvent(ev);
}

function printMousePos(event) {
    ++mouseDown;
    setInterval(()=> {
        if(mouseDown){
            console.log(mouseDown)
            click(event.clientX, event.clientY);
        } else {
            clearInterval()
        }
    }, 1)
}

document.addEventListener("mousedown", printMousePos);
document.addEventListener("mouseup", removeMouse);

var count = 0;
document.documentElement.addEventListener("mousedown", function() {
    count++;
    document.body.innerText = count.toString();
})

编辑:
我设法根据@Roko 的回答拼凑了一个很酷的小脚本,但是,它似乎不适用于像 https://clickspeedtest.com/ 这样的网站。或 https://www.clickspeedtester.com/ ,或者真的任何网站。这是他们的原因吗?谢谢!
这是代码:

let intervalHandler = null;

const Mouse = {
  mousedown(ev){
    this.isDown = true;
    this.autoClick(ev)
  },
  mouseup(){ 
    this.isDown = false; 
    clearInterval(intervalHandler)
  },
  mouseover(ev) { 
    if(intervalHandler) clearInterval(intervalHandler)
    if (this.isDown) this.autoClick(ev); 
  },
};
Object.defineProperties(Mouse, {
  isDown: {
    value: false,
    writable: true,
  },
  autoClick: {
    value: (ev) => {
      const ELFP = document.elementFromPoint(ev.clientX, ev.clientY);
      intervalHandler = setInterval(() => {
        ELFP.click();
      }, 100)
    }
  }
});
Object.keys(Mouse).forEach(t => document.addEventListener(t, Mouse[t].bind(Mouse)));

// Demo with buttons
document.querySelectorAll("button").forEach(EL => 
  EL.addEventListener("click", () => console.log(EL.id))
);
<button id="a" type="button">BUTTON 1</button>
<button id="b" type="button">BUTTON 2</button>

最佳答案

  • 创建一个 Singleton Mouse具有默认浏览器监听器可迭代方法的对象"mousedown" "mouseup" "mouseover"事件。
  • 然后分配给您的单例额外 non-enumerable特性:isDown ( bool 值)处理鼠标是按下还是按下autoClick (函数)将在 "mouseover" 上触发事件。
  • 分配您的 enumerable keys ("EventTypes") 方法 forEach方式到Window.document对象

  • const Mouse = {
      mousedown()   { this.isDown = true; },
      mouseup()     { this.isDown = false; },
      mouseover(ev) { if (this.isDown) this.autoClick(ev); },
    };
    Object.defineProperties(Mouse, {
      isDown: {
        value: false,
        writable: true,
      },
      autoClick: {
        value: (ev) => {
          const ELFP = document.elementFromPoint(ev.clientX, ev.clientY);
          ELFP.click();
        }
      }
    });
    Object.keys(Mouse).forEach(t => document.addEventListener(t, Mouse[t].bind(Mouse)));
    
    // DEMO TIME:
    document.querySelectorAll("button").forEach(EL => 
      EL.addEventListener("click", () => console.log(EL.id))
    );
    <button id="a" type="button">BUTTON 1</button>
    <button id="b" type="button">BUTTON 2</button>

    不断向 "click" 发送垃圾邮件事件(尽可能快)你可以这样做:

    const spamClick = (ev) => {
      const ms = 1; // Repeat every 1 millisecond
      const EL = ev.currentTarget;
      ev.type === "mousedown" ? EL._itv = setInterval(() => EL.click(), ms) : clearInterval(EL._itv) ;
    };
    ["mousedown", "mouseup", "mouseleave"].forEach(evtName => 
      document.querySelectorAll("button").forEach(EL =>
        EL.addEventListener(evtName, spamClick)
      )
    );
    
    // FOR THIS DEMO ONLY:
    document.querySelectorAll("button").forEach(EL =>
      EL.addEventListener("click", () => console.log(EL.id))
    );
    <button id="a" type="button">BUTTON 1</button>
    <button id="b" type="button">BUTTON 2</button>

    补充阅读:
  • MDN:Function.bind()
  • 关于javascript - 为什么一个简单的 JS 自动点击器会破坏页面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66413779/

    相关文章:

    php - 如果使用 PHP 文本框为空,则在提交时发出警告消息

    javascript - 如何使用 javascript 将数组添加到我的 html

    javascript - 嵌套(扩展) promise 似乎需要一个全局变量

    javascript - Bootstrap 3 - 将页面刷新到特定选项卡

    javascript - 创建这个 javascript 和 css 繁重的元素的最有效方法是什么?

    javascript - Grunt 添加多个输入/输出目录

    javascript - 无法在移动设备上与溢出 :auto element underneath scrollable section using fullpage. js 进行交互,scrollOverflow:true

    javascript - 切换 div -jquery

    javascript - 检测所有XMLHttpRequest调用是否完成

    javascript - 使用正则表达式强调字符串中的多个关键字并替换