保存并恢复jQuery对象上的“onclick”操作

时间:2011-07-11 22:42:20

标签: javascript jquery function

我想在页面上禁用一大堆对象,然后再重新启用它们。由于其中一些是标签而不是按钮,我通过删除它们的onclick attr来禁用它们。我试图将旧处理程序存储在.data()中,但不幸的是,当我尝试使用$(obj).attr('onclick',$(obj).data('onclick'))恢复它们时,它调用函数而不是将其恢复到属性。如果我尝试将它存储在不同的属性而不是数据中,它不存储函数,它存储函数的返回值。

有没有办法在不重写我页面上的每个标签和每个onclick处理程序的情况下完成此操作?

if( doEnable) {

    $(obj).attr('href', $(obj).data('href'));
    $(obj).attr('onclick', $(obj).data('onclick'));


    $(obj).removeClass(EIS.config.classes.disabled);
    $(obj).show();

}
else {
    // Save the things you're going to remove
    $(obj).data('onclick', $(obj).attr('onclick'));
    $(obj).data('href', $(obj).attr('href'));

    $(obj).prop("href", null);
    $(obj).prop("onclick", null);

    $(obj).addClass(EIS.config.classes.disabled);
    $(obj).show();
   }

顺便说一句,这段代码似乎在Chrome和Firefox中运行良好,但有时只在IE8中运行,而在IE6中从未运行过。不幸的是,客户端首先在IE6中进行测试。

3 个答案:

答案 0 :(得分:6)

$(obj).attr('onclick', ...

含糊不清,结果在不同版本的jQuery和不同浏览器中有所不同。它可能不会做你想要的。您应该避免在事件处理程序上使用attr

问题是onclick 属性onclick 属性之间的脱节。 jQuery试图在过去的地毯下刷新属性和属性之间的区别,使用attr来访问它们,但它们完全不同。这在jQuery 1.6中有所改变,并在1.6.1中部分恢复,引起了广泛的争议,混乱和不兼容。

对于许多属性,属性的值和相应的DOM属性是相同的;对于其他人,包括所有不是字符串的属性,他们不是。事件处理程序当然不是:属性是Function对象,而string属性可能是(a)HTML中onclick="..."属性的原始字符串,(b)没有(如果onclick是从脚本分配的)成为一个Function对象)或(c)不可用(在旧的IE中)。

要访问事件处理函数Function属性,请在jQuery 1.6中使用prop()

$(obj).data('onclick', $(obj).prop('onclick'));
...
$(obj).prop('onclick', $(obj).data('onclick'));

或者只使用普通的JavaScript,它实际上更简单,更易读; jQuery在这里没有赢任何东西。

obj._onclick= obj.onclick;
...
obj.onclick= obj._onclick;

无论哪种方式,这都不能可靠地“禁用”元素,因为它们可以(并且很可能会,如果你使用jQuery)在其上注册了其他事件监听器,使用addEventListener / attachEvent而不是old-school事件处理程序接口。

答案 1 :(得分:1)

看起来通过.data()保存功能就可以了:

var f1 = function() { console.log('invoked'); };
$('a').data('func', f1)
var f2 = $('a').data('func');  // 'invoked' is not printed
f1 === f2 // true

那你如何通过.data存储这个功能呢?如果你正在做类似

的事情
a = $('a');
a.data('onclick', a.click());  // click handler is invoked here

然后你实际上过早地调用了点击处理程序,并将返回值与.data()一起存储。

- 编辑 -

似乎.attr(function)调用传递的函数。这是jQuery的一个特性。我建议使用jQuery的.click()方法将该函数作为单击处理程序附加。

a = $('a');
a.each(function() {
    this.data('onclick', handler_fn);
    this.bind('click', handler_fn);
});

// later
a.each(function() {
    this.unbind('click');
});

// even later
a.each(function() {
    this.bind('click', this.data('onclick'));
});

答案 2 :(得分:0)

如何在jQuery中绑定事件而不是设置onclick属性?

$(obj).click($(obj).data('onclick'));

我们能看到用于设置数据属性的代码吗?