2012-02-06 85 views
1

我知道這是一個「經典」,我已經嘗試閱讀關於此主題的不同解釋性文章,但我仍然設法以某種方式做錯了。我正在討論在JavaScript循環中添加事件處理函數和函數。在循環中附加事件,javascript

這裏是我的代碼有問題(這是一個提示框/自動完成)

function autoCompleteCB(results) { 
document.getElementById('autocom').innerHTML = ''; 
if (results.length == 0) { 
    document.getElementById('autocom').style.display = 'none'; 
} else { 
    document.getElementById('autocom').style.display = 'block'; 
    var divholders = []; 
    for (var i = 0; i < results.length; i++) { 
     divholders[i] = document.createElement('div'); 
     divholders[i].style.width = '350px'; 
     var divrestext = document.createElement('div'); 
     divrestext.className = 'autocom0'; 
     divrestext.innerHTML = results[i][0]; 
     divholders[i].appendChild(divrestext); 
     var divrestype = document.createElement('div'); 
     divrestype.className = 'autocom1' + results[i][1]; 
     divrestype.innerHTML = results[i][1]; 
     divholders[i].appendChild(divrestype); 
     divholders[i].attachEvent('onmouseover', (function(i) { return function() { divholders[i].style.backgroundColor='#266699'; }; })(i)); 
     divholders[i].attachEvent('onmouseout', (function (i) { return function() { divholders[i].style.backgroundColor = '#F5F5F5'; }; })(i)); 
     document.getElementById('autocom').appendChild(divholders[i]); 
    } 
} 
} 

這是(當然)的的attachEvent線不工作。這部分的javascript是如此奇怪/棘手:)一位善良的專家能幫我修復這兩行嗎?


這是一箇中途修正(我覺得(:

function bindEvent(element, type, listener) { 
if (element.addEventListener) { 
    element.addEventListener(type, listener, false); 
} else if (element.attachEvent) { 
    element.attachEvent('on' + type, listener); 
} 
} 
function autoCompleteCB(results) { 
document.getElementById('autocom').innerHTML = ''; 
if (results.length == 0) { 
    document.getElementById('autocom').style.display = 'none'; 
} else { 
    document.getElementById('autocom').style.display = 'block'; 
    var divholders = []; 
    for (var i = 0; i < results.length; i++) { 
     divholders[i] = document.createElement('div'); 
     divholders[i].style.width = '350px'; 
     var divrestext = document.createElement('div'); 
     divrestext.className = 'autocom0'; 
     divrestext.innerHTML = results[i][0]; 
     divholders[i].appendChild(divrestext); 
     var divrestype = document.createElement('div'); 
     divrestype.className = 'autocom1' + results[i][1]; 
     divrestype.innerHTML = results[i][1]; 
     // BIND THE EVENTS 
     divholders[i].appendChild(divrestype); 
     document.getElementById('autocom').appendChild(divholders[i]); 
    } 
} 
} 

現在看起來是這樣,但仍然沒有 「動作」

function autoComplete() { 
var ss = document.getElementById('txbkeyword').value; 
if (ss.length > 0) { CSearch.SearchAutoComplete(ss, 3, autoCompleteCB); } 
else { document.getElementById('autocom').style.display = 'none'; } 

} 
function bindEvent(element, type, listener) { 
if (element.addEventListener) { 
    element.addEventListener(type, listener, false); 
} else if (element.attachEvent) { 
    element.attachEvent('on' + type, listener); 
} 
} 
function autoCompleteCB(results) { 
document.getElementById('autocom').innerHTML = ''; 
if (results.length == 0) { 
    document.getElementById('autocom').style.display = 'none'; 
} else { 
    document.getElementById('autocom').style.display = 'block'; 
    var divholders = []; 
    for (var i = 0; i < results.length; i++) { 
     divholders[i] = document.createElement('div'); 
     divholders[i].style.width = '350px'; 
     var divrestext = document.createElement('div'); 
     divrestext.className = 'autocom0'; 
     divrestext.innerHTML = results[i][0]; 
     divholders[i].appendChild(divrestext); 
     var divrestype = document.createElement('div'); 
     divrestype.className = 'autocom1' + results[i][1]; 
     divrestype.innerHTML = results[i][1]; 
     (function (i) { 
      bindEvent(divholders[i], 'mouseover', function() { 
       divholders[i].style.backgroundColor = '#266699'; 
      }); 
      bindEvent(divholders[i], 'mouseout', function() { 
       divholders[i].style.backgroundColor = '#F5F5F5'; 
      }); 
     })(i); 
     divholders[i].appendChild(divrestype); 
     document.getElementById('autocom').appendChild(divholders[i]); 
    } 
} 
} 
+1

*這是做的attachEvent線(當然)不工作*他們不工作有什麼意義? – 2012-02-06 15:38:55

+0

他們不會改變顏色onmouseover – Jesper 2012-02-06 15:42:04

+0

爲什麼你通過索引'我'而不是'this'?函數是否可以訪問'divholders'? – 2012-02-06 15:42:19

回答

2

一種可能性是因爲attachEvent是IE-spec IFIC。您必須在其他許多瀏覽器中使用attachEventListener

而且,使用「正確」的方法對當前的瀏覽器,你需要功能檢測到它們(snippet from MDN):

if (el.addEventListener){ 
    el.addEventListener('click', modifyText, false); 
} else if (el.attachEvent){ 
    el.attachEvent('onclick', modifyText); 
} 

你也可以創建一個函數在這個幫助:

function bindEvent(element, type, listener) { 
    if (element.addEventListener) { 
     element.addEventListener(type, listener, false); 
    } else if (element.attachEvent) { 
     element.attachEvent('on' + type, listener); 
    } 
} 

然後,在這些地方2行:

divholders[i].attachEvent('onmouseover', (function(i) { return function() { divholders[i].style.backgroundColor='#266699'; }; })(i)); 
divholders[i].attachEvent('onmouseout', (function (i) { return function() { divholders[i].style.backgroundColor = '#F5F5F5'; }; })(i)); 

...使用函數來斌d的處理程序(跳過事件類型參數的on):

(function (i) { 
    bindEvent(divholders[i], 'mouseover', function() { 
     divholders[i].style.backgroundColor = '#266699'; 
    }); 
    bindEvent(divholders[i], 'mouseout', function() { 
     divholders[i].style.backgroundColor = '#F5F5F5'; 
    }); 
})(i); 

你也可以只封閉<div>

(function (div, i) { 
    bindEvent(div, 'mouseover', function() { 
     div.style.backgroundColor = '#266699'; 
    }); 
    bindEvent(div, 'mouseout', function() { 
     div.style.backgroundColor = '#F5F5F5'; 
    }); 
})(divholders[i], i); 
+0

嗨,我完全看到你的觀點和你的跨瀏覽器附加事件功能,但我不知道如何使用/將最後兩個片段中的一個放在我的循環中?你能幫助多一點:)我會在我的問題 – Jesper 2012-02-06 16:28:15

+0

@Jesper道歉中編輯一半的解決方案。片段應該適合2'divholders [i] .attachEvent(...);'調用(或者你在編輯中有'綁定事件'的權限)。 – 2012-02-06 16:34:02

+0

謝謝,我有點想通了:)但他們仍然不會改變顏色。粘貼最新重寫 – Jesper 2012-02-06 16:35:22

-1

試試這個:

divholders[i].attachEvent('onmouseover', this.style.backgroundColor='#266699'); 
+0

不,這並不容易,因爲我在另一個範圍內。它必須看起來像我的代碼「幾乎」,但有一些修改......在你的例子中,'這個'是未定義的 – Jesper 2012-02-06 15:35:56

+0

你可能忘了'this(){...}'this.style .... '但即使這樣也行不通。 IE不會將'this'設置爲事件處理程序所附的元素(它可以與'divholders [i] .onmouseover = function(){...}'一起使用)。致歉; – 2012-02-06 15:38:15

+0

道歉;匆匆寫了這個回覆;爲什麼不設置var obj = divholders [i];然後做 obj.attachEvent('onmouseover',obj.style.backgroundColor ='#266699'); – user879355 2012-02-06 15:50:52