js循環(huán)動(dòng)態(tài)綁定帶參數(shù)函數(shù)遇到的問題及解決方案[轉(zhuǎn)]
更新時(shí)間:2010年11月11日 15:00:01 作者:
關(guān)于Javascript利用循環(huán)綁定事件的例子,需要的朋友可以參考下。
眾所周知,不帶參數(shù)的綁定非常簡單,只要使用(語法:“document.getElementById("對(duì)象ID名").attachEvent("事件名,如onchange",函數(shù)名);”)(示例:“document.getElementById("select_0").attachEvent("onchange",modifyFunction);”)即可。(注:以下只寫示例)
帶參數(shù)的綁定就要復(fù)雜一些:document.getElementById("select _0").attachEvent("onchange",function(){modifyFunction (obj,i););即在function()中寫需要執(zhí)行的函數(shù)即可。當(dāng)然還有另一種寫法:document.getElementById("select _0"). onchange=function(){modifyFunction (obj,i););。
綁定成功,OK。不過,慢,此時(shí)又遇到了第二個(gè)問題,傳遞過去的參數(shù)值都是同一個(gè),并不是想象中的將i的值傳遞過去后,每個(gè)綁定的函數(shù)的參數(shù)值都不一樣。
于是乎,上網(wǎng)百度。經(jīng)過艱難的搜索測試,期間還找到一個(gè)如下所示的例子:
<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找到有動(dòng)作的組件,然后獲取它的源,再取出name值。這樣就可以通過傳入的obj,獲得是第幾個(gè)obj,然后進(jìn)行相應(yīng)的操作。
只是還有個(gè)問題,經(jīng)過這種操作之后,obj的值又出現(xiàn)了問題,不管操作哪個(gè)select,獲得的值都是最后一個(gè)。
繼續(xù)百度。
終于,在一篇文章中獲得了原因。文章轉(zhuǎn)帖如下:
我們先看一個(gè)關(guān)于Javascript利用循環(huán)綁定事件的例子:
例如:一個(gè)不確定長度的列表,在鼠標(biāo)經(jīng)過某一條的時(shí)候改變背景。
[Ctrl+A 全選 注:引入外部Js需再刷新一下頁面才能執(zhí)行]
這個(gè)例子循環(huán)為一組對(duì)象綁定事件處理函數(shù)。
但是,如果我們在這個(gè)基礎(chǔ)上增加一些需求。比如在點(diǎn)擊某一條記錄的時(shí)候彈出這是第幾條記錄?
肯能你會(huì)理所當(dāng)然的這么寫:
[Ctrl+A 全選 注:引入外部Js需再刷新一下頁面才能執(zhí)行]
測試一下你會(huì)發(fā)現(xiàn)alert出來的都是:這是第6記錄
其實(shí)這里for循環(huán)已將整個(gè)列表循環(huán)了一遍,并執(zhí)行了i++,所以這里i變成了6,
有什么好的辦法解決這個(gè)問題嗎?
那就是閉包了,個(gè)人認(rèn)為閉包是js中最難捉摸的地方之一,
看看什么是閉包:
閉包時(shí)是指內(nèi)層的函數(shù)可以引用存在與包圍他的函數(shù)內(nèi)的變量,即使外層的函數(shù)的執(zhí)行已經(jīng)終止。
這個(gè)例子中我們可以這樣做:
[Ctrl+A 全選 注:引入外部Js需再刷新一下頁面才能執(zhí)行]
PS:閉包很難,很復(fù)雜!
經(jīng)過以上文章可以得知,引起這個(gè)問題的原因其實(shí)是因?yàn)閖s的閉包難題。按照面向?qū)ο蟮腏AVA語言的理解可以解釋為:js循環(huán)動(dòng)態(tài)綁定帶參數(shù)函數(shù)中的參數(shù),其實(shí)相當(dāng)于java中的引用傳遞,而非值傳遞。傳遞進(jìn)來的引用只相當(dāng)于一個(gè)指針,指向的是一個(gè)內(nèi)存地址,這個(gè)內(nèi)存地址存放的才是具體的值,而外面的循環(huán)會(huì)不斷的修改這個(gè)存放地址中的值,所以最后循環(huán)結(jié)束之后,參數(shù)的值只能找到最后一個(gè)。
知道了原因就很好解決了。New一個(gè)新的“函數(shù)類”(姑且這么稱呼吧)。測試OK。一下是修改后的代碼:
//在新增按鈕上綁定函數(shù)
document.getElementById("add").attachEvent("onclick",addFunction);
var jc_count = 0;//定義需要改變第幾行的值
function txzmcFunction(x,y){//下拉框中綁定的函數(shù)
var sql="select txzjc from dm_txzmc where dm='"+x.value+"'";//取得下拉框中的代碼,通過ajax獲得相應(yīng)的中文名稱
jc_count = y;//定義當(dāng)前行是第幾行
ajaxSelect(sql,"txzjcFunction");//封裝的ajax函數(shù)
}
function txzjcFunction(x){//接收封裝的ajax函數(shù)返回值,并賦值
document.getElementById("_subarea_hxax_clzjxxb_hxax_txzxxb_update_txzjc_"+jc_count).value=x;
}
function bb(dx,sz){//解決動(dòng)態(tài)綁定閉包問題要用到函數(shù)
this.clickFunc=function(){
txzmcFunction(dx,sz);//調(diào)用相應(yīng)的函數(shù)
}
}
function addFunction(){ //動(dòng)態(tài)循環(huán)綁定
var count=document.getElementById("_subarea_hxax_clzjxxb_hxax_txzxxb_update_maxcount").value;//獲取最大的行數(shù)
for (var i=0;i<count ;i++ )//循環(huán)綁定
{
var obj=document.getElementById("_subarea_hxax_clzjxxb_hxax_txzxxb_update_txzmc_" +i);
var tp = new bb(obj,i);//解決閉包問題,new一個(gè)新的函數(shù)類
obj.onchange = tp.clickFunc;
}
}
//顯示頁面時(shí)執(zhí)行一次
addFunction();
帶參數(shù)的綁定就要復(fù)雜一些:document.getElementById("select _0").attachEvent("onchange",function(){modifyFunction (obj,i););即在function()中寫需要執(zhí)行的函數(shù)即可。當(dāng)然還有另一種寫法:document.getElementById("select _0"). onchange=function(){modifyFunction (obj,i););。
綁定成功,OK。不過,慢,此時(shí)又遇到了第二個(gè)問題,傳遞過去的參數(shù)值都是同一個(gè),并不是想象中的將i的值傳遞過去后,每個(gè)綁定的函數(shù)的參數(shù)值都不一樣。
于是乎,上網(wǎng)百度。經(jīng)過艱難的搜索測試,期間還找到一個(gè)如下所示的例子:
復(fù)制代碼 代碼如下:
<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找到有動(dòng)作的組件,然后獲取它的源,再取出name值。這樣就可以通過傳入的obj,獲得是第幾個(gè)obj,然后進(jìn)行相應(yīng)的操作。
只是還有個(gè)問題,經(jīng)過這種操作之后,obj的值又出現(xiàn)了問題,不管操作哪個(gè)select,獲得的值都是最后一個(gè)。
繼續(xù)百度。
終于,在一篇文章中獲得了原因。文章轉(zhuǎn)帖如下:
我們先看一個(gè)關(guān)于Javascript利用循環(huán)綁定事件的例子:
例如:一個(gè)不確定長度的列表,在鼠標(biāo)經(jīng)過某一條的時(shí)候改變背景。
[Ctrl+A 全選 注:引入外部Js需再刷新一下頁面才能執(zhí)行]
這個(gè)例子循環(huán)為一組對(duì)象綁定事件處理函數(shù)。
但是,如果我們在這個(gè)基礎(chǔ)上增加一些需求。比如在點(diǎn)擊某一條記錄的時(shí)候彈出這是第幾條記錄?
肯能你會(huì)理所當(dāng)然的這么寫:
[Ctrl+A 全選 注:引入外部Js需再刷新一下頁面才能執(zhí)行]
測試一下你會(huì)發(fā)現(xiàn)alert出來的都是:這是第6記錄
其實(shí)這里for循環(huán)已將整個(gè)列表循環(huán)了一遍,并執(zhí)行了i++,所以這里i變成了6,
有什么好的辦法解決這個(gè)問題嗎?
那就是閉包了,個(gè)人認(rèn)為閉包是js中最難捉摸的地方之一,
看看什么是閉包:
閉包時(shí)是指內(nèi)層的函數(shù)可以引用存在與包圍他的函數(shù)內(nèi)的變量,即使外層的函數(shù)的執(zhí)行已經(jīng)終止。
這個(gè)例子中我們可以這樣做:
[Ctrl+A 全選 注:引入外部Js需再刷新一下頁面才能執(zhí)行]
PS:閉包很難,很復(fù)雜!
經(jīng)過以上文章可以得知,引起這個(gè)問題的原因其實(shí)是因?yàn)閖s的閉包難題。按照面向?qū)ο蟮腏AVA語言的理解可以解釋為:js循環(huán)動(dòng)態(tài)綁定帶參數(shù)函數(shù)中的參數(shù),其實(shí)相當(dāng)于java中的引用傳遞,而非值傳遞。傳遞進(jìn)來的引用只相當(dāng)于一個(gè)指針,指向的是一個(gè)內(nèi)存地址,這個(gè)內(nèi)存地址存放的才是具體的值,而外面的循環(huán)會(huì)不斷的修改這個(gè)存放地址中的值,所以最后循環(huán)結(jié)束之后,參數(shù)的值只能找到最后一個(gè)。
知道了原因就很好解決了。New一個(gè)新的“函數(shù)類”(姑且這么稱呼吧)。測試OK。一下是修改后的代碼:
復(fù)制代碼 代碼如下:
//在新增按鈕上綁定函數(shù)
document.getElementById("add").attachEvent("onclick",addFunction);
var jc_count = 0;//定義需要改變第幾行的值
function txzmcFunction(x,y){//下拉框中綁定的函數(shù)
var sql="select txzjc from dm_txzmc where dm='"+x.value+"'";//取得下拉框中的代碼,通過ajax獲得相應(yīng)的中文名稱
jc_count = y;//定義當(dāng)前行是第幾行
ajaxSelect(sql,"txzjcFunction");//封裝的ajax函數(shù)
}
function txzjcFunction(x){//接收封裝的ajax函數(shù)返回值,并賦值
document.getElementById("_subarea_hxax_clzjxxb_hxax_txzxxb_update_txzjc_"+jc_count).value=x;
}
function bb(dx,sz){//解決動(dòng)態(tài)綁定閉包問題要用到函數(shù)
this.clickFunc=function(){
txzmcFunction(dx,sz);//調(diào)用相應(yīng)的函數(shù)
}
}
function addFunction(){ //動(dòng)態(tài)循環(huán)綁定
var count=document.getElementById("_subarea_hxax_clzjxxb_hxax_txzxxb_update_maxcount").value;//獲取最大的行數(shù)
for (var i=0;i<count ;i++ )//循環(huán)綁定
{
var obj=document.getElementById("_subarea_hxax_clzjxxb_hxax_txzxxb_update_txzmc_" +i);
var tp = new bb(obj,i);//解決閉包問題,new一個(gè)新的函數(shù)類
obj.onchange = tp.clickFunc;
}
}
//顯示頁面時(shí)執(zhí)行一次
addFunction();
您可能感興趣的文章:
- vue.js刪除動(dòng)態(tài)綁定的radio的指定項(xiàng)
- vue.js選中動(dòng)態(tài)綁定的radio的指定項(xiàng)
- AngularJS 單選框及多選框的雙向動(dòng)態(tài)綁定
- 詳解Vue.js動(dòng)態(tài)綁定class
- AngularJS動(dòng)態(tài)綁定HTML的方法分析
- AngularJS單選框及多選框?qū)崿F(xiàn)雙向動(dòng)態(tài)綁定
- Chrome擴(kuò)展頁面動(dòng)態(tài)綁定JS事件提示錯(cuò)誤
- Javascript動(dòng)態(tài)綁定事件的簡單實(shí)現(xiàn)代碼
- javascript下動(dòng)態(tài)this與動(dòng)態(tài)綁定實(shí)例代碼
- JavaScript動(dòng)態(tài)綁定詳解
相關(guān)文章
解析使用js判斷只能輸入數(shù)字、字母等驗(yàn)證的方法(總結(jié))
本篇文章對(duì)使用js判斷只能輸入數(shù)字、字母等驗(yàn)證的方法進(jìn)行了總結(jié)介紹,需要的朋友參考下2013-05-05js定時(shí)調(diào)用方法成功后并停止調(diào)用示例
這篇文章主要介紹了js定時(shí)調(diào)用方法成功后并停止調(diào)用的實(shí)現(xiàn),需要的朋友可以參考下2014-04-04uniapp開發(fā)H5使用formData上傳文件解決方案
我們很多時(shí)候上傳文件就是使用FormData,然而uniapp默認(rèn)不支持FormData類型數(shù)據(jù)的上傳,下面這篇文章主要給大家介紹了關(guān)于uniapp開發(fā)H5使用formData上傳文件的相關(guān)資料,需要的朋友可以參考下2023-12-12解析JavaScript中instanceof對(duì)于不同的構(gòu)造器或許都返回true
這篇文章主要是對(duì)JavaScript中instanceof對(duì)于不同的構(gòu)造器或許都返回true進(jìn)行了詳細(xì)的解析,需要的朋友可以過來參考下,希望對(duì)大家有所幫助2013-12-12Bootstrap導(dǎo)航簡單實(shí)現(xiàn)代碼
這篇文章主要介紹了Bootstrap導(dǎo)航的簡單實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03JavaScript利用crypto模塊實(shí)現(xiàn)加解密
crypto模塊提供了加密功能,包含對(duì) OpenSSL 的哈希、HMAC、加密、解密、簽名、以及驗(yàn)證功能的一整套封裝。本文將利用它實(shí)現(xiàn)加解密算法,需要的可以參考一下2023-02-02