Problems and solutions of JS cyclic dynamic binding with parameter function []_javascript technique

Source: Internet
Author: User
Tags closure
As we all know, binding without parameters is very simple, just use (syntax: "document.getElementById" ("Object ID Name"). Attachevent ("event name, such as onchange", function name); " (Example: "document.getElementById" ("Select_0"). Attachevent ("onchange", modifyfunction); " To (Note: The following is just an example)
Binding with parameters is complicated: document.getElementById ("select _0"). Attachevent ("onchange", function () {modifyfunction (obj,i);); That is, you write functions that need to be executed in the function (). There is, of course, another way of writing: document.getElementById ("select _0"). Onchange=function () {modifyfunction (obj,i););.
Bind succeeded, OK. However, slow, and then encountered the second problem, passed the parameter values are the same one, not imagine the value of I passed the past, each bound function has a different parameter value.
So, internet Baidu. After a difficult search test, you also find an example that looks like this:
Copy Code code as follows:

<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>

This example is an event that finds an action component, gets its source, and then extracts the name value. This allows you to get the first few obj through the incoming obj, and then do the appropriate action.
There is only one problem, after this operation, the value of obj has a problem, regardless of which select the operation, the value is the last one.
Continue to Baidu.
Finally, in an article to get the reason. The article reprint as follows:
Let's take a look at an example of JavaScript using cyclic binding events:
For example, a list of indeterminate lengths that changes the background when the mouse passes through a bar.
<textarea id="runcode35476"><! DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 transitional//en" "Http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd "> <ptml xmlns=" http://www.w3.org/1999/xhtml "> <pead> <title>untitled page</title> </p ead> <body> <ul id= "list" > <li> 1th record </li> <li> 2nd record </li> <li> 3rd record </ li> <li> 4th record </li> <li> 5th record </li> <li> 6th record </li> </ul> <script type= "Text/javascript" > var list_obj = document.getElementById ("list"). getElementsByTagName ("Li"); Gets the object array for all Li below the list for (var i = 0; I <= list_obj.length i++) {list_obj[i].onmousemove = function () {This.style. BackgroundColor = "#cdcdcd"; } list_obj[i].onmouseout = function () {This.style.backgroundColor = "#FFFFFF"; }} </script> </body> </ptml></textarea>
[Ctrl + A All SELECT Note: If the need to introduce external JS need to refresh to perform]

This example loops through a set of object binding event handler functions.
However, if we add some demand on this basis. For example, when you click on a record, what's the first few records?
Ken, you'll take it for granted:
<textarea id="runcode27190"><! DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 transitional//en" "Http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd "> <ptml xmlns=" http://www.w3.org/1999/xhtml "> <pead> <title>untitled page</title> </p ead> <body> <ul id= "list" > <li> 1th record </li> <li> 2nd record </li> <li> 3rd record </ li> <li> 4th record </li> <li> 5th record </li> <li> 6th record </li> </ul> <script type= "Text/javascript" > var list_obj = document.getElementById ("list"). getElementsByTagName ("Li"); Gets the object array for all Li below the list for (var i = 0; I <= list_obj.length i++) {list_obj[i].onmousemove = function () {This.style. BackgroundColor = "#cdcdcd"; } list_obj[i].onmouseout = function () {This.style.backgroundColor = "#FFFFFF"; List_obj[i].onclick = function () {alert ("This is the first" + i + "record"); }} </script> </body> </ptml></textarea>
[Ctrl + A All SELECT Note: If the need to introduce external JS need to refresh to perform]

Test it out and you'll find out that alert is all: This is the 6th record.
In fact, here the For Loop has cycled through the entire list and executed the i++, so here I turned 6,
Is there any good way to solve the problem?
That's closure, and personally think that closure is one of the most elusive places in JS,
Look at what a closure is:
A closure is an inner function that refers to a variable that exists within a function that surrounds him, even though the execution of the outer function is terminated.
In this example we can do this:
<! DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 transitional//en" "Http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd "> <ptml xmlns=" http://www.w3.org/1999/xhtml "> <pead> <title>untitled page</title> </p ead> <body> <ul id= "list" > <li> 1th record </li> <li> 2nd record </li> <li> 3rd record </ li> <li> 4th record </li> <li> 5th record </li> <li> 6th record </li> </ul> <script type= "Text/javascript" > Function tt (NOB) {this.clickfunc = function () {alert ("This is the first" + (NOB + 1) + "record"); } var list_obj = document.getElementById ("list"). getElementsByTagName ("Li"); Gets the object array for all Li below the list for (var i = 0; I <= list_obj.length i++) {list_obj[i].onmousemove = function () {This.style. BackgroundColor = "#cdcdcd"; } list_obj[i].onmouseout = function () {This.style.backgroundColor = "#FFFFFF"; var col = new TT (i); List_obj[i].onclick = Col.clickfunc; } </script> </bOdy> </ptml>
[Ctrl + A All SELECT Note: If the need to introduce external JS need to refresh to perform]

PS: Closure is difficult, very complicated!
After the above article can be learned that the cause of this problem is actually because of JS closure problem. According to the Object-oriented Java language understanding can be interpreted as: JS cyclic dynamic binding with parameters in the parameter function, in fact, equivalent to the reference in Java, rather than the value of delivery. Passing in the reference is just the equivalent of a pointer to a memory address, this memory address is a specific value, and the outside loop will constantly modify the value of this store address, so after the end of the loop, the value of the parameter can only find the last one.
Knowing the reason is a good solution. New "function Class" (Let's call it that). Test OK. Here's the modified code:
Copy Code code as follows:

Bind function on New button
document.getElementById ("Add"). Attachevent ("onclick", addfunction);
var jc_count = 0;//definition needs to change the value of the first few lines
function Txzmcfunction (x,y) {//dropdown box-bound functions
var sql= "Select Txzjc from DM_TXZMC where dm=" "+x.value+" ";//Get the code in the dropdown box and get the corresponding Chinese name via Ajax
Jc_count = y;//defines the current line as the first line
Ajaxselect (SQL, "txzjcfunction")/encapsulated Ajax functions
}
function Txzjcfunction (x) {//Receive encapsulated Ajax function return value and assign value
document.getElementById ("_subarea_hxax_clzjxxb_hxax_txzxxb_update_txzjc_" +jc_count). Value=x;
}
function bb (dx,sz) {//Solve dynamic binding closure problem to use functions
This.clickfunc=function () {
Txzmcfunction (DX,SZ);//Call the corresponding function
}
}
function AddFunction () {//dynamic cyclic binding
var Count=document.getelementbyid ("_subarea_hxax_clzjxxb_hxax_txzxxb_update_maxcount"). value;//get the maximum number of rows
for (var i=0;i<count; i++)/Loop binding
{
var Obj=document.getelementbyid ("_subarea_hxax_clzjxxb_hxax_txzxxb_update_txzmc_" +i);
var tp = new BB (obj,i);//solve the closure problem, a newer function class
Obj.onchange = Tp.clickfunc;
}
}
Execute once when the page is displayed
AddFunction ();

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.