Почему Firefox, Chrome, Opera не отстают от событий мыши? - PullRequest
1 голос
/ 19 декабря 2010

Почему современные браузеры не поспевают за мышью?Firefox 3.6, Chrome 8.xx, Opera 10.xx, все не в состоянии запускать события мыши, такие как mouseover, mouseout и mousemove, с достаточно высокой скоростью, чтобы не отставать от быстро движущейся мыши.

Какбраузер решает, когда генерировать событие mouseover или mouseout в этих условиях?На практике это не имеет никакого сходства с принятым определением «Это событие mouseout отправляется элементу, когда пользователь перемещает мышь за пределы элемента. Это событие противоположно наведению мыши».[MDC]

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

<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" >
<html xmlns="http://www.w3.org/1999/xhtml"
      xml:lang="en" lang="en" >
  <head>
    <title>Mouse event tracking</title>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
    <style type="text/css">
      div {
        position: absolute;
        border:   1px solid black;
        width:    40px;
        height:   100px;
      }
    </style>
  </head>
  <body>
    <h1 style="position: absolute; top: 10px; left: 10px; font-size: 14px">Start on green, move mouse to yellow</h1>
    <div id="ladder_start"  style="top: 50px;  left: 10px; background-color: #44ff44;"></div>
    <div id="ladder"        style="top: 50px;  left: 50px;"></div>    
    <div id="ladder_end"    style="top: 50px;  left: 850px; background-color: #ffff44;"></div>
    <div id="ladder_p_over" style="top: 50px;  left: 900px; width: 100px; height: 50px"></div>
    <div id="ladder_p_out"  style="top: 100px; left: 900px; width: 100px; height: 50px"></div>
    <canvas id="ladder_trace"  style="position: absolute; border: 1px solid black; top: 155px; left: 50px; height: 20px"></canvas>

    <script type="text/javascript">
      window.addEventListener("load", function (event) {
        if (window.event_tests_loaded === true) {
          return;
        }

        var ladder           = document.getElementById("ladder");
        var ladder_trace     = document.getElementById("ladder_trace");
        var ladder_start     = document.getElementById("ladder_start");
        var ladder_end       = document.getElementById("ladder_end");
        var ladder_p_over    = document.getElementById("ladder_p_over");
        var ladder_p_out     = document.getElementById("ladder_p_out");
        var mouse_over_count = 0;
        var mouse_out_count  = 0;
        var steps            = [];
        var trace            = ladder_trace.getContext('2d');  


        var step_over = function (event) {
          event.preventDefault();
          event.stopPropagation();
          if (typeof event.target.parentNode === "object") {
            if (event.target.parentNode === ladder) {
              event.target.style.backgroundColor = event.target.highlight_color;
              mouse_over_count++;
              ladder_p_over.textContent = mouse_over_count;
            }
          }
        };

        var step_out = function (event) {
          event.preventDefault();
          event.stopPropagation();
          if (typeof event.target.parentNode === "object") {
            if (event.target.parentNode === ladder) {
              mouse_out_count++;
              ladder_p_out.textContent = mouse_out_count;
            }
          }
        };

        var move = function (event) {
          event.preventDefault();
          event.stopPropagation();
          if ((event.clientX >= 50) && (event.clientX < 850)) {
            trace.fillStyle   = "black";
            trace.strokeStyle = "black";
            trace.lineWidth   = 1;
            trace.beginPath();
            trace.moveTo(event.clientX - 50 + 0.5, 0);
            trace.lineTo(event.clientX - 50 + 0.5, 20);
            trace.stroke();
          }
        };

        ladder_start.addEventListener("mouseover", function (event) {
          event.preventDefault();
          event.stopPropagation();
          mouse_over_count = 0;
          mouse_out_count  = 0;
          ladder_p_over.textContent = mouse_over_count;
          ladder_p_out.textContent  = mouse_out_count;
          var i;
          for (i = 0; i < 40; i++) {
            steps[i].style.backgroundColor = steps[i].original_color;
          }
          trace.clearRect(0, 0, 800, 20);
          document.addEventListener("mouseover", step_over, false);
          document.addEventListener("mouseout", step_out, false);
          document.addEventListener("mousemove", move, false);
        }, false);

        ladder_end.addEventListener("mouseover", function (event) {
          document.removeEventListener("mouseover", step_over, false);
          document.removeEventListener("mouseout", step_out, false);
          document.removeEventListener("mousemove", move, false);
        }, false);

        (function () {
          var i;
          for (i = 0; i < 40; i++) {
            steps[i] = document.createElement("div");
            steps[i].style.width           = "20px";
            steps[i].style.border          = "0";
            steps[i].style.top             = "0px";
            steps[i].style.left            = (i * 20) + "px";
            steps[i].original_color        = "rgb(" + (i * 4) + ",0,0)";
            steps[i].highlight_color       = "rgb(255," + (i * 4) + ",255)";
            steps[i].style.backgroundColor = steps[i].original_color;
            ladder.appendChild(steps[i]);
          }

          ladder.style.width       = (i * 20) + "px";
          ladder_trace.style.width = (i * 20) + "px";
          ladder_trace.width       = (i * 20);
          ladder_trace.height      = 20;
        }());

        ladder_p_over.textContent = mouse_over_count;
        ladder_p_out.textContent  = mouse_out_count;
      }, false);
    </script>
  </body>
</html>

1 Ответ

2 голосов
/ 09 сентября 2011

Это потому, что сначала они рендерится, а затем проверяют ввод.
Я тоже некоторое время расстраивался из-за этого, но несколько тестов подтвердили это.
Они рендерится и затем проверяют ввод.

Редактировать : Если у вас хороший компьютер и вы используете хорошее программное обеспечение для записи, попробуйте записать мышь с полной частотой кадров вашего монитора.Теперь играйте в замедленном темпе, например, 1/10 скорости.

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

  • Пройти через каждый пиксель, каждый кадр.
    Это ограничило бы скорость мыши (пикселей / секунду) до FPS (герц) вашего монитора.
  • Практически проходит каждый пиксель в субкадре.
    Это определенно потребует много времени процессора для обдумывания.

Чтобы исправить это, каждая ОС заставляет мышь переходить / переходить к необходимому пикселю в каждом кадре.
... и, таким образом, ваша проблема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...