在IE7中,jquery的.attr('onclick'无效。

3
我知道有一些几乎相同的问题帖子,但所有提到的“修复”对我都不起作用。
首先,这是我需要的: 我的应用程序中的一些表格必须通过激活编辑模式来启用。如果编辑模式处于活动状态,则页面上的每个按钮(除保存和放弃之外)和链接都不应执行其正常功能,而应该显示一个消息,告诉您必须结束编辑模式。
我的脚本: 开始编辑模式的按钮调用此函数:
    function startEditMode(selector) {
            var disableAction = "return false;";
            jQuery("mySelectors").each(function(){
                    jQuery(this).bind('click', editModeOnClickHandler);
                    var onClickValue = "";
                    var onClick = jQuery(this).attr("onClick");
                    if ( onClick !== undefined ) onClickValue = "" + onClick;
                    jQuery(this).attr("onClick", disableAction + onClickValue);
            });
    }

停止编辑模式有一种方法可以撤销所有更改。使用的处理程序“editModeOnClickHandler”仅显示消息并返回false;对我的问题不重要。
所以...在Firefox和IE8(还有Chrome)中一切正常,但在IE7中不行。根据我在其他帖子中阅读的内容,通过.attr在IE7中简单地未修改onClick。
无处不在的解决方案: 使用事件绑定而不是操作属性。我希望我能用那个!
这是我不能的原因: 我尝试取消绑定所有处理程序并绑定自己的处理程序,如上面的代码所示。但这并不能防止调用内联onclick。 好吧,你可能会想,不要使用内联调用..但我的项目是使用Primefaces编写的JSF,并且大部分代码都是动态生成的。总之,我没有可能防止内联onclick。
现在我卡住了。 我必须处理内联onclick,但只能通过在前面插入“return false;”来防止调用它们,但这似乎在IE7中不可能。
有人知道IE7的解决方法,以便能够操作onclick属性吗?再次强调:我不能使用.bind('click'...或.click(,因为它们无法停止原始内联onclick。
感谢所有答案! Alex
编辑 在您的帮助下,我发现在IE7中使用this.onclick = ..可以更改内联onclick。这个问题的正确处理已经在这个问题中回答:如何动态更改onClick处理程序? 对于我在这里的具体问题,我找不到合适的解决方案,因为我无法在破坏它们的情况下操纵原始内联onclick值。因此,我更改了我的脚本,以便IE7禁用所有按钮和链接,以确保它们不再可点击。为了确保不启用太多,我还会添加一个类名。
禁用所有尚未禁用的(在循环中调用):
if (!jQuery(this).attr('disabled')) {
    jQuery(this).attr('disabled', 'disabled');
    jQuery(this).addClass('editmodedisabled');
}

启用我之前禁用的东西:

if (jQuery(this).hasClass('editmodedisabled')) {
    jQuery(this).attr('disabled', '');
    jQuery(this).removeClass('editmodedisabled');
}

也许这能帮助其他人。

1
你为什么要将attr('onClick')中的C大写?此外,以下代码可能对你有帮助:var clickEvents = $(element).data("events").click; $.each(clickEvents, function(key, handlerObj) { .. } - Robert de W
感谢您的评论:1. 我将C大写,因为不知何故IE8无法删除我的添加的return false;,除非有C :(
  1. 我也尝试过使用data("events"),但内联onclick似乎不是其中的一部分。我会再试一次。
- Allanon
4个回答

5

我遇到了与你相同的JSF和PrimeFaces问题。这里是我解决此问题的方案。

您可以禁用内联函数并根据需要恢复它们:

// get the element with jQuery
var element = $('#someId');

// get the current inline onclick function. This works under all browsers. 
var originalInlineClickHandler = element[0].onclick;

// define new click event which will replace the old one.
var click = function () {
    alert('You clicked me!');
}

// replace the old "onclick" event with the new one or in other words disable the click 
element[0].onclick = click;

// Now when clicking #someId element the new function will be executed and only it (the "click" function).
// Original inline function is gone already and those it will not be executed.

// Restore original inline function - a.k.a. enable the click event
element[0].onclick = originalInlineClickHandler.

这种方法适用于所有浏览器。问题在于,当你改变element.attr('onclick', callback);时(意味着element[0].onclick = eval(element.attr('onclick'))或类似的操作),所有现代浏览器都会更改element[0].onclick,但IE <= IE 7不会。然而,如果你即使没有改变onclick属性,仅改变element[0].onclick属性,它也能在所有浏览器下工作。在这种情况下,onclick属性不对应真正的事件处理程序。为了在所有浏览器下保持onclick属性和属性同步,可以添加以下行:

// define new click event which will replace the old one.
var click = function () {
    alert('You clicked me!');
    return false;
}

// update the onclick attribute of the element. Under most browsers this will update and onclick property of the DOM element.
element.attr('onclick', click.toString());

// replace the old "onclick" event with the new one or in other words disable the click 
element[0].onclick = click;

1
您可以通过以下方式获取内联onclickvar inlineHandler = this.onclick;
function startEditMode(selector) {
        var disableAction = "return false;";
        jQuery("mySelectors").each(function(){
                jQuery(this).bind('click', editModeOnClickHandler);
                var onClickValue = "";
                var onClick = this.onclick;
                if ( onClick !== undefined ) onClickValue = "" + onClick;
                jQuery(this).attr("onClick", disableAction + onClickValue);
        });
}

感谢您的帖子@Mrchief!那部分解决了问题…获取值不是问题,而是设置,在this.onclick = newvalue;使用后我能够在IE7中修改内联onclick。但现在我指向另一个问题。添加和删除return false;都有效,但两个版本获取该值,会在IE7中返回一个类似此function anonymoues() { here is the real onclick }的包装函数。将其作为字符串添加到onclick值中可能会破坏它。 - Allanon
FYI:使用 this.getAttributeNode('onclick') 可以获取没有包装器的 onclick 值,但我找不到正确的方法来更改 this.onclick 而不破坏旧的 js.. 因为我找不到这样做的方法,所以我改变了我的脚本,在 IE7 的情况下,我将禁用所有按钮和链接。太糟糕了,现在我必须接受 IE7 禁用的样式 :( - Allanon
1
很有趣,@Allanon。很好的事情是世界很快就会摆脱IE7了。 - Mrchief

0

这是IE7已知的问题。

您尝试过这个解决方法吗?

或者,我也听说可以简单地使用IE的专有event.returnValue作为解决方法,但无法验证其是否有效。

以下是您代码中需要更改的部分:

var disableAction = "event.returnValue = false; return false;";

感谢您的评论@namuol!据我所知,在链接内联onclick中返回false;可以防止IE7中的默认行为,我的问题是/曾经无法直接修改它。链接中提到的方法只是添加了一个新事件,我同意这种方式,仍然调用默认操作。我还通过搜索几次找到了event.returnValue的事情,但那并没有成为线索,因为正如我所说,我无法修改onclick,我的脚本只是无法在IE7中更新DOM中的内联onclick。 - Allanon

0

我曾经遇到过同样的问题,但是使用纯粹的 href="javascript:some_js_function_without_returning_false();" 解决了它。 我知道这不是onclick的解决方案,但在某些情况下可能会有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接