jQuery移除元素自动解绑事件实现

世界本该如此!

所以,在现代浏览器,如果你将一个元素从DOM树种进行移除的时候,浏览器会自动帮你绑定的事件进行解绑以释放其占用的内存。也许你猜到了,较老版本的浏览器则不会主动去做这件事,所以,当你的应用在较老版本的浏览器运行的越久,其消耗内存越多,应用就会变得越来越卡。因此,需要我们自己对要删除的元素进行事件解绑。

实现思路

用jQuery将元素移除的基本方法常用的有三个,一个是remove()方法,一个是html()方法,一个是empty()方法。我们可以对此三个方法进行进一步的封装,我们会在事件绑定的时候给绑定事件的元素添加一个属性标识,从要删除的元素中去寻找有此标识的元素,然后进行事件的完全解绑。一切都是那么的巧妙!需要注意的一点是,remove()方法在执行的时候会对其自身进行事件解绑,并且该方法可以接受一个选择器参数,以删除其子元素。

实现代码

有了实现思路,编码可以很快搞定。如下:

define(['jquery', 'underscore'], function () {
    var bindDirects = ['delegate', 'bind','on', 'hover', 'blur', 'change', 'click', 'dblclick', 'focus', 'keydown', 'keypress', 'keyup', 'mousedown', 'mouseenter', 'mouseleave', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'resize', 'scroll', 'select', 'submit'];
    var eMarker = '_addedEvent';
    _.each(bindDirects, function (eventName) {
        var alias = $.fn[eventName];
        $.fn[eventName] = function () {
            var $tar = _.isElement(this)?$(this):this;
            var hasEventAdded = $tar.attr(eMarker) || '';
            var _en = eventName;
            if (hasEventAdded.length) {
                _en += ',' + hasEventAdded;
            }
            $tar.attr(eMarker, _en);
            return alias.apply(_.isElement(this)?$tar:this, [].slice.call(arguments));
        };
    });
    // 为某一个元素移除绑定的事件
    function removeEvents($tar) {
        var addedEventsName = $tar.attr(eMarker);
        if (addedEventsName) {
            addedEventsName.replace(/[^,]+/g, function (eventName) {
                // 全部移除
                if (eventName === 'delegate') {
                    $tar.undelegate();
                } else {
                    $tar.unbind();
                }
                return eventName;
            });
        }
    }

    var funcs = ['html','empty'];
    _.each(funcs, function (func) {
        var alias = $.fn[func];
        $.fn[func] = function () {
            var $tar = _.isElement(this)?$(this):this;
            if($tar.length){
                $tar.find('*[' + eMarker + ']').each(function (k, subEl) {
                    try{
                        removeEvents($(subEl));
                    }catch(e){
                        console.error(e.message);
                    }
                });
            }
            var args = [].slice.call(arguments);
            return alias.apply($tar, args);
        };
    });
    // 扩展remove()方法
    var alias = $.fn.remove;
    $.fn.remove = function () {
        var $tar = _.isElement(this)?$(this):this,
            arg = arguments;
        if($tar.length && !arg.length){
            $tar.find('*[' + eMarker + ']').each(function (k, subEl) {
                try{
                    removeEvents($(subEl));
                }catch(e){
                    console.error(e.message);
                }
            });
        }
        if(arg.length){
            var selector = arg[0];
            if(_.isString(selector)){
                $tar.find(selector).each(function(k,curEl){
                    var $cur = $(curEl);
                    $cur.find('*[' + eMarker + ']').each(function (k, subEl) {
                        try{
                            removeEvents($(subEl));
                        }catch(e){
                            console.error(e.message);
                        }
                    });
                    removeEvents($cur);
                    $cur.remove();
                });
            }
        }
        var args = [].slice.call(arguments);
        return alias.apply($tar, args);
    };
});



还是那句话,了解的越多,你能做的就越多!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值