javascript 在 jQuery 对象上保存和恢复“onclick”操作

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6657567/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 21:26:26  来源:igfitidea点击:

Save and restore "onclick" action on jQuery objects

javascriptjqueryfunction

提问by Paul Tomblin

I want to disable a whole bunch of objects on the page, and then re-enable them later. Since some of them are tags rather than buttons, I disable them by removing their onclick attr. I've tried to store the old handler in a .data(), but unfortunately when I attempt to restore them with $(obj).attr('onclick',$(obj).data('onclick')), it calls the function rather than restoring it to the attribute. And if I try to store it in a different attribute instead of a data, it doesn't store the function, it stores the return value for the function.

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

Is there any way to accomplish this without re-writing every tag and every onclick handler on my page?

有没有什么方法可以在不重写我页面上的每个标签和每个 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();
   }

By the way, this code seems to work fine in Chrome and Firefox, but only sometimes in IE8 and never in IE6. Unfortunately the client tests first in IE6.

顺便说一下,这段代码在 Chrome 和 Firefox 中似乎可以正常工作,但有时在 IE8 中可以正常工作,而在 IE6 中则不能。不幸的是,客户端首先在 IE6 中进行测试。

回答by bobince

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

is ambiguous, has results that differ in different versions of jQuery and different browsers. It probably doesn't do what you want. You should avoid using attron event handlers.

是模棱两可的,在不同版本的 jQuery 和不同浏览器中具有不同的结果。它可能不会做你想要的。您应该避免使用attron 事件处理程序。

The problem is the disconnect between the onclickattributeand the onclickproperty. jQuery has tried to brush the difference between an attribute and a property under the carpet in the past, using attrto access both, but they're quite different. This was changed in jQuery 1.6, and partially reverted in 1.6.1, to widespread controversy, confusion and incompatibility.

问题在于onclickattributeonclickproperty之间的脱节。jQuery 过去曾尝试在地毯下刷属性和属性之间的差异,使用attr访问两者,但它们完全不同。这在 jQuery 1.6 中有所改变,并在 1.6.1 中部分恢复,导致广泛的争议、混乱和不兼容。

For many properties, the values of an attribute and the corresponding DOM property are the same; for others, including all properties that aren't strings, they aren't. Event handlers certainly aren't: the property is a Function object, whereas the string attribute might be (a) the original string of the onclick="..."attribute in the HTML, (b) nothing (if the onclick was assigned from script to be a Function object) or (c) unavailable (in older IE).

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

To access the event handler Function property, use prop()in jQuery 1.6:

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

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

or just use plain old JavaScript which is actually simpler and more readable; jQuery wins you nothing here.

或者只是使用简单的旧 JavaScript,它实际上更简单、更易读;jQuery 在这里什么也赢不了你。

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

Either way this is not going to reliably ‘disable' elements since they can (and very likely will, if you're using jQuery) have other event listeners registered on them, using addEventListener/attachEvent rather than the old-school event handler interfaces.

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

回答by digitalbath

It looks like saving a function via .data()works just fine:

看起来通过.data()工作保存函数就好了:

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

so how are you storing the function via .data? if you're doing something like

那么你如何通过 存储函数.data?如果你正在做类似的事情

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

then you're actually invoking the click handler(s) prematurely, and storing the return value with .data().

那么您实际上是过早地调用了点击处理程序,并将返回值存储在.data().

--edit--

- 编辑 -

it appears that .attr(function)invokes the passed function. This is a feature of jQuery. I'd suggest using jQuery's .click()method to attach the function as a click handler.

似乎.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'));
});

回答by amosrivera

What about binding the event in jQuery instead of setting the onclick attribute?

在 jQuery 中绑定事件而不是设置 onclick 属性怎么样?

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

Can we see the code that you use to set the data attribute?

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