是否有任何不引人注目的方式来挂钩触发器的jQuery方法?
我想知道是否有任何不引人注目的方法来挂钩诸如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( $(""). 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方法内部的触发器调用。
编写“钩子”函数非常简单:
function hook(original, wrapper) { return function() { wrapper.apply(this, arguments); return original.apply(this, arguments); } }
在调用原始函数本身之前,将使用与original
函数相同的参数调用您提供的wrapper
函数。
使用示例:
$.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
function的调用也是一个简单的扩展,但这比你想要的更有用。)
您可以直接使用它来执行您想要的操作,或者您可以使wrapper
函数触发您以标准jquery方式侦听的自定义jquery事件。
原来这个黑客会起作用; 我使用数据的内置setData触发器(以及前面提到的’hook’来在jQuery的attr和removeAttr上添加function)来复制jQuery对象上的数据对象中的attrs。 虽然它有点脏,但我得到的function是挂钩数据更改触发器,数据,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);
目前jQuery中没有这个事件。
livequery插件可以提供您需要的东西,例如更改类。 基本上保存选择器,然后DOM中任何更改选择器影响的更改都会调用传递的函数等。
为什么不使用最简单的方法:
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的语法。
这是对你所谈论的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()
我不知道。
注意我不宽恕它的用法,这只是学术上的努力。 为了填充事件参数的from
属性,你想要对attr()
产生性能损失。 在编写新值之前,我们必须读取旧值。