DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> js循環動態綁定帶參數函數遇到的問題及解決方案[轉]
js循環動態綁定帶參數函數遇到的問題及解決方案[轉]
編輯:關於JavaScript     
眾所周知,不帶參數的綁定非常簡單,只要使用(語法:“document.getElementById("對象ID名").attachEvent("事件名,如onchange",函數名);”)(示例:“document.getElementById("select_0").attachEvent("onchange",modifyFunction);”)即可。(注:以下只寫示例)
帶參數的綁定就要復雜一些:document.getElementById("select _0").attachEvent("onchange",function(){modifyFunction (obj,i););即在function()中寫需要執行的函數即可。當然還有另一種寫法:document.getElementById("select _0"). onchange=function(){modifyFunction (obj,i););。
綁定成功,OK。不過,慢,此時又遇到了第二個問題,傳遞過去的參數值都是同一個,並不是想象中的將i的值傳遞過去後,每個綁定的函數的參數值都不一樣。
於是乎,上網百度。經過艱難的搜索測試,期間還找到一個如下所示的例子:
復制代碼 代碼如下:
<script>
document.onclick=check;
function check() {
if(event.srcElement.type== "button ")
alert(event.srcElement.name);
}
</script>
<input type=button name=button1>
<input type=button name=button2>

此例子是通過event找到有動作的組件,然後獲取它的源,再取出name值。這樣就可以通過傳入的obj,獲得是第幾個obj,然後進行相應的操作。
只是還有個問題,經過這種操作之後,obj的值又出現了問題,不管操作哪個select,獲得的值都是最後一個。
繼續百度。
終於,在一篇文章中獲得了原因。文章轉帖如下:
我們先看一個關於Javascript利用循環綁定事件的例子:
例如:一個不確定長度的列表,在鼠標經過某一條的時候改變背景。

[Ctrl+A 全選 注:如需引入外部Js需刷新才能執行]
這個例子循環為一組對象綁定事件處理函數。
但是,如果我們在這個基礎上增加一些需求。比如在點擊某一條記錄的時候彈出這是第幾條記錄?
肯能你會理所當然的這麼寫:

[Ctrl+A 全選 注:如需引入外部Js需刷新才能執行]
測試一下你會發現alert出來的都是:這是第6記錄
其實這裡for循環已將整個列表循環了一遍,並執行了i++,所以這裡i變成了6,
有什麼好的辦法解決這個問題嗎?
那就是閉包了,個人認為閉包是js中最難捉摸的地方之一,
看看什麼是閉包:
閉包時是指內層的函數可以引用存在與包圍他的函數內的變量,即使外層的函數的執行已經終止。
這個例子中我們可以這樣做:

[Ctrl+A 全選 注:如需引入外部Js需刷新才能執行]
PS:閉包很難,很復雜!
經過以上文章可以得知,引起這個問題的原因其實是因為js的閉包難題。按照面向對象的JAVA語言的理解可以解釋為:js循環動態綁定帶參數函數中的參數,其實相當於java中的引用傳遞,而非值傳遞。傳遞進來的引用只相當於一個指針,指向的是一個內存地址,這個內存地址存放的才是具體的值,而外面的循環會不斷的修改這個存放地址中的值,所以最後循環結束之後,參數的值只能找到最後一個。
知道了原因就很好解決了。New一個新的“函數類”(姑且這麼稱呼吧)。測試OK。一下是修改後的代碼:
復制代碼 代碼如下:
//在新增按鈕上綁定函數
document.getElementById("add").attachEvent("onclick",addFunction);
var jc_count = 0;//定義需要改變第幾行的值
function txzmcFunction(x,y){//下拉框中綁定的函數
var sql="select txzjc from dm_txzmc where dm='"+x.value+"'";//取得下拉框中的代碼,通過ajax獲得相應的中文名稱
jc_count = y;//定義當前行是第幾行
ajaxSelect(sql,"txzjcFunction");//封裝的ajax函數
}
function txzjcFunction(x){//接收封裝的ajax函數返回值,並賦值
document.getElementById("_subarea_hxax_clzjxxb_hxax_txzxxb_update_txzjc_"+jc_count).value=x;
}
function bb(dx,sz){//解決動態綁定閉包問題要用到函數
this.clickFunc=function(){
txzmcFunction(dx,sz);//調用相應的函數
}
}
function addFunction(){ //動態循環綁定
var count=document.getElementById("_subarea_hxax_clzjxxb_hxax_txzxxb_update_maxcount").value;//獲取最大的行數
for (var i=0;i<count ;i++ )//循環綁定
{
var obj=document.getElementById("_subarea_hxax_clzjxxb_hxax_txzxxb_update_txzmc_" +i);
var tp = new bb(obj,i);//解決閉包問題,new一個新的函數類
obj.onchange = tp.clickFunc;
}
}
//顯示頁面時執行一次
addFunction();
XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved