в JavaScript, вручную контролируя порядок прослушивателей событий - PullRequest
7 голосов
/ 26 сентября 2011

Предполагая, что 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 - хотя может добавить собственных слушателей на входе.

Попытка 1 изменить formFirst() для создания и отправки нового change Event (будет игнорироваться в formFirst), который будет вызывать inputFirst(), но не сможет остановить распространение для предотвращения inputLast() вызывается впоследствии.

Попытка 2 add middle добавлена ​​как слушатель INPUT, но не может гарантировать порядок запуска двух слушателей одного типа и одного и того же useCapture.

<ч />

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

Вот правила

  1. нецелевой элемент срабатывает с useCapture=false, начиная с самого дальнего элемента и двигаясь к целевому элементу

    а) если более одного useCapture=true срабатывает для одного и того же элемента, то порядок объявления.

  2. у целевого элемента, порядок объявления, независимо от useCapture

  3. нецелевой элемент срабатывает с useCapture=false, начиная с самого внутреннего элемента и удаляясь от целевого элемента

    a) если более одного useCapture=false запускает один и тот же элемент, то порядок объявления.

1 Ответ

3 голосов
/ 26 сентября 2011

Я думаю, что это отвечает только на ваш вопрос. не стесняйтесь комментировать \ свяжитесь со мной для получения дополнительной информации.

----- редактировать ------

ОК, я немного поиграл с ним, как и обещал, и нашел очень простое решение:

<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>
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...