>웹 프론트엔드 >JS 튜토리얼 >매개변수 [transfer]_javascript 기술을 사용하는 js 루프 동적 바인딩 함수에서 발생하는 문제 및 해결 방법

매개변수 [transfer]_javascript 기술을 사용하는 js 루프 동적 바인딩 함수에서 발생하는 문제 및 해결 방법

WBOY
WBOY원래의
2016-05-16 18:16:381139검색

우리 모두 알고 있듯이 매개변수 없이 바인딩하는 것은 매우 간단합니다. (구문: "document.getElementById("Object ID name").attachEvent("Event name, such as onchange", function name);") (예: " 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););.
바인딩 성공, 알겠습니다. 그런데 이때 슬슬 두 번째 문제가 발생했습니다. 전달된 매개변수 값은 모두 동일했습니다. i의 값을 전달한 후 각 바인딩된 함수의 매개변수 값이 달라지는 것은 상상과 달랐습니다.
그러면 온라인으로 Baidu에 접속하세요. 어렵게 검색하고 테스트한 끝에 아래와 같은 예시도 발견했습니다.

코드 복사 코드는 다음과 같습니다.

<script> <br>document.onclick=check; <br>function check() { <br>if(event.srcElement.type== "button ") <br>alert(event .srcElement.name) <br></script>
<입력 유형=버튼 이름=버튼2>
이번 예제는 이벤트를 통해 액션이 있는 컴포넌트를 찾아 소스를 얻은 후 이름값을 추출하는 예제입니다. 이런 방식으로 들어오는 obj를 통해 obj 번호를 얻은 후 해당 작업을 수행할 수 있습니다.
이 작업 후에는 obj 값에 또 다른 문제가 있습니다. 어떤 선택을 수행하더라도 얻은 값은 마지막 값입니다.
계속해서 바이두로 가세요.
드디어 한 글에서 그 이유를 찾았습니다. 기사는 다음과 같이 재게시되었습니다.
먼저 루프 바인딩 이벤트를 사용하는 Javascript의 예를 살펴보겠습니다.
예: 무한 길이의 목록, 마우스가 특정 항목 위로 지나갈 때 배경이 변경됩니다.





[Ctrl A 모두 선택 참고: 외부 J를 도입해야 하는 경우 실행하려면 새로 고쳐야 합니다. ] 이것은 예제는 그룹 객체 바인딩 이벤트 핸들러 함수로 반복됩니다. 그러나 이를 바탕으로 몇 가지 요구사항을 추가한다면. 예를 들어, 특정 레코드를 클릭하면 어떤 레코드가 팝업되나요?
아마도 다음과 같이 쓸 것입니다:




[Ctrl A 모두 선택 참고: 외부 J를 도입해야 하는 경우 실행하려면 새로 고쳐야 합니다 ]
测试一下你会发现alert出来的都是:这是第6记录
其实这里for循环已将整个列表循环了一遍,并执行了i++,所以这里i变成了6,
有什么好的办法解决这个问题吗?
那就是闭包了,个人认为闭包是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{
var obj=document.getElementById("_subarea_hxax_clzjxxb_hxax_txzxxb_update_txzmc_" +i);
var tp = new bb(obj,i);//解决闭包问题,new一个新的函数类
obj.onchange = tp.clickFunc;
}
}
//显示页面时执行一次
addFunction();
성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.