我有这个jQuery方法,如果我在找到了元素.singlePaneOfGlassBlock
的页面上,可以正常工作。
function replaceRightClickIcefacesMethod() {
//I only want this to run on IE for now, but the content
//is prepared to run on other browsers too
if (jQuery.browser.msie) {
var elem = jQuery(".singlePaneOfGlassBlock"), oldName = elem
.attr("oncontextmenu"), fn = String;
//IE returns function instead of string so let's try to take the string
//in the right way
if (typeof oldName == "function") {
oldName = elem[0].getAttributeNode("oncontextmenu").value,
fn = Function;
}
//do the replace
oldName = oldName.replace('Ice.Menu.contextMenuPopup',
'contextMenuPopupUpdated');
//change oncontextmenu with the new value
jQuery.each(elem, function() {
this.setAttribute("oncontextmenu", fn(oldName));
})
}
}
但它错误地出现了这个错误:
`'undefined' is null or not an object`
在尝试进行替换的行上,如果我在其他缺少这些元素类型的页面上...
我在添加之前添加了一个检查以查看它是否为null或者是否包含该字符串,但它仍然失败:
if (jQuery(oldName).length || oldName.indexOf("Ice.Menu.contextMenuPopup") != -1) {
oldName = oldName.replace('Ice.Menu.contextMenuPopup',
'contextMenuPopupUpdated');
jQuery.each(elem, function() {
this.setAttribute("oncontextmenu", fn(oldName));
})
}
你能给我一个解决方案吗?
感谢。
UPDATE :当我问一个解决方案时,我只是问如何纠正这种方法,以便在找不到那种类型的元素时不运行?
答案 0 :(得分:2)
你能给我一个解决方案吗?
我不确定 - 对于初学者,请格式化您的代码,以便更清楚它应该做什么。 看起来像,就像在if
条件之后你可能有一对丢失的大括号。
至少,不使用逗号分隔的表达式来实现两个赋值 - 将该块放在大括号中并正确地拆分两个赋值。然后代码逻辑应该变得更清晰。
无论如何,由于只有在页面上不存在该类时才会出现问题,那应该是您的第一个测试:
function replaceRightClickIcefacesMethod() {
if (jQuery.browser.msie) {
var elem = jQuery(".singlePaneOfGlassBlock");
if (elem.length > 0) { // new test here!
var oldName = elem.attr("oncontextmenu");
var fn = String;
if (typeof oldName == "function") {
oldName = elem[0].getAttributeNode("oncontextmenu").value;
fn = Function;
}
//do the replace
oldName = oldName.replace('Ice.Menu.contextMenuPopup',
'contextMenuPopupUpdated');
//change oncontextmenu with the new value
jQuery.each(elem, function() {
this.setAttribute("oncontextmenu", fn(oldName));
});
}
}
}
答案 1 :(得分:1)
更新:在问题中重新更新您的代码:
function replaceRightClickIcefacesMethod() {
if (jQuery.browser.msie) {
var elem = jQuery(".singlePaneOfGlassBlock"), oldName = elem
.attr("oncontextmenu"), fn = String;
if (typeof oldName == "function") {
oldName = elem[0].getAttributeNode("oncontextmenu").value,
fn = Function;
}
// ====> This is where the bug is, you're assuming you have
// a string at this point, but you don't necessarily,
// because if there is no match at all, `attr` will
// return `undefined` or `null` (I forget which).
//do the replace
oldName = oldName.replace('Ice.Menu.contextMenuPopup',
'contextMenuPopupUpdated');
//change oncontextmenu with the new value
jQuery.each(elem, function() {
this.setAttribute("oncontextmenu", fn(oldName));
})
}
}
修复:
function replaceRightClickIcefacesMethod() {
if (jQuery.browser.msie) {
var elem = jQuery(".singlePaneOfGlassBlock"), oldName = elem
.attr("oncontextmenu"), fn = String;
if (typeof oldName == "function") {
oldName = elem[0].getAttributeNode("oncontextmenu").value,
fn = Function;
}
// ====> Add this `if`:
if (oldName) {
//do the replace
oldName = oldName.replace('Ice.Menu.contextMenuPopup',
'contextMenuPopupUpdated');
//change oncontextmenu with the new value
jQuery.each(elem, function() {
this.setAttribute("oncontextmenu", fn(oldName));
});
}
}
}
原始回答:
在我看来,你错过了一些大括号(至少):
function replaceRightClickIcefacesMethod() {
if (jQuery.browser.msie) {
var elem = jQuery(".singlePaneOfGlassBlock"), oldName = elem
.attr("oncontextmenu"), fn = String;
if (typeof oldName == "function") { // <=== Added { here
oldName = elem[0].getAttributeNode("oncontextmenu").value,
fn = Function;
oldName = oldName.replace('Ice.Menu.contextMenuPopup',
'contextMenuPopupUpdated');
jQuery.each(elem, function() {
this.setAttribute("oncontextmenu", fn(oldName));
})
} // <=== Added } here
}
}
以上是修正了缩进的内容:
function replaceRightClickIcefacesMethod() {
if (jQuery.browser.msie) {
var elem = jQuery(".singlePaneOfGlassBlock"), oldName = elem
.attr("oncontextmenu"), fn = String;
if (typeof oldName == "function") { // <=== Added { here
oldName = elem[0].getAttributeNode("oncontextmenu").value,
fn = Function;
oldName = oldName.replace('Ice.Menu.contextMenuPopup',
'contextMenuPopupUpdated');
jQuery.each(elem, function() {
this.setAttribute("oncontextmenu", fn(oldName));
})
} // <=== Added } here
}
}
这是您的原始,并更正了缩进:
function replaceRightClickIcefacesMethod() {
if (jQuery.browser.msie) {
var elem = jQuery(".singlePaneOfGlassBlock"), oldName = elem
.attr("oncontextmenu"), fn = String;
if (typeof oldName == "function")
oldName = elem[0].getAttributeNode("oncontextmenu").value,
fn = Function;
// Note how these statements are NOT protected by the `if`
// above, and so if `oldName` is `undefined` (as opposed to
// being a String or Function.
oldName = oldName.replace('Ice.Menu.contextMenuPopup',
'contextMenuPopupUpdated');
jQuery.each(elem, function() {
this.setAttribute("oncontextmenu", fn(oldName));
})
}
}
或者可能是您错过了else
条款,可能还有进一步的防御if
:
function replaceRightClickIcefacesMethod() {
if (jQuery.browser.msie) {
var elem = jQuery(".singlePaneOfGlassBlock"), oldName = elem
.attr("oncontextmenu"), fn = String;
if (typeof oldName == "function") {
oldName = elem[0].getAttributeNode("oncontextmenu").value,
fn = Function;
}
else {
oldName = oldName.replace('Ice.Menu.contextMenuPopup',
'contextMenuPopupUpdated');
}
if (oldName) {
jQuery.each(elem, function() {
this.setAttribute("oncontextmenu", fn(oldName));
});
}
}
}
但是很难说,我不能完全遵循逻辑。它的函数路径部分似乎没有任何改变,但字符串路径部分确实......
答案 2 :(得分:0)
而不是jQuery(oldName).length
,为什么不执行oldName != null
?