4

这里 jsFiddle 来测试样本

我目前正在编写一个 jquery 片段来处理由任何 jquery domManip 函数(扩展一些函数)“触发”的 DOM 中的任何 html 内容更改。不确定这是最好的方法,所以欢迎任何建议。如果绑定到文档,此代码段将按预期工作。但是,如果我尝试将其绑定到特定元素,我将面临某些功能为.remove()的问题。也许这是由于自定义事件没有使用正常的传播行为,但我真的不确定。

这是一个工作示例,我将“contentChange”事件绑定到文档,可以跨浏览器工作,因为我可以测试它:{Firefox、IE9、Chrome 和 Safari 在 Win7}

;
(function ($) {
    $.fn.contentChange = function (types, data, fn) {
        return this.on('contentChange', types, null, data, fn);
    };
    var oDomManip = $.fn.domManip,
        oHtml = $.fn.html,
        oEmpty = $.fn.empty,
        oRemove = $.fn.remove,
        extendFct = function (oFct, sender, args) {
            return oFct.apply(sender, args), $.event.trigger('contentChange');
            //=>if testing specific element (#test) use instead following line
             //return oFct.apply(sender, args), $(sender).trigger('contentChange');
        };
    $.fn.domManip = function () {
        extendFct(oDomManip, this, arguments)
    };
    $.fn.html = function () {
        extendFct(oHtml, this, arguments)
    };
    $.fn.empty = function () {
        extendFct(oEmpty, this, arguments)
    };
    $.fn.remove = function () {
        extendFct(oRemove, this, arguments)
    };

})(jQuery);

我使用:$.event.trigger('contentChange') 触发自定义事件。

像这样称呼:

$(document).contentChange(function () {
    console.log("onContentChange")
});

但是,如果我使用:

$('#test').contentChange(function () {
    console.log("onContentChange")
});

不会触发自定义事件。因此,要在特定元素上触发自定义事件,我可以像这样触发它:

$(sender).trigger('contentChange');

但是现在,remove()对 self 或 children 的方法调用不会触发我的自定义事件。我可以理解,如果我删除元素,将不会调用事件回调函数,但是为什么在删除子元素时不调用它(如果绑定到文档则它正在工作!)?

期待这条线将自定义事件气泡设为“#test”:

$('#test').find('div:first').remove();

在操作此元素和/或其子元素时,是否有任何方法可以触发绑定到特定元素的自定义事件?

4

2 回答 2

1

您需要在被修改的元素上触发事件。

http://jsfiddle.net/Gw4Lj/2/

return oFct.apply(sender, args), sender.trigger('contentChange');

但是,通过该更改,您将不再捕获在未连接到 DOM 的元素上触发的事件,因为它不是该文档的后代,我认为这没问题,因为它没有关联对于那个 DOM,它在一个 DOM 片段中。

于 2013-04-10T14:20:05.190 回答
0

我提供了稍微修改过的版本,似乎可以很好地达到我的目的。需要对.on()方法扩展进行优化,所以请随时分享您的反馈。

灵感来自这里:https ://groups.google.com/forum/?fromgroups=#!topic/jquery-dev/ZaMw2XB6wyM

感谢威尔·斯塔基

这里是 jsFiddle

;(function ($) {
    var fctsToObserve = {
        append: [$.fn.append, 'self'],
        prepend: [$.fn.prepend, 'self'],
        remove: [$.fn.remove, 'parent'],
        before: [$.fn.before, 'parent'],
        after: [$.fn.after, 'parent']
    }, fctsObserveKeys = '';
    $.each(fctsToObserve, function (key, element) {
        fctsObserveKeys += "hasChanged." + key + " ";
    });
    var oOn = $.fn.on;
    $.fn.on = function () {
        if (arguments[0].indexOf('hasChanged') != -1) arguments[0] += " " + fctsObserveKeys;
        return oOn.apply(this, arguments);
    };
    $.fn.hasChanged = function (types, data, fn) {
        return this.on(fctsObserveKeys, types, null, data, fn);
    };
    $.extend($, {
        observeMethods: function (namespace) {
            var namespace = namespace ? "." + namespace : "";
            var _len = $.fn.length;
            delete $.fn.length;
            $.each(fctsToObserve, function (key) {
                var _pre = this;
                $.fn[key] = function () { 
                    var target = _pre[1] === 'self' ? this : this.parent(),
                        ret = _pre[0].apply(this, arguments);
                    target.trigger("hasChanged." + key + namespace, arguments);
                    return ret;
                };
            });
            $.fn.length = _len;
        }
    });
    $.observeMethods()
})(jQuery);
于 2013-04-12T14:09:20.350 回答