看JS,一直纠结于for循环事件绑定,我一直不理解,想找到一些解释,以下是个人研究一个下午后的一些见解,有不对的还望大神们指正,轻喷。在这里谢过啦。

首先,目的是做一个滑动切换图片的效果,上JS代码:

// 拿对象
// 获取所有的按钮div,返回一个数组
var barArr=document.getElementsByClassName("up_stript_div_bar")
//定义一个图片的数组
var imgSrcArr=new Array("images/视频.jpg","images/秒拍.jpg","images/综艺.jpg")
往后,一开始我是这样写的:“勤快写法”
barArr[0].onmouseover=function overIt() {
document.getElementById("imgBig").src=imgSrcArr[0]; }
barArr[1].onmouseover=function overIt() {
document.getElementById("imgBig").src=imgSrcArr[1];
}
barArr[2].onmouseover=function overIt() {
document.getElementById("imgBig").src=imgSrcArr[2];
}
发现是可以的; 然后,就想试一下for循环绑定,代码如下:
for(var i=0;i<barArr.length;i++){
barArr[i].onmouseover=function overIt() {
document.getElementById("imgBig").src=imgSrcArr[i];
} }
结果显示:undefined:1 Failed to load resource: the server responded with a status of 404 (Not Found)
当时我就好奇了,什么情况??
for循环理论上,是一种迭代偷懒的计数器,你给他设定范围,设定步长,他就做事。难道结果不是跟第一种如下一开始的一样么?
barArr[0].onmouseover=function overIt() {
document.getElementById("imgBig").src=imgSrcArr[0]; }
barArr[1].onmouseover=function overIt() {
document.getElementById("imgBig").src=imgSrcArr[1];
}
barArr[2].onmouseover=function overIt() {
document.getElementById("imgBig").src=imgSrcArr[2];
}
经过我的思考我发现了这点:
最上面这种全部列出来的“勤快写法”;大致可以看成是这样
[0]------[0]
[1]------[1]
[2]------[2]
而上面那个for循环的结果是什么呢?
我原以为也是这样,因为通过打印,发现,他是执行完0,1,2的过程的,难道不是左右都有,然后等待鼠标事件?
但其实应该只有一半!: 他是分两步来完成的:
第一:
[0]----
[1]---
[2]---
for循环结束,一切定格,它能做的就这么多啊 第二: 鼠标事件发生
[0或1或2] ------i
因为后一半要通过鼠标事件才可以显现,它是被好好的保护着的,一旦鼠标事件发生,好家伙,function部分醒过来了,手上拿着i,问i是多少,好的,i是3,于是,你到哪找3给它。于是就报错了。
它根本没有完成开头的“勤快写法的全部”,(for循环就是为了减少代码量的) 所以,问题在于,怎么把“勤快写法”给表现出来。做的事情不能少。 问题知道了,下面看怎么解决: 解决一:用另外一个跟随被点击对象的自定义属性来复制一份[0][1][2]
简单说,就是
被点的对象,都手持一个牌子,被点的时候,就告诉后面一个数组,牌子的标号。看代码:
for(var i=0;i<barArr.length;i++){
// console.log(i)
barArr[i].n=i;
barArr[i].onmouseover=function () {
console.log(i)
document.getElementById("imgBig").src=imgSrcArr[this.n]; }
}
变成了这样:
n
[0]--[0]---
[1]--[1]---
[2]--[2]---
鼠标点击时,i=3,但是要什么紧。又不根据i找,你点哪个,我把对应的n给你,因为复制好一份对应的n的一列。这个完成了操作,就跟映射列表一样,都对应好了。

解决二:
闭包:
这个是我自学的。
大概意思就是,函数包函数,这个在java里面是不允许的,一般是函数包一个函数的调用。
但有一条一样:就是如果一个函数的内在成员如果是被另一个函数引用的话,那他就不会被垃圾回收机制干掉(java和js都有垃圾回收机制)
一开始我是这样写的:想着闭包,干脆别那么麻烦,少些那个注释的两行:看代码:
for(var i=0;i<barArr.length;i++){
barArr[i].onmouseover=(function (i) {
// return function () {
document.getElementById("imgBig").src=imgSrcArr[i]
} //})(i) }
思考:那两条双斜杠的,少了会怎么样?

那是一个自执行函数,简单来说,这样(function(i){巴拉巴拉})(i),就是他可以自己自动执行,可以传参。
问题是,它到底是个什么过程?如下?
[0]--[0]
[1]--[1]
[2]--[2] 鼠标事 i=3
这个更有意思,我觉得,它是执行完,但都随后直接弹栈了。。。。。因为,它执行完了,根本不需要鼠标事件了。。。。

于是,闭包就来了
首先:它内部函数吊着外面的变量,他不会被回收
具体,我觉得是这样,它是真的完成了操作,也没借助额外的属性设置:
[0]--[0]
[1]--[1]
[2]--[2]
for循环结束,
i=3
鼠标事件,就跟一开头的“勤快写法一样” 所以,关键点在于闭包,它没弹栈。 总结:最先前的,直接写i的那种,鼠标事件之前,它完成了左边的赋值,右面没有,鼠标事件一发生,i的值是4
闭包:用的是它内部函数吊着外面的一个变量,它不弹栈。 今天研究了一个下午的成果,如上。 多谢学习给我带来快乐! 加油!


初学笔记之:Java_Script的for循环事件绑定的更多相关文章

  1. vuejs学习笔记(1)--属性,事件绑定,ajax

    属性 v-for 类似于angular中的 ng-repeat ,用于重复生成html片段: <ul id="box"> <li v-for="(v, ...

  2. vuejs学习笔记(2)--属性,事件绑定,ajax

    属性 v-for 类似于angular中的 ng-repeat ,用于重复生成html片段: <ul id="box"> <li v-for="(v, ...

  3. JQuery在循环中绑定事件的问题详解

    JQuery在循环中绑定事件的问题详解 有个页面上需要N个DOM,每个DOM里面的元素ID都要以数字结尾,比如说 ? 1 2 3 <input type="text" nam ...

  4. C++ STL初学笔记

    C++  STL初学笔记 更系统的版本见徐本柱的PPT set 在这儿:http://www.cnblogs.com/pdev/p/4035020.html #include <vector&g ...

  5. lufylegend库 鼠标事件 循环事件 键盘事件

    lufylegend库 鼠标事件 循环事件 键盘事件 <!DOCTYPE html> <html lang="en"> <head> <m ...

  6. 【python学习笔记】5.条件、循环和其他语句

    [python学习笔记]5.条件.循环和其他语句 print: 用来打印表达式,不管是字符串还是其他类型,都输出以字符串输出:可以通过逗号分隔输出多个表达式 import: 导入模块     impo ...

  7. 【Visual C++】游戏编程学习笔记之六:多背景循环动画

    本系列文章由@二货梦想家张程 所写,转载请注明出处. 本文章链接:http://blog.csdn.net/terence1212/article/details/44264153 作者:ZeeCod ...

  8. Python编程从入门到实践笔记——用户输入和while循环

    Python编程从入门到实践笔记——用户输入和while循环 #coding=utf-8 #函数input()让程序暂停运行,等待用户输入一些文本.得到用户的输入以后将其存储在一个变量中,方便后续使用 ...

  9. Spring 初学笔记

    Spring 初学笔记: https://blog.csdn.net/weixin_35909255/article/category/7470388

随机推荐

  1. Linux命令_sed_2

    2.替换(将包含"xxx"的行中的"yyy"替换成"zzz") 现有文件“replace_specified_contained_line” ...

  2. 计算机网络Web应用层与运输层(HTTP/TCP)

    应用层协议原理 Web和HTTP DNS:英特网的目录服务 运输层 面向连接的运输:TCP及拥塞原理 一.应用层协议原理 DNS域名解析: (用例:www.baidu.com)域名解析是网络请求的第一 ...

  3. 使用Docker安装SonarQube

    需先安装docker和docker-compose.见:https://www.cnblogs.com/hackyo/p/9280042.html 在任意目录下新建文件docker-compose.y ...

  4. hibernate自定义校验Valid

    步骤: 1.定义注解: import javax.validation.Constraint; import javax.validation.Payload; import java.lang.an ...

  5. python常用的内置函数哈哈

    python常用的内置函数集合做一个归类用的时候可以查找 abs 返回数字x的绝对值或者x的摸 all (iterable)对于可迭代的对象iterable中所有元素x都有bool(x)为true,就 ...

  6. c语言编译四大步

    -o: 指定生成后的文件名,后面跟指定的名称 四步:-E 预处理 > -S 编译 > -c 汇编 > 链接 -E: 表示预处理,生成文件为.i,会做宏(define)定义的展开.头文 ...

  7. vue组件中data为什么必须是个函数

    <body> <div id="app"> <counter></counter> </div> <templat ...

  8. Collections -- OrderedDict类

    普通dict(字典)在插入的时候并不记住元素的顺序,迭代器会根据散列表(哈希表)中存储的顺序来生成的.而OrderedDict则会记录元素的顺序,并且在迭代器输出时,会按现在记录的顺序进行遍历. 例: ...

  9. Python-Struct

    从一个例子开始: >>> from struct import * >>> pack('hhl',1655, 255, 370) b'w\x06\xff\x00r\ ...

  10. web前端效率提升之禁用缓存-遁地龙卷风

    1.使用场景 我用的是Chrome,Ctrl+F5并不是在任何时候都能清楚缓存,这样很影响效率,下面的方式可以在开发者工具打开的使用禁止浏览器缓存任何资源, 还是出现不及时更新的情况,就要考虑服务器是 ...