Javascript - Отслеживание положения мыши


161

Я надеюсь отслеживать положение курсора мыши, периодически каждые мсек. Поэтому, по существу, когда страница загружается - этот трекер должен запускаться и, скажем, каждые 100 мс, я должен получить новое значение posX и posY и распечатать его в форме.

Я попробовал следующий код - но значения не обновляются - в полях формы отображаются только начальные значения posX и posY. Любые идеи о том, как я могу получить это и работает?

<html>
<head>
<title> Track Mouse </title>
<script type="text/javascript">
function mouse_position()
{
    var e = window.event;

    var posX = e.clientX;
    var posY = e.clientY;

    document.Form1.posx.value = posX;
    document.Form1.posy.value = posY;

    var t = setTimeout(mouse_position,100);

}
</script>

</head>

<body onload="mouse_position()">
<form name="Form1">
POSX: <input type="text" name="posx"><br>
POSY: <input type="text" name="posy"><br>
</form>
</body>
</html>

Проблема в том, что eventпри повторном вызове функции не будет объекта. Вы, вероятно, должны слушать какое-то событие, чем использовать setTimeout.
Феликс Клинг

Да, но разве функция mouse_position () не должна вызывать себя каждые 100 миллисекунд. Разве это не должно вести себя как бесконечная рекурсивная функция?
Хари


@Titan: Да, но я подозреваю, что это будет ошибка, потому что window.eventбудет undefinedили null. Если нет события, нет eventобъекта.
Феликс Клинг

1
из интереса, какое применение это?
SuperUberDuper

Ответы:


178

Положение мыши сообщается об eventобъекте, полученном обработчиком для mousemoveсобытия, которое вы можете прикрепить к окну (событие всплывает):

(function() {
    document.onmousemove = handleMouseMove;
    function handleMouseMove(event) {
        var eventDoc, doc, body;

        event = event || window.event; // IE-ism

        // If pageX/Y aren't available and clientX/Y are,
        // calculate pageX/Y - logic taken from jQuery.
        // (This is to support old IE)
        if (event.pageX == null && event.clientX != null) {
            eventDoc = (event.target && event.target.ownerDocument) || document;
            doc = eventDoc.documentElement;
            body = eventDoc.body;

            event.pageX = event.clientX +
              (doc && doc.scrollLeft || body && body.scrollLeft || 0) -
              (doc && doc.clientLeft || body && body.clientLeft || 0);
            event.pageY = event.clientY +
              (doc && doc.scrollTop  || body && body.scrollTop  || 0) -
              (doc && doc.clientTop  || body && body.clientTop  || 0 );
        }

        // Use event.pageX / event.pageY here
    }
})();

(Обратите внимание, что тело этого ifбудет работать только на старом IE.)

Пример вышесказанного в действии - он рисует точки, когда вы наводите курсор мыши на страницу. (Проверено на IE8, IE11, Firefox 30, Chrome 38.)

Если вам действительно нужно решение на основе таймера, вы комбинируете это с некоторыми переменными состояния:

(function() {
    var mousePos;

    document.onmousemove = handleMouseMove;
    setInterval(getMousePosition, 100); // setInterval repeats every X ms

    function handleMouseMove(event) {
        var dot, eventDoc, doc, body, pageX, pageY;

        event = event || window.event; // IE-ism

        // If pageX/Y aren't available and clientX/Y are,
        // calculate pageX/Y - logic taken from jQuery.
        // (This is to support old IE)
        if (event.pageX == null && event.clientX != null) {
            eventDoc = (event.target && event.target.ownerDocument) || document;
            doc = eventDoc.documentElement;
            body = eventDoc.body;

            event.pageX = event.clientX +
              (doc && doc.scrollLeft || body && body.scrollLeft || 0) -
              (doc && doc.clientLeft || body && body.clientLeft || 0);
            event.pageY = event.clientY +
              (doc && doc.scrollTop  || body && body.scrollTop  || 0) -
              (doc && doc.clientTop  || body && body.clientTop  || 0 );
        }

        mousePos = {
            x: event.pageX,
            y: event.pageY
        };
    }
    function getMousePosition() {
        var pos = mousePos;
        if (!pos) {
            // We haven't seen any movement yet
        }
        else {
            // Use pos.x and pos.y
        }
    }
})();

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

Примечание : если вы собираетесь что-то делать каждые 100 мс (10 раз в секунду), постарайтесь ограничить фактическую обработку, которую вы выполняете в этой функции . Это большая работа для браузера, особенно старых Microsoft. Да, на современных компьютерах это не так много, но в браузерах многое происходит ... Так, например, вы можете отслеживать последнюю обработанную вами позицию и немедленно освобождать от обработчика, если позиция не изменилась. т изменилось.


66

Вот решение, основанное на jQuery и слушателе событий мыши (что намного лучше, чем обычный опрос) на теле:

$("body").mousemove(function(e) {
    document.Form1.posx.value = e.pageX;
    document.Form1.posy.value = e.pageY;
})

Как я уже говорил, регулярный опрос - это именно то, что я хочу сделать. Я не отслеживаю изменения в событиях мыши, я только пытаюсь зафиксировать положение мыши каждые x миллисекунд (независимо от того, двигалась мышь или нет).
Хари

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

1
Здесь нет преимущества использования jQuery, за исключением излишнего использования
Pattycake Jr

@PattycakeJr Последний раз, когда я смотрел, он был меньше 90 КБ в минимизированной версии
Крис

1
@PattycakeJr также, если вы вообще очень маловероятно скачиваете его, если вы указываете на CDN, так как почти все другие сайты ссылаются на него
Брайан Лейшман

53
onmousemove = function(e){console.log("mouse location:", e.clientX, e.clientY)}

Откройте консоль ( Ctrl+ Shift+ J), скопируйте и вставьте приведенный выше код и наведите курсор мыши на окно браузера.


1
Imo лучший ответ
здесь

10

Я считаю, что мы думаем об этом,

function mouse_position(e)
{
//do stuff
}
<body onmousemove="mouse_position(event)"></body>


1
Я новичок в этом форуме, так что просто чтобы я знал, пожалуйста, объясните, почему вы - мой awnser - это так, чтобы я больше не повторял ту же ошибку. Спасибо! ThePROgrammer
dGRAMOP

10
Меня тоже раздражают негативы без объяснения причин. Чтобы дать вам возможное объяснение, этот ответ не решает проблему опроса опроса каждые 100 мс. В его ответе на другие ответы стало яснее, что это необходимо.
аааааа

1
я считаю, что такая встроенная обработка событий не рекомендуется. document.body.addEventListener("mousemove", function (e) {})способ сделать это, в вашем коде JavaScript, в отличие от HTML
Райан

10

То, что я думаю, что он хочет знать только позиции курсора X / Y, чем то, почему ответ такой сложный.

// Getting 'Info' div in js hands
var info = document.getElementById('info');

// Creating function that will tell the position of cursor
// PageX and PageY will getting position values and show them in P
function tellPos(p){
  info.innerHTML = 'Position X : ' + p.pageX + '<br />Position Y : ' + p.pageY;
}
addEventListener('mousemove', tellPos, false);
* {
  padding: 0:
  margin: 0;
  /*transition: 0.2s all ease;*/
  }
#info {
  position: absolute;
  top: 10px;
  right: 10px;
  background-color: black;
  color: white;
  padding: 25px 50px;
}
<!DOCTYPE html>
<html>
  
  <body>
    <div id='info'></div>
        </body>
  </html>


5

Код на основе ES6:

let handleMousemove = (event) => {
  console.log(`mouse position: ${event.x}:${event.y}`);
};

document.addEventListener('mousemove', handleMousemove);

Если вам нужно регулировать движение мышью, используйте это:

let handleMousemove = (event) => {
  console.warn(`${event.x}:${event.y}\n`);
};

let throttle = (func, delay) => {
  let prev = Date.now() - delay;
  return (...args) => {
    let current = Date.now();
    if (current - prev >= delay) {
      prev = current;
      func.apply(null, args);
    }
  }
};

// let's handle mousemoving every 500ms only
document.addEventListener('mousemove', throttle(handleMousemove, 500));

вот пример


2

Независимо от браузера, ниже строки работали для получения правильного положения мыши.

event.clientX - event.currentTarget.getBoundingClientRect().left event.clientY - event.currentTarget.getBoundingClientRect().top


2

Если вы хотите визуально отслеживать движение мыши:

<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<style type="text/css">
* { margin: 0; padding: 0; }
html, body { width: 100%; height: 100%; overflow: hidden; }
</style>
<body>
<canvas></canvas>

<script type="text/javascript">
var
canvas    = document.querySelector('canvas'),
ctx       = canvas.getContext('2d'),
beginPath = false;

canvas.width  = window.innerWidth;
canvas.height = window.innerHeight;

document.body.addEventListener('mousemove', function (event) {
	var x = event.clientX, y = event.clientY;

	if (beginPath) {
		ctx.lineTo(x, y);
		ctx.stroke();
	} else {
		ctx.beginPath();
		ctx.moveTo(x, y);
		beginPath = true;
	}
}, false);
</script>
</body>
</html>


2

У меня недостаточно репутации, чтобы оставлять комментарии, но я взял превосходный ответ TJ Crowder и полностью определил код на таймере 100 мс . (Он оставил некоторые детали для воображения.)

Спасибо OP за вопрос, и TJ за ответ! Вы оба отличная помощь. Код встроен ниже как зеркало isbin.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Example</title>
  <style>
    body {
      height: 3000px;
    }
    .dot {
      width: 2px;
      height: 2px;
      background-color: black;
      position: absolute;
    }
  </style>
</head>
<body>
<script>
(function() {
    "use strict";
    var mousePos;

    document.onmousemove = handleMouseMove;
    setInterval(getMousePosition, 100); // setInterval repeats every X ms

    function handleMouseMove(event) {
        var eventDoc, doc, body;

        event = event || window.event; // IE-ism

        // If pageX/Y aren't available and clientX/Y are,
        // calculate pageX/Y - logic taken from jQuery.
        // (This is to support old IE)
        if (event.pageX == null && event.clientX != null) {
            eventDoc = (event.target && event.target.ownerDocument) || document;
            doc = eventDoc.documentElement;
            body = eventDoc.body;

            event.pageX = event.clientX +
              (doc && doc.scrollLeft || body && body.scrollLeft || 0) -
              (doc && doc.clientLeft || body && body.clientLeft || 0);
            event.pageY = event.clientY +
              (doc && doc.scrollTop  || body && body.scrollTop  || 0) -
              (doc && doc.clientTop  || body && body.clientTop  || 0 );
        }

        mousePos = {
            x: event.pageX,
            y: event.pageY
        };
    }
    function getMousePosition() {
        var pos = mousePos;
		
        if (!pos) {
            // We haven't seen any movement yet, so don't add a duplicate dot 
        }
        else {
            // Use pos.x and pos.y
            // Add a dot to follow the cursor
            var dot;
            dot = document.createElement('div');
            dot.className = "dot";
            dot.style.left = pos.x + "px";
            dot.style.top = pos.y + "px";
            document.body.appendChild(dot);
        }
    }
})();
</script>
</body>
</html>


0

Вот комбинация двух требований: отслеживание положения мыши каждые 100 миллисекунд:

var period = 100,
    tracking;

window.addEventListener("mousemove", function(e) {
    if (!tracking) {
        return;
    }

    console.log("mouse location:", e.clientX, e.clientY)
    schedule();
});

schedule();

function schedule() {
    tracking = false;

    setTimeout(function() {
        tracking = true;
    }, period);
}

Это отслеживает и воздействует на положение мыши, но только каждый миллисекунд периода .


0

Просто упрощенная версия @TJ Crowder и ответы @RegarBoy .

Меньше значит больше, на мой взгляд.

Проверьте событие onmousemove для получения дополнительной информации о событии.

Изображение мыши трекер

Существует новое значение posXи posYкаждый раз, когда мышь движется в соответствии с горизонтальными и вертикальными координатами.

<!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>Example Mouse Tracker</title>
      <style>    
        body {height: 3000px;}
        .dot {width: 2px;height: 2px;background-color: black;position: absolute;}
      </style>
    </head>
    <body>
    <p>Mouse tracker</p>
    <script>
    onmousemove = function(e){
        //Logging purposes
        console.log("mouse location:", e.clientX, e.clientY);

        //meat and potatoes of the snippet
        var pos = e;
        var dot;
        dot = document.createElement('div');
        dot.className = "dot";
        dot.style.left = pos.x + "px";
        dot.style.top = pos.y + "px";
        document.body.appendChild(dot);
    }      
    </script>
    </body>
    </html>
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.