关于jquery hashChange反复添加hash之后造成多次触发事件的bug
更新:HHH   时间:2023-1-7


        jquery hashChange是一个监听浏览器hash的改变,根据hash的改变进行对应的触发对应事件的插件。

       读了事件加载的源码才理解了其中的缘故,这之间踩过一些坑,写下来希望能帮到之后用它的人。


        hashchange的主要的原理是监听浏览器的hashchange事件然后将事件进行分发,利用ajax处理事物的一种机制。

        最近项目用到了这个插件,我们的项目用到了jqeury的ajax update进行异步的加载页面并把页面的内同append到对应的区域中去,起先我以为是ajaxUpdate加载页面时把页面的js反复的加载导致我的页面出现触发两次或者更多次事件,所以再进行该页面的下一步操作的时候会发现所有的方法都对应到了一个dom层,如果是提交表单会同时提交好多次。并且此时后台返回的数据也会出现异常。

关于hashchange添加hash参数的时候,原来的代码是这么写的:


$.fn.hashchange = function(options) {
    // options array passed
    if (Object.prototype.toString.call(options) === "[object Array]") {
      for (var i = options.length - 1; i >= 0; i--) {
        methods.init.apply(this, [options[i]]);
      }
      return this;
    }
    // single option passed
    return methods.init.apply(this, arguments);
  };
查看源码才知道原来它在添加hash参数的时候并不会进行排重,所以加了很多的hash参数,然后就会导致触发一个事件的时候,触发很多次方法

$.fn.hashchange = function (options) {
    //by chenjianhui
    var self = this;
    var _options = window._options;
    // options array passed
    if (Object.prototype.toString.call(options) === "[object Array]") {
        //for (var i = options.length - 1; i >= 0; i--) {
        //    methods.init.apply(this, [options[i]]);
        //}
        //如果已有的option为空
        if (_options == undefined) {
            window._options = new Array();
            for (var i = options.length - 1; i >= 0; i--) {
                window._options.push(options[i]);
                methods.init.apply(this, [options[i]]);
            }
        } else {
            for (var i = options.length - 1; i >= 0; i--) {
                var isHas = false;
                for (var j in _options) {
                    if (_options[j].hash == options[i].hash) {
                        isHas = true;
                    }
                }
                if(!isHas){
                    window._options.push(options[i]);
                    methods.init.apply(this, [options[i]]);
                }
            }
        }
        return this;
    }

        通过以上的代码我将传进来的option临时放到了windows对象里面,因为这些值应该属于一个全局使用的一个值。


        至此之后添加进来的hash就不会再有重复的hash值,这样就不会造成反复添加hash然后一个hash产生多次触发事件的情况了。

        这个代码应该还有优化的空间比如在判断是否存在的问题上可以使用jquery的isInArray方法可能更加直观。如果更好的改进方案请联系,大家一起前进。

返回web开发教程...