[Javascript] 是否有任何不显眼的方式来钩入触发器的jQuery方法?


Answers

原来这个黑客会起作用; 我使用数据的内置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);
Question

我想知道是否有任何不显眼的方式挂钩到attr,数据,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和from更改为每个jQuery方法内的触发器调用。




为什么不使用最简单的方法:

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的语法。