8 回答

TA貢獻(xiàn)2037條經(jīng)驗(yàn) 獲得超6個(gè)贊
別人問的是可不可以合并,樓上一大坨說(shuō)的啥,好像恨不得把幾十年學(xué)的js全抖出來(lái),萬(wàn)一樓主有不可告人的原因而無(wú)法使用dom123456789級(jí)還有代理呢?
var len = Math.max(oBtn1.length,oSp1.length)
for(i=0;i<len;i++){
if(oBtn1[i]){
oBtn1[i].onclick=function(){
alert('a');
}
}
if(oSp1[i]){
oSp1[i].onclick=function(){
alert('a');
}
}
}

TA貢獻(xiàn)1842條經(jīng)驗(yàn) 獲得超22個(gè)贊
從代碼中初步斷定為樓主循環(huán)目的為多元素綁定事件并且采用的是DOM 0級(jí)事件綁定方式,我這邊先對(duì)1樓說(shuō)的不推薦事件這么注冊(cè)補(bǔ)充一些說(shuō)明,然后在針對(duì)代碼簡(jiǎn)化提一些建議。
首先,0級(jí)的事件綁定一大優(yōu)勢(shì)就在于有著較好的向后兼容性,因?yàn)樽钤鐦?biāo)準(zhǔn)沒出來(lái)的時(shí)候主流瀏覽器廠商做的事件綁定都這么綁,標(biāo)準(zhǔn)出來(lái)后之后總得兼顧以前的代碼吧,因此這種綁定方式也被留了下來(lái)。這種綁定方式的最大缺點(diǎn)在于無(wú)法為同一個(gè)元素同一個(gè)事件綁定多個(gè)處理函數(shù),而且通過w3c事件綁定即x.addEventListener能指定事件的處理階段是在捕獲階段還是在冒泡階段。綜上所述,因?yàn)?級(jí)事件存在無(wú)法對(duì)事件觸發(fā)階段進(jìn)行更精細(xì)的控制并且不在w3c標(biāo)準(zhǔn)內(nèi),因此在使用上要加以斟酌。
針對(duì)代碼部分,我理解為樓主合并兩個(gè)循環(huán)的目的為簡(jiǎn)化代碼量并提升性能,在提升算法性能思路上可以考慮將兩個(gè)循環(huán)合并為一個(gè)循環(huán),當(dāng)oBtn1的集合長(zhǎng)度與oSp1的長(zhǎng)度相等時(shí),此時(shí)單層循環(huán)就能解決合并問題。
// 我不知道樓主這邊查詢到的DOM節(jié)點(diǎn)集合是nodeList還是什么類型
// 如果是nodeList類型集合會(huì)存在與DOM樹實(shí)時(shí)同步的特點(diǎn),建議遍歷時(shí)
// 把長(zhǎng)度值先另存下來(lái)
for(let i=0, len = oBtn1.length; i<len;i++){
oBtn1[i].onclick = function(){
alert('a');
}
oSp1[i].onclick = function(){
alert('b');
}
}
當(dāng)兩集合長(zhǎng)度不一樣的時(shí),一層循環(huán)的一個(gè)思路在于使用較長(zhǎng)的那個(gè)長(zhǎng)度作為遍歷次數(shù),
在內(nèi)部根據(jù)當(dāng)前長(zhǎng)度值判斷為哪個(gè)元素進(jìn)行事件綁定。
let lenOfoBtn = oBtns.length;
let lenOfoSp1 = oSp1.length;
let len = Math.max(lenOfBtn, lenOfoSp1);
// 假設(shè)是Sp1長(zhǎng)度比較短
for(let i=0; i<len;i++){
oBtn1[i].onclick = function(){
alert('a');
}
if( i < lenBtnOfSp1 ){
oSp1[i].onclick = function(){
alert('b');
}
}
}
鑒于個(gè)人算法功底較差,此時(shí)如果想再一步優(yōu)化算法性能,個(gè)人暫時(shí)沒有可行的思路,或許能遞歸?
當(dāng)然,在DOM中當(dāng)然還能使用一樓提出的事件委托進(jìn)行代碼及性能層面上的優(yōu)化。
// 偽代碼
parentOfObtn = Obtn.parentNode;
parentOfoSp1 = oSp1.parentNode
parentOfbtn.addEventListener("click", function( e ){
// 識(shí)別事件觸發(fā)對(duì)象是誰(shuí)的條件語(yǔ)句,可能用類名或其他標(biāo)識(shí)
if( e.target == xxx ){
alert("a")
}
}, false)
parentOfoSp1 .addEventListener("click", function( e ){
// 識(shí)別事件觸發(fā)對(duì)象是誰(shuí)的條件語(yǔ)句,可能用類名或其他標(biāo)識(shí)
if( e.target == xxx ){
alert("b")
}
}, false)
更一步就是把事件委托到sp1與oBtn共有的祖先節(jié)點(diǎn)上,小透明第一次答題,
希望能對(duì)你有幫助。

TA貢獻(xiàn)1883條經(jīng)驗(yàn) 獲得超3個(gè)贊
還有另一種方式「合并」
function bindF(a) {
for (var i = 0; i < a.length; ++i) {
a[i].onclick = function () {
alert('a');
};
}
}
bindF(oBtn1, i);
bindF(oSp1, i);
你知道 loop fusion 嗎
題主的兩個(gè)循環(huán)相互之間沒有依賴關(guān)系
如果循環(huán)次數(shù)一樣,是可以合成一個(gè)的
即便循環(huán)次數(shù)不一樣
也可以強(qiáng)行合并(雖然理論上會(huì)被編譯器再用 loop fission 拆成兩個(gè)循環(huán))
const { max } = Math;
var n = max(oBtn1.length, oSp1.length);
var i = 0;
function set(a, i) {
if (i < a.length) {
a[i].onclick = function () {
alert('a');
};
}
}
for (; i < n; ++i) {
set(oBtn1, i);
set(oSp1, i);
}

TA貢獻(xiàn)1803條經(jīng)驗(yàn) 獲得超6個(gè)贊
var clickFunc = function(){
alert('a');
};
for(i=0;i<oBtn1.length;i++){
oBtn1[i].onclick=clickFunc;
}
for(i=0;i<oSp1.length;i++){
oSp1[i].onclick=clickFunc;
}
添加回答
舉報(bào)