我想知道是否有任何不引人注目的方式来挂钩诸如attr,data,css等方法并调用自定义触发器?
理想情况下,我可以这样做:
$(".friend a").bind("attr.changed", changed /* data */, function(e) {
alert("The " + changed.attribute + " attribute changed from " + changed.from + " to " + changed.to + "!");
});
$(".friend").append(
$("<a/>").
attr("href", "#").
html("Friend 1").
click(function() { alert('I was clicked!'); }); // creates the element, doesn't execute since element didn't exist
$(".friends a").each(function() {
var $this = $(this);
$this.attr("rel", "friend"); // triggers "attr.changed"
});
理想情况下,这可以在任何元素上触发,并将从对象更改的attr传递给每个jQuery方法内部的触发器调用。
答案 0 :(得分:7)
编写“钩子”函数非常容易:
function hook(original, wrapper) {
return function() {
wrapper.apply(this, arguments);
return original.apply(this, arguments);
}
}
在调用原始函数本身之前,将使用与wrapper
函数相同的参数调用您提供的original
函数。
使用示例:
$.fn.attr = hook($.fn.attr, function(attribute, value) {
alert('attribute: '+attribute+', value: '+value);
});
$('a.pie').attr('href', 'http://blueberry.pie');
// An alert says "attribute: href, value: http://blueberry.pie"
(旁注:让wrapper
取消对original
功能的调用是一个简单的扩展,但这比你想要的功能更强大。)
你可以直接使用它来做你想做的事情,或者你可以让wrapper
函数触发你用标准jquery方式监听的自定义jquery事件。
答案 1 :(得分:1)
原来这个黑客会起作用;我使用数据的内置setData触发器(以及前面提到的'hook'来在jQuery的attr和removeAttr上添加功能)来复制jQuery对象上的数据对象中的attrs。虽然它有点脏,但我得到的功能是挂钩数据,attr的数据更改触发器,如果编写,还有任何其他跟踪键/值对的jQuery方法。
(function($) {
var binder = function(e, dataKey, dataValue) {
return (function(dataKey, dataValue, self) {
var $this = $(self),
oldValue = $this.data(dataKey),
newValue = dataValue,
passed = {
attr: dataKey,
from: oldValue,
to: newValue
};
var isAttribute = !!($this.data(dataKey + "-attribute"));
if(oldValue !== newValue) {
var attrPrefix = isAttribute ? "attr-" : "";
$this.trigger(attrPrefix + dataKey + "-changed", passed);
$this.trigger(attrPrefix + "data-changed", passed);
}
})(dataKey, dataValue, this);
};
var hook = function(original, wrapper) {
return function() {
wrapper.apply(this, arguments);
return original.apply(this, arguments);
};
};
$.fn.attr = hook($.fn.attr, function(attr, val) {
if(val) {
$(this).data(attr + "-attribute", true);
$(this).data(attr, val);
}
});
$.fn.removeAttr = hook($.fn.removeAttr, function(attr) {
$(this).removeData(attr + "-attribute");
$(this).removeData(attr);
});
$.fn.observeData = function() {
$(this).bind("setData", binder);
};
})(jQuery);
答案 2 :(得分:0)
jQuery中目前没有此事件。
livequery plugin可能会提供您所需要的内容,例如更改课程。基本上保存了选择器,然后DOM中任何改变选择器影响的更改都会调用传递的函数等。
答案 3 :(得分:0)
为什么不使用最简单的方法:
jQuery.fn.changeAttr = function(attrName,attrValue) {
return this.each(function(){
this.attr(attrName,attrValue);
alert('The att: '+attrName+ ' is now '+attrValue);
});
};
然后只是:
$('.friends a').changeAttr('rel','friend')
很抱歉,如果它不起作用,我不记得确切扩展jQuery的语法。
答案 4 :(得分:0)
这是对attr()
的修改,与你所说的一致。
(function(attr) {
jQuery.attr = function(elem, name, value) {
var current = attr(elem, name, undefined); // read current value
var retval = current;
if (value !== undefined) { // writing
retval = attr(elem, name, value); // call original
jQuery.event.trigger('attr.changed', {
attribute: name,
from: current,
to: value
}, elem)
}
return retval; // return original
}
})(jQuery.attr);
用法应该是:
$(".friend a").bind("attr.changed", function(e, changed) {
alert("The " + changed.attribute + " attribute changed from " + changed.from + " to " + changed.to + "!");
});
$(".friends a").attr("class", "foo"); // triggers alert
我不相信css()
是可能的,因为.style
属性无法触发事件。 data()
我不知道。
注意我不宽恕它的用法,这只是学术上的努力。您希望在attr()
上产生性能损失,以填充事件参数的from
属性。在编写新值之前,我们必须先读取旧值。