我正在编写一个jquery片段来处理由任何jquery domManip函数(扩展某些函数)触发的DOM中的任何html内容更改。不确定这是最好的方式,所以任何建议都会受到欢迎。 如果绑定到文档,此代码段将按预期工作。但是,如果我尝试将其绑定到特定元素,我将遇到一些问题,其中一些功能为 .remove()。也许是因为自定义事件没有使用正常的传播行为,但我真的不确定。
这是一个工作示例,我将'contentChange'事件绑定到文档,跨浏览器工作,因为我可以测试它:{Firefox,IE9,Chrome和Win7下的Safari}
;
(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()
方法不会触发我的自定义事件。
我可以理解,如果我删除元素,将不会调用事件回调函数,但是为什么在删除子元素时不调用它(当它绑定到文档时它正在工作!)
我希望这一行将自定义事件气泡设为'#test':
$('#test').find('div:first').remove();
在操作此元素和/或其子元素时,有没有办法触发绑定到特定元素的自定义事件?
答案 0 :(得分:1)
您需要在已修改的元素上触发事件。
return oFct.apply(sender, args), sender.trigger('contentChange');
但是,通过该更改,您将不再捕获在未连接到DOM的元素上触发的事件,因为它不是该文档的后代,在我看来这是可以的,因为它不是与该DOM相关联,它位于DOM片段中。
答案 1 :(得分:0)
我带有稍微修改过的版本,似乎可以达到目的。
需要针对.on()
方法扩展进行优化,因此请随时分享您的反馈意见。
从这里启发:https://groups.google.com/forum/?fromgroups=#!topic/jquery-dev/ZaMw2XB6wyM
感谢Wil Stuckey
;(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);