在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级, formFirstformLastmiddle拥有代码,但无法访问INPUT代码, inputFirstinputLast - 虽然可以在INPUT上添加自己的侦听器。

尝试1修改formFirst()以创建和分派新的change Event (将在formFirst被忽略),它将调用inputFirst() ,但无法停止传播以防止随后调用inputLast()

尝试2添加middle作为侦听器添加到INPUT,但不能保证两个相同类型和相同useCapture的侦听器的触发顺序。


尝试2的前提不正确 - 射击顺序由目标元素内的声明顺序决定。

这是规则

  • 非目标元素使用useCapture=false触发,从最外层的元素开始并朝目标元素工作

    a)如果多于一个useCapture=true触发相同的元素,则声明的顺序。

  • 在目标元素,声明的顺序,不管useCapture

  • 非目标元素使用useCapture=false触发,从最里面的元素开始并远离目标元素

    a)如果多于一个useCapture=false触发相同的元素,则声明的顺序。


  • 我认为这只是回答你的问题。 随时发表评论联系我的更多信息。

    -----编辑------

    好吧,我只是按照承诺玩了一下,我找到了一个非常简单的解决方案:

    <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>
    
  • 链接地址: http://www.djcxy.com/p/9361.html

    上一篇: in javascript, manually controlling order of event listeners

    下一篇: Rotating Three20 TTPhotoViewController inside TabBarController