2011-05-05 45 views
1

我有這個jQuery方法,其中工作正常,如果我在頁面上有元素髮現其中有類.singlePaneOfGlassBlockjQuery方法中的奇怪n

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)); 
      }) 
     } 
    } 

但與此錯誤failes:

`'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:當我問一個解決方案我只是問如何糾正這種方法不運行時,找不到類型的元素?

回答

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)); 
      }); 
     } 
    } 
} 

但它真的很難說,我不能完全遵循的邏輯。它的功能路徑部分似乎沒有改變任何東西,但字符串路徑部分...

+0

謝謝,我已經添加了大括號,但在正確的位置爲我的情況。但是,npe錯誤並不是因爲這個.. – 2011-05-05 13:30:31

+0

@Cristian,@Alnitak:我已經更新了一下。 @克里斯蒂安:如果你退後一步並描述你實際想要做什麼(可能作爲一個單獨的問題),我認爲很可能有更好的方法來處理它。 – 2011-05-05 13:32:08

+0

@Cristian:重新更新你的代碼:你仍然假設你找回了一個'Function'或'String';看到我更新的答案。 – 2011-05-05 13:36:35

0

而不是jQuery(oldName).length,爲什麼不只是做oldName != null

+0

這不起作用... – 2011-05-05 13:26:35

2

Can you give me a solution?

我不確定 - 對於初學者,請格式化您的代碼,以便它更清楚它應該做什麼。它看起來像就像你可能有一對大括號後面的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)); 
      }); 
     } 
    } 
} 
+0

+1謝謝你也有效的檢查... – 2011-05-05 13:43:42

+0

+1 I堅持一個絕對簡約的改變方法,但我確實更喜歡這個代碼的原始。 (你沒有改變*很多,但它讀得更乾淨。) – 2011-05-05 14:02:43

+0

謝謝 - 我討厭用逗號分開的聲明,它們太容易出錯,而且它們也很難讀取。在這裏進行測試可以儘早避免任何額外的處理! [我已經給你+1努力,...] – Alnitak 2011-05-05 14:11:18