в javascript, ръчно контролиращ реда на слушателите на събития

Ако приемем, че FORM съдържа INPUT, имайте следните слушатели:

javascript

function formFirst(e) { ... }
function formLast(e) { ... }
function inputFirst(e) { ... }
function inputLast(e) { ... }
function middle(e) { ... }

document.getElementById('form').addEventListener('change',formFirst,true);
document.getElementById('form').addEventListener('change',formLast,false);
document.getElementById('input').addEventListener('change',inputFirst,true);
document.getElementById('input').addEventListener('change',inputLast,false);

желан ред на изпичане

formFirst()   // normal - outer element, useCapture = true
inputFirst()  // normal - triggering element, declared first
middle()      // -- how to do this?
inputLast()   // normal - triggering element, declared second
formLast()    // normal - outer element, useCapture = false

естеството на проблема и опита за решения

Собствен код на ниво FORM, formFirst, formLast и middle, но няма достъп до INPUT код, inputFirst и inputLast - въпреки че може да добави собствени слушатели на INPUT.

Опит 1 модифицира formFirst() за създаване и изпращане на нов change Event (ще бъде игнориран в рамките на formFirst), който ще извика inputFirst(), но няма начин да спре разпространението, за да предотврати последващото извикване на inputLast().

Опит 2 добавяне на middle като слушател към INPUT, но не може да гарантира реда на задействане на два слушателя от един и същи тип и една и съща употребаCapture.


Предпоставката на опит 2 е неправилна - редът на изстрелване се определя от реда на деклариране в целевия елемент.

Ето правилата

  1. нецелеви елемент задейства с useCapture=false, започвайки от най-външния елемент и работейки към целевия елемент

    a) ако повече от един useCapture=true се задейства за един и същ елемент, тогава редът на деклариране.

  2. в целевия елемент, ред на деклариране, независимо от useCapture

  3. нецелевият елемент се задейства с useCapture=false, започвайки от най-вътрешния елемент и работейки далеч от целевия елемент

    a) ако повече от един useCapture=false се задействат за един и същ елемент, тогава редът на деклариране.


person cc young    schedule 26.09.2011    source източник


Отговори (1)


Мисля, че това отговаря точно на въпроса ви. не се колебайте да коментирате\свържете се с мен за повече информация.

----- редактиране ------

Добре, просто си поиграх малко с него, както обещах, и намерих много просто решение:

<script type="text/javascript">
function formFirst(e) { alert(1); }
function formLast(e) { alert(5); }
function inputFirst(e) { alert(2); }
function inputLast(e) { alert(4); }
function middle(e) { alert(3); }

function init(){
    document.getElementById('form').addEventListener('change',formFirst,true);
    document.getElementById('form').addEventListener('change',formLast,false);
    document.getElementById('input').addEventListener('change',inputFirst,true);
    document.getElementById('input').addEventListener('change',middle,true);
      /*** alternative to last tow lines  
    document.getElementById('input').addEventListener('change',function(){inputFirst();middle();},true);
         **/
    document.getElementById('input').addEventListener('change',inputLast,false);
}

</script>
<body onload="init();">
<form id="form">
<input type="text" id="input" /> <br />
</form>
</body>

забележка:

  • Поставих частта addEventListener във функция init, така че мога да я извикам, след като страницата е заредена и елементът вече съществува.
  • Изпълних това само на chrome. Така че не искам да ви гарантирам неща за други браузъри.
  • Алтернатива е да напишете сами обработката на събития. ето пример за това. разчитайки на тази статия.

    <script type="text/javascript">
    
    function formFirst(e) { alert(1); }
    function formLast(e) { alert(5); }
    function inputFirst(e) { alert(2); }
    function inputLast(e) { alert(4); }
    function middle(e) { alert(3); }
    
    function init(){
    
      //create event
      myHandler = new Event();
    
      //add handler
      myHandler.addHandler(formFirst);
      myHandler.addHandler(inputFirst);
      myHandler.addHandler(middle);
      myHandler.addHandler(inputLast);
      myHandler.addHandler(formLast);
    
      //regiser one listener on some object
      document.getElementById('input').addEventListener('change',function(){myHandler.execute();},true);
    }
    
    
    function Event(){
      this.eventHandlers = new Array();
    }
    
    Event.prototype.addHandler = function(eventHandler){
      this.eventHandlers.push(eventHandler);
    }
    
    Event.prototype.execute = function(){
      for(var i = 0; i < this.eventHandlers.length; i++){
        this.eventHandlers[i]();
      }
    }
    
    
    </script>
    <body onload="init();">
    <form id="form">
    <input type="text" id="input" /> <br />
    </form>
    </body>
    
person Ramzi Khahil    schedule 26.09.2011
comment
за вашия конкретен пример, просто използвайте 'ture' като трети параметър за всички ваши слушатели на събития. - person Ramzi Khahil; 26.09.2011
comment
от моите тестове мисля, че не сте прави. ако formLast бяха добавени с useCapture = true, тогава formLast щеше да се задейства преди задействанията INPUT, а не да ги следва, както става сега. - person cc young; 26.09.2011
comment
Ти си прав. Не мислех, че хвърля. Опитайте тази статия, там можете създайте свои собствени манипулатори. И не съм го пробвал (просто го намерих). Но предполагам, че можете да прикачите средната функция към манипулатора на събития, който задейства функцията inputFirst, така че манипулаторът по-късно да задейства средния метод. Вечерта ще играя с тази опция. Така че уведомете ме, ако това все още не работи. - person Ramzi Khahil; 26.09.2011
comment
Съжалявам, че отне толкова време, за да се върна - преместване. Прав сте - редът на създаване на слушатели определя реда на задействане в рамките на целта - въпреки че има смисъл true тригерите да се задействат преди false, тъй като при нецел, това не е така. - person cc young; 05.10.2011
comment
Здравей отново. Преди няколко дни прочетох нещо за jQuery, не е това, което искате, но може да помогне. защото има опция callback. което означава, че извиквате един метод и в обратното извикване изпращате следващия (създаване на верига за изпълнение). Може да е проблематично, ако по някакъв начин теглите полета като това задействане едновременно. Но за събитието change се съмнявам в това. - person Ramzi Khahil; 18.10.2011