Сравнение методов связывания события mouseleave с событием mouseenter в jQuery - PullRequest
5 голосов
/ 15 июля 2011

Я хочу вызвать событие, когда моя мышь входит в div, и отдельное событие, когда оно покидает div, используя jQuery.Я знаю, что существует множество плагинов, примеров кода и т. Д., Которые решают эту конкретную проблему.Мне просто любопытно, какой способ будет наиболее эффективным с точки зрения как производительности, так и управления памятью.

Так, например, предположим, что у нас есть HTML-код, подобный следующему:

<div class="mouse-trap"> 1   </div>
<div class="mouse-trap"> 2   </div>
...
<div class="mouse-trap"> n-1 </div>
<div class="mouse-trap"> n   </div>

1.Отдельные события

Мы можем поддерживать события отдельно.Этот код читабелен и с ним легко работать.

$(".mouse-trap").bind('mouseenter', function() {
    // mouse came in
});

$(".mouse-trap").bind('mouseleave', function() {
    // mouse left
});

2.Вложенные события

Вместо того, чтобы постоянно хранить событие «mouseleave», создавайте его только тогда, когда это необходимо, и затем удаляйте его, когда мы закончим, поскольку для каждого указателя мыши будет только одно событие Mouseleave.event.

$(".mouse-trap").bind('mouseenter', function() {
    // mouse came in

    $(this).one('mouseleave', function() {
        // mouse left
    });
});

В первом сценарии, если у вас есть n событий, это означает, что jQuery постоянно должен прослушивать nx 2 событий.

Во втором сценарии, предполагая, что элементы div не вложены друг в друга, вы прослушиваете только n + 1 событий в любой заданной точке.

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


Теперь, как все изменится, если вы можете иметь div, вложенные друг в друга?

Например:

<div class="mouse-trap">
    <div class="mouse-trap">
        <div class="mouse-trap">
        ...
        </div>
        <div class="mouse-trap">
        ...
        </div>
    </div>
    ...
    <div class="mouse-trap">
        ...
    </div>
</div>

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

Поскольку они вложенные, я считаю, что событие "mouseleave" не будет вызванона внешних divs, как вы двигаетесь внутрь.В этом случае я считаю, что оба сценария должны будут отслеживать события nx 2 , но только при наведении курсора на самый внутренний элемент div.


Теперь возникает другой вопрос о том, сколько накладных расходов требуется для привязки и отмены привязки событий.Я думал, что прочитал некоторое время назад, что jQuery хранит все события в очереди, хотя я не смог найти конкретную документацию, подтверждающую это при исследовании этой проблемы.Таким образом, в зависимости от используемой структуры данных, очередь / очередь может иметь стоимость O (1) или O (n) ,Кто-нибудь знает специфику этого?

В сценарии 1 вы связываете все сразу, и вам больше не нужно с этим связываться (за исключением новых ловушек div.mouse, которые динамически добавляются на страницу).Это nx 2 привязок, которые имеют место.

В сценарии 2 вы только привязываете n событий заранее,но теоретически не может быть предела тому, сколько раз вы входите и выходите из области мышью.Это создает возможность для бесконечных необходимых привязок.Но в том же отношении мышь (и человек, управляющий этой мышью) могут двигаться только так быстро, поэтому эти привязки также распределяются в течение более длительного периода времени.Это может свести к минимуму влияние многочисленных привязок.


Все это говорит о том, что я думаю, что второй сценарий, вероятно, лучше, но я пропускаю что-то еще?Есть ли другие способы сделать это лучше, чем два, которые я перечислил?

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

Ответы [ 5 ]

3 голосов
/ 19 июля 2011

Оберните все .mouse-trap в div, свяжите события только один раз для этого и используйте event.target, чтобы обработать его.следует профилировать его и посмотреть, какое решение лучше для you .

0 голосов
/ 23 июля 2011

Возможно, это не тот ответ, который вы ищете, но ..
Не стоит так сильно беспокоиться об управлении производительностью и памятью - для современных компьютеров эта конкретная проблема настолько тривиальна, что анализ даже на таком детальном уровне не стоит анализировать. Я думаю, что гораздо более важным является чистота и удобство сопровождения вашего кода. Так что держите это просто с функцией hover () :

$('.mouse-trap').hover(
  function() {
    // mouse in

  },
  function() {
    // mouse out
  }
);
0 голосов
/ 22 июля 2011

Как насчет O (2) решения, подобного этому:

HTML:

<div class="mouse-trap-container">
  <div class="mouse-trap"> 1   </div>
  <div class="mouse-trap"> 2   </div>
   ...
  <div class="mouse-trap"> n-1 </div>
  <div class="mouse-trap"> n   </div>
</div>

JS:

$('div.mouse-trap-container')
   .delegate('div.mouse-trap', 'mouseenter', function(e) {
      // mouse came in
 }).delegate('div.mouse-trap', 'mouseleave', function(e) {
     // mouse left
 });
0 голосов
/ 19 июля 2011

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

И о некоторых ваших проблемах:

  • Как сказал Тимоти Джонс в комментарии, вы должны учитывать область действия включенных в замыкания замыканий может оказать большое влияние на память . Как говорится в статье, использование аргументов функции внутри обратного вызова потенциально может вызвать проблемы с производительностью (о которых я не знал до сих пор, полезно знать). Даже если вы не совсем делаете этого в своем подходе, то, как вы прикрепляете свои события, не очень далеко от него, и вы можете потенциально попасть в ловушку по мере вашего развития. Если у вас два отдельных мероприятия, вам даже не придется об этом беспокоиться.

  • В сценарии с вложенными элементами, как я предложил в своем комментарии, вместо этого вы можете использовать подходы mouseover и mouseout. Следует позаботиться о том, чтобы « входил в ребенка, оставаясь при этом в родительском », поскольку ввод ребенка с mouseover вызовет mouseout для родителя.

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

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

0 голосов
/ 18 июля 2011

может быть лучше, как это:

jQuery.fn.mouse_trap=function(f1,f2)
{ 
 var obj=$(this);
 obj.one('mouseenter',function(){enter(obj)});
 function enter(obj) {
  f1(obj);
  obj.one('mouseleave',function(){leave(obj)})
 }
 function leave(obj) {
  f2(obj);
  obj.one('mouseenter',function(){enter(obj)})
 }}

$(".mouse-trap").mouse_trap(function() {
    // mouse came in
},function() {
    // mouse came out
});

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

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