zoukankan      html  css  js  c++  java
  • IE与非IE浏览器在事件绑定的执行顺序问题

    原始的DOM1事件处理机制,是不能绑定多个处理函数。如一个元素在onclick事件先绑定一个函数,用来alert其id,然后再在相同的事件绑定另一个函数,用来alert其style。对不起,第二个函数会覆盖掉第一个,只会alert其style。于是.addEventListener() 与 .attachEvent()被分别开发出来了。为了屏蔽各浏览器的差异,javascript界举办了一个慈善邀请赛,鼓励大家提交各自addEvent/removeEvent 方案,最后由John Resig大神获得。

      function addEvent( obj, type, fn ) {
        if ( obj.attachEvent ) {
          obj["e"+type+fn] = fn;
          obj[type+fn] = function(){obj["e"+type+fn]( window.event );}
          obj.attachEvent("on"+type, obj[type+fn] );
        } else
          obj.addEventListener( type, fn, false );
      }
      function removeEvent( obj, type, fn ) {
        if ( obj.detachEvent ) {
          obj.detachEvent("on"+type, obj[type+fn] );
          obj[type+fn] = null;
        } else
          obj.removeEventListener( type, fn, false );
      }
    

    但是最近我在同一个元素绑定多个onclick事件时,发现些问题。

    IE8与其他标准浏览器会弹出1,2,3,4,换言之,先进先出。IE6非先进先出,也不是后进先出,而是2,4,3,1。但如果我们绑定更多函数,IE8的执行顺序就有问题了,IE6与IE7更不用说。谁有好的解决方法吗?

      /**
       * addEvent & removeEvent -- cross-browser event handling
       * Copyright (C) 2006-2007  Dao Gottwald
       *
       * This library is free software; you can redistribute it and/or
       * modify it under the terms of the GNU Lesser General Public
       * License as published by the Free Software Foundation; either
       * version 2.1 of the License, or (at your option) any later version.
       *
       * This library is distributed in the hope that it will be useful,
       * but WITHOUT ANY WARRANTY; without even the implied warranty of
       * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       * Lesser General Public License for more details.
       *
       * You should have received a copy of the GNU Lesser General Public
       * License along with this library; if not, write to the Free Software
       * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
       *
       * Contact information:
       *   Dao Gottwald  <dao at design-noir.de>
       *
       * @version  1.2.1
       */
    
      function addEvent(o, type, fn) {
        o.addEventListener(type, fn, false);
      }
      function removeEvent(o, type, fn) {
        o.removeEventListener(type, fn, false);
      }
      /*@cc_on if (!window.addEventListener) {
      var addEvent = function (o, type, fn) {
        if (!o._events) o._events = {};
        var queue = o._events[type];
        if (!queue) {
          o._events[type] = [fn];
          if (!o._events._callback)
            o._events._callback = function (e) { Event._callListeners(e, o) };
          o.attachEvent("on" + type, o._events._callback);
        } else if (Event._fnIndex(o, type, fn) == -1)
          queue.push(fn);
        else return;
        Event._mem.push([o, type, fn]);
      };
      var removeEvent = function (o, type, fn) {
        var i = Event._fnIndex(o, type, fn);
        if (i < 0) return;
        var queue = o._events[type];
        if (queue.calling) {
          delete queue[i];
          if (queue.removeListeners)
            queue.removeListeners.push(i);
          else
            queue.removeListeners = [i];
        } else
          if (queue.length == 1)
            Event._detach(o, type);
          else
            queue.splice(i, 1);
      };
      var Event = {
        AT_TARGET: 2,
        BUBBLING_PHASE: 3,
        stopPropagation: function () { this.cancelBubble = true },
        preventDefault: function () { this.returnValue = false },
        _mem: [],
        _callListeners: function (e, o) {
          e.stopPropagation = this.stopPropagation;
          e.preventDefault = this.preventDefault;
          e.currentTarget = o;
          e.target = e.srcElement;
          e.eventPhase = e.currentTarget == e.target ? this.AT_TARGET : this.BUBBLING_PHASE;
          switch (e.type) {
            case "mouseover":
              e.relatedTarget = e.fromElement;
              break;
            case "mouseout":
              e.relatedTarget = e.toElement;
          }
          var queue = o._events[e.type];
          queue.calling = true;
          for (var i = 0, l = queue.length; i < l; i++)
            if (queue[i])
              if ("handleEvent" in queue[i])
                queue[i].handleEvent(e);
              else
                queue[i].call(o,e);
          queue.calling = null;
          if (!queue.removeListeners)
            return;
          if (queue.length == queue.removeListeners.length) {
            this._detach(o, e.type);
            return;
          }
          queue.removeListeners = queue.removeListeners.sort(function(a,b){return a-b});
          var i = queue.removeListeners.length;
          while (i--)
            queue.splice(queue.removeListeners[i], 1);
          if (queue.length == 0)
            this._detach(o, e.type);
          else
            queue.removeListeners = null;
        },
        _detach: function (o, type) {
          o.detachEvent("on" + type, o._events._callback);
          delete o._events[type];
        },
        _fnIndex: function (o, type, fn) {
          var queue = o._events[type];
          if (queue)
            for (var i = 0, l = queue.length; i < l; i++)
              if (queue[i] == fn)
                return i;
          return -1;
        },
        _cleanup: function () {
          for (var m, i = 0; m = Event._mem[i]; i++)
            if (m[1] != "unload" || m[2] == Event._cleanup)
              removeEvent(m[0], m[1], m[2]);
        }
      };
      addEvent(window, "unload", Event._cleanup);
    } @*/
    

    后来,又发现Dean Edwards也修正了IE事件顺序错乱问题

      // addEvent/removeEvent written by Dean Edwards, 2005
      // with input from Tino Zijdel
      // http://dean.edwards.name/weblog/2005/10/add-event/
      function addEvent(element, type, handler) {
        if (!handler.$$guid) handler.$$guid = addEvent.guid++;
        if (!element.events) element.events = {};
        var handlers = element.events[type];
        if (!handlers) {
          handlers = element.events[type] = {};
          if (element["on" + type]) {
            handlers[0] = element["on" + type];
          }
        }
        handlers[handler.$$guid] = handler;
        element["on" + type] = handleEvent;
      };
      addEvent.guid = 1;
      function removeEvent(element, type, handler) {
        if (element.events && element.events[type]) {
          delete element.events[type][handler.$$guid];
        }
      };
      function handleEvent(event) {
        var returnValue = true;
        event = event || fixEvent(window.event);
        var handlers = this.events[event.type];
        for (var i in handlers) {
          this.$$handleEvent = handlers[i];
          if (this.$$handleEvent(event) === false) {
            returnValue = false;
          }
        }
        return returnValue;
      };
      function fixEvent(event) {
        event.preventDefault = fixEvent.preventDefault;
        event.stopPropagation = fixEvent.stopPropagation;
        return event;
      };
      fixEvent.preventDefault = function() {
        this.returnValue = false;
      };
      fixEvent.stopPropagation = function() {
        this.cancelBubble = true;
      };
    
      function addEvent(element, type, handler) {
        if (!handler.$$guid) handler.$$guid = addEvent.guid++;
        if (!element.events) element.events = {};//一个巨大的哈希,
        var handlers = element.events[type];
        if (!handlers) {
          handlers = element.events[type] = {};//哈希的每一个键都是哈希
          if (element["on" + type]) {
            handlers[0] = element["on" + type];
          }
        }
        handlers[handler.$$guid] = handler;
        element["on" + type] = function(event) {
          var returnValue = true;
          event = event || window.event;
          var handlers = this.events[event.type];
          for (var i in handlers) {
            this.$$handleEvent = handlers[i];
            if (this.$$handleEvent(event) === false) {
              returnValue = false;
            }
          }
          return returnValue;
        };
      };
      addEvent.guid = 1;
    
  • 相关阅读:
    决策树之C4.5算法
    决策树之ID3算法
    AndroidStudio 3.4.2配置 Opencv 3.7
    Android 实现在ImageView上绘图
    Opencv 对比度增强 C++
    Opencv对比度增强 python API
    hive中与hbase外部表join时内存溢出(hive处理mapjoin的优化器机制)
    hive的数据导入与数据导出:(本地,云hdfs,hbase),列分隔符的设置,以及hdfs上传给pig如何处理
    hive的map类型处理
    pig的udf编写
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/1570327.html
Copyright © 2011-2022 走看看