保存并恢复"onclick"jQuery对象的操作

Save and restore "onclick" action on jQuery objects

本文关键字:quot 对象 操作 jQuery onclick 保存 恢复      更新时间:2023-09-26

我想禁用页面上的一大堆对象,然后稍后重新启用它们。由于其中一些是标签而不是按钮,我通过删除它们的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中测试。

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

是不明确的,在不同版本的jQuery和不同的浏览器中有不同的结果。它可能不符合你的要求。您应该避免在事件处理程序上使用attr

问题在于onclick 属性onclick 属性之间的脱节。过去,jQuery试图掩盖属性和属性之间的区别,使用attr来访问两者,但它们是完全不同的。这在jQuery 1.6中进行了更改,并在1.6.1中部分恢复,引起了广泛的争议、混乱和不兼容。

对于许多属性,一个属性的值和对应的DOM属性是相同的;对于其他属性,包括所有不是字符串的属性,它们不是。事件处理程序当然不是:属性是一个函数对象,而字符串属性可能是(a)在HTML中onclick="..."属性的原始字符串,(b)什么都没有(如果onclick被从脚本分配为一个函数对象)或(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而不是老式的事件处理程序接口。

看起来通过.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'));
});

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

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

我们可以看到用来设置data属性的代码吗?