如何使用 javascript 模拟鼠标点击和鼠标移动

How to simulate mouse click along with mouse move using javascript

我在 js 文件中使用 element.click() 模拟鼠标点击操作,但是鼠标光标在其他地方并且动作在正确的元素上执行,我想在执行时将鼠标光标放在元素上模拟鼠标 click.Does 任何人都知道使用 javascript 代码,我怎样才能得到这个?

您不能使用 javascript 移动鼠标指针,因为它会带来安全隐患。

您无法在浏览器中更改鼠标光标位置。参见 this

但是可以使用javascriptclick()的方法来模拟点击事件。要完成这项工作,您必须使用 elementFromPoint() 到 select 单击位置。在我的底部示例中,当您单击第一个按钮时,javascript 模拟第二个按钮单击。

var first = document.getElementById("first");
var second = document.getElementById("second");

first.addEventListener("click", function(){ 
    var xPos = second.offsetLeft;
    var yPos = second.offsetHeight;
    document.elementFromPoint(xPos, yPos).click();
});

second.addEventListener("click", function(){ 
    alert("Second button clicked!");
});
<button id="first">First</button>
<button id="second">Second</button>

正如其他答案中已经指出的那样,您不能使用 JavaScript 更改鼠标的真实位置...但是...您需要这样做吗?没有!

您可以添加鼠标光标的图像并将其放置在内容顶部的任何位置,相对于浏览器 window 左上角。 您可以通过将 css 'cursor: none;' class 应用到您希望光标消失的屏幕区域来隐藏真正的光标。

所以为了模拟你想要的东西,你可以得到你想要点击的元素的位置,隐藏真实的鼠标光标,显示假的鼠标光标并将它移动到你想要点击的元素的位置,然后点击它。

为了用户友好:开始模拟时请通知用户不要再移动他的鼠标,模拟鼠标移动和点击,当用户移动他的鼠标时隐藏假鼠标并显示真实鼠标并通知用户模拟结束

我找到了一个 git 存储库,它模拟了 鼠标拖动 事件:

link to git-repository
SEE CODEPEN EXAMPLE HERE
useful article

HTML

<!--
    author: kemokid
    github: https://github.com/kemokid/scripting-sortable/blob/master/script_sortable_dnd_more_general.js
-->
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="main.css">
</head>
<body>
    <!-- https://ghostinspector.com/blog/simulate-drag-and-drop-javascript-casperjs/ -->
        <p>Drag the W3Schools image into the rectangle:</p>
        <div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>

    <br>

        <img id="drag1" src="https://www.w3schools.com/html/img_logo.gif" ondragstart="drag(event)" >

    <br/>

        <button onClick="autodrag();">Auto-drag</button>

    <br/>
    <br/>

        Reload the page to reset the image.

    <script src="app.js"></script>
</body>
</html>

CSS

/*
    author: kemokid
    github: https://github.com/kemokid/scripting-sortable/blob/master/script_sortable_dnd_more_general.js
*/
#div1 {
    width: 350px;
    height: 70px;
    padding: 10px;
    border: 1px solid #aaaaaa;
}

#drag1 {
    width: 336px;
    height: 69px;
}

JS

/*
    author: kemokid
    github: https://github.com/kemokid/scripting-sortable/blob/master/script_sortable_dnd_more_general.js
*/

function allowDrop(ev) {
    ev.preventDefault();
}

function drag(ev) {
    ev.dataTransfer.setData("text", ev.target.id);
}

function drop(ev) {
    ev.preventDefault();
    var id = ev.dataTransfer.getData("text");
    ev.target.appendChild(document.getElementById(id));
}

function autodrag() {
    return triggerDragAndDrop('#drag1', '#div1');
}

// Originally from https://ghostinspector.com/blog/simulate-drag-and-drop-javascript-casperjs/
// trimmed down and modified by @kemokid (Martin Baker) to work with Sortable.js
///
// Probably not going to work with dragging from one list to another

// This has been made more general, to work with other drag-and-drop elements besides a
// Sortable list, but is not as complete as the Casper example above.

// Call with DOM selectors, eg `triggerDragAndDrop('#drag', '#drop');`

// Returns false if unable to start.
// callback, if present, will be called with true if able to finish, false if not.
// If you receive "false" on the callback, the list is likely not in the beginning state.
var triggerDragAndDrop = function (selectorDrag, selectorDrop, callback) {
  var DELAY_INTERVAL_MS = 10;
  var MAX_TRIES = 10;
  var dragStartEvent;

  // fetch target elements
  var elemDrag = document.querySelector(selectorDrag);
  var elemDrop = document.querySelector(selectorDrop);

  if (!elemDrag || !elemDrop) {
    console.log("can't get elements");
    return false;
  }

  var startingDropRect = elemDrop.getBoundingClientRect();

  function rectsEqual(r1, r2) {
    return r1.top === r2.top && r1.right === r2.right && r1.bottom === r2.bottom && r1.left === r2.left;
  }

  // function for triggering mouse events
  function fireMouseEvent(type, elem, dataTransfer) {
    var evt = document.createEvent('MouseEvents');
    evt.initMouseEvent(type, true, true, window, 1, 1, 1, 0, 0, false, false, false, false, 0, elem);
    if (/^dr/i.test(type)) {
      evt.dataTransfer = dataTransfer || createNewDataTransfer();
    }

    elem.dispatchEvent(evt);
    return evt;
  };

  function createNewDataTransfer() {
    var data = {};
    return {
      clearData: function(key) {
        if (key === undefined) {
          data = {};
        } else {
          delete data[key];
        }
      },
      getData: function(key) {
        return data[key];
      },
      setData: function(key, value) {
        data[key] = value;
      },
      setDragImage: function() {},
      dropEffect: 'none',
      files: [],
      items: [],
      types: [],
      // also effectAllowed      
    }
  };

  // trigger dragging process on top of drop target
  // We sometimes need to do this multiple times due to the vagaries of
  // how Sortable manages the list re-arrangement
  var counter = 0;
  function dragover() {
    counter++;
    console.log('DRAGOVER #' + counter);

    var currentDropRect = elemDrop.getBoundingClientRect();
    if (rectsEqual(startingDropRect, currentDropRect) && counter < MAX_TRIES) {
      if (counter != 1) console.log("drop target rect hasn't changed, trying again");

      // mouseover / mouseout etc events not necessary
      // dragenter / dragleave events not necessary either
      fireMouseEvent('dragover', elemDrop, dragStartEvent.dataTransfer);

      setTimeout(dragover, DELAY_INTERVAL_MS);
    } else {
      if (rectsEqual(startingDropRect, currentDropRect)) {
        console.log("wasn't able to budge drop target after " + MAX_TRIES + " tries, aborting");
        fireMouseEvent('drop', elemDrop, dragStartEvent.dataTransfer);
        if (callback) callback(false);
      } else {
        setTimeout(drop, DELAY_INTERVAL_MS);
      }
    }
  }

  function drop() {
    console.log('DROP');
    // release dragged element on top of drop target
    fireMouseEvent('drop', elemDrop, dragStartEvent.dataTransfer);
    fireMouseEvent('mouseup', elemDrop);    // not strictly necessary but I like the symmetry
    if (callback) callback(true);
  }

  // start dragging process
  console.log('DRAGSTART');
  fireMouseEvent('mousedown', elemDrag);
  dragStartEvent = fireMouseEvent('dragstart', elemDrag);

  // after a delay, do the first dragover; this will run up to MAX_TRIES times
  // (with a delay between each run) and finally run drop() with a delay:
  setTimeout(dragover, DELAY_INTERVAL_MS);
  return true;
};