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 миллисекунд. Разве это не должно вести себя как бесконечная рекурсивная функция?
Хари
2
возможный дубликат захвата позиции мыши на setInterval () в Javascript
Мастер теней - ухо для тебя
@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. Да, на современных компьютерах это не так много, но в браузерах многое происходит ... Так, например, вы можете отслеживать последнюю обработанную вами позицию и немедленно освобождать от обработчика, если позиция не изменилась. т изменилось.

TJ Crowder
источник
66

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

$("body").mousemove(function(e) {
    document.Form1.posx.value = e.pageX;
    document.Form1.posy.value = e.pageY;
})
solendil
источник
Как я уже говорил, регулярный опрос - это именно то, что я хочу сделать. Я не отслеживаю изменения в событиях мыши, я только пытаюсь зафиксировать положение мыши каждые 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), скопируйте и вставьте приведенный выше код и наведите курсор мыши на окно браузера.

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

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

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

dGRAMOP
источник
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));

вот пример

oboshto
источник
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>

luistar15
источник
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>
Jonas
источник