2009-04-14 196 views
5

我已閱讀了許多關於此的帖子,但沒有任何可靠的答案。這裏是我的代碼:setAttribute,onClick和跨瀏覽器兼容性

// button creation 
onew = document.createElement('input'); 
onew.setAttribute("type", "button"); 
onew.setAttribute("value", "hosts"); 
onew.onclick = function(){fnDisplay_Computers("'" + alines[i] + "'"); }; // ie 
onew.setAttribute("onclick", "fnDisplay_Computers('" + alines[i] + "')"); // mozilla 
odiv.appendChild(onew); 

現在,setAttribute()方法(與Mozilla的評論)在Mozilla罰款,但只有當它來到它上面的行之後。換句話說,它似乎只是默認最後設定的那個。 .onclick方法(使用ie註釋)在任何情況下都不起作用,我是否正確使用它?

無論哪種方式,我無法找到一種方法在IE中完成這項工作,更不用說在兩者中。當使用.onclick方法時,我確實改變了函數調用,並且它僅使用一個簡單的調用alert函數就能正常工作,這就是爲什麼我相信我的語法不正確。長話短說,我不能讓onclick參數在IE/Mozilla之間一致地工作。

- 尼古拉斯

回答

6

我通常使用類似:

onew.onclick = new Function("fnDisplay_Computers('" + alines[i] + "')"); 

這應該在IE火狐ë工作兩者。

+0

這完美的作品,你能解釋一下爲什麼設置它爲「新功能」(即使函數fnDisplay_Computers()」是否已經定義,解決了這個問題? – 2009-04-14 19:24:34

+0

我認爲這是一個涉及到的數據類型的問題,以及與新的onclick方法相關的「新函數」的引用......但我真的不知道確切的答案,對不起! – 2009-04-14 19:28:36

1

使用addEventListener()功能與「click」爲type參數用於基於Mozilla的瀏覽器,並以「onclickattachEvent()函數作爲sEvent參數的IE;我覺得最好用try/catch語句,例如:

try { 
    onew.attachEvent("onclick", //For IE 
        function(){fnDisplay_Computers("'" + alines[i] + "'"); }); 
} 
catch(e) { 
    onew.addEventListener("click", //For Mozilla-based browsers 
        function(){fnDisplay_Computers("'" + alines[i] + "'"); }, 
        false); 
} 
15

onew.setAttribute(「type」,「button」);

不要在HTML文檔上使用setAttribute。 IE得到它在許多情況下嚴重錯誤,和DOM-HTML屬性是較短的,更快速,更容易閱讀:

onew.type= 'button'; 

onew.onclick =函數(){fnDisplay_Computers( 「'」 + ALINES [I ] +「'」); }; // ie

'alines'是什麼?你爲什麼把它轉換成一個字符串並用單引號包圍它?看起來你正在試圖做一些令人討厭的事情,包括評估字符串中的代碼(這就是你在'onew.setAttribute'版本中做的)。評估字符串中的JavaScript代碼幾乎總是錯誤的;避免它像瘟疫一樣。在上面的例子中,IE應該和Firefox一樣:它不應該工作。

如果'alines [i]'是一個字符串,我想你要做的就是通過構建一個代碼字符串來記住該字符串,該字符串將在JavaScript中評估爲原始字符串。但是:

"'" + alines[i] + "'" 

不足。如果'alines [i]'有一個撇號或者一個反斜槓,會發生什麼?

'O'Reilly' 

你有一個語法錯誤和可能的安全漏洞。現在,你可以做一些繁瑣和惱人的,如:

"'" + alines[i].split('\\').join('\\\\').split("'").join("\\'") + "'" 

試圖逃跑的字符串,但它的醜陋,並不會爲其它數據類型的工作。你甚至可以問JavaScript來爲你做它:

uneval(alines[i]) 

但不是所有的對象,甚至可以轉化爲可求的JavaScript源字符串;基本上整個方法註定要失敗。

正常的事情,如果你只是想擁有的onclick回調調用帶有參數的功能是編寫代碼以直接的方式:

onew.onclick= function() { 
    fnDisplay_Computers(alines[i]); 
}; 

通常,這工作,是你想要的。然而,你可能會在這裏碰到一個輕微的皺紋,這可能是你考慮到古怪的方法和絃的混淆。

也就是說,如果在這種情況下'i'是封閉'for'循環的變量,那麼對'alines [i]'的引用將不會做你認爲它所做的事情。點擊發生後,'i'將被回調函數訪問 - 循環結束後。此時,'i'變量將留在循環結尾的任何值,因此'alines [i]'將永遠是'alines'的最後一個元素,無論單擊哪個'onew'。

(對於一些這方面的討論,例如參見How to fix closure problem in ActionScript 3 (AS3),這是混淆的,在JavaScript和Python的倒閉的最大原因之一,確實應​​該有一天固定在一個語言水平。)

你可以避開環路問題通過其自身的功能封裝倒閉,就像這樣:

function callbackWithArgs(f, args) { 
    return function() { f.apply(window, args); } 
} 

// ... 

onew.onclick= callbackWithArgs(fnDisplay_Computers, [alines[i]]); 

而在JavaScript中的更高版本,你就可以簡單地說:

onew.onclick= fnDisplay_Computers.bind(window, alines[i]); 

如果你想今天能夠使用「Function.bind()」在瀏覽器中,你可以從Prototype框架的實施,或只是使用:

if (!('bind' in Function.prototype)) { 
    Function.prototype.bind= function(owner) { 
     var that= this; 
     var args= Array.prototype.slice.call(arguments, 1); 
     return function() { 
      return that.apply(owner, 
       args.length===0? arguments : arguments.length===0? args : 
       args.concat(Array.prototype.slice.call(arguments, 0)) 
      ); 
     }; 
    }; 
} 
0

我覺得#3 protesteth太多。在很多情況下,我正在動態構建一個表,並且需要將參數傳遞給回調函數。這不是一個類型安全問題,因爲我的變量parm是所討論錶行的整數索引。這裏是既具有可變和固定參數的代碼,這似乎是跨瀏覽器兼容:

for (i = 0; i < arrTableData.length; i++) { 
    eleTR = objTable.insertRow(i + 1); 
    cell = eleTR.insertCell(0); 
    cell.width = "21"; 
    var myElement = document.createElement('img'); 
    myElement.setAttribute('src', 'images/button_down.gif'); 
    myElement.setAttribute('alt', 'Move item down'); 
    myElement.onclick = new Function('moveItem(' + i + ',0)'); 
    cell.appendChild(myElement); 
}