Js实现背景图片切换(单线程问题)
实现目标:
点击页面中间的小图片,页面的背景就会变成相应的图片样式
思路
- 点击图片,获取到对应的图片的li元素
- 因为图片的名字是从1开始顺序命名的,所以可以通过获取的li元素的索引号来改变背景图片的地址名
- 将地址名改到body标签的backgroundImage属性中
实现代码
- html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
<ul>
<li><img src="images/1.jpg" alt=""></li>
<li><img src="images/2.jpg" alt=""></li>
<li><img src="images/3.jpg" alt=""></li>
<li><img src="images/4.jpg" alt=""></li>
</ul>
</div>
</body>
</html>
- css代码
* {
margin: 0;
padding: 0;
}
ul li {
list-style: none;
float: left;
margin: 2px;
width: 100px;
height: 80px;
}
div {
width: 416px;
height: 68px;
background-color: #fff;
margin: 50px auto;
}
img {
width: 100px;
}
body {
background-image: url(images/1.jpg);
background-repeat: no-repeat;
}
- Js代码
var lis = document.getElementsByTagName('li');
for (var i = 0; i < lis.length; i++) {
lis[i].onclick = function () {
document.body.style.backgroundImage = 'url(images/'+ (i + 1) +'.jpg)';
}
}
此时出现了问题,代码报错,输出的i一直为4不变,这是因为Js是单线程加事件队列,而for是主线程的代码,代码会在for循环结束后再运行,所以i始终为4
- 解决办法
将for循环中的i使用let定义,将for循环变成块级作用域,此时的i只会在for循环中访问,在循环外访问不到
var lis = document.getElementsByTagName('li');
for (let i = 0; i < lis.length; i++) {
lis[i].onclick = function () {
document.body.style.backgroundImage = 'url(images/'+ (i + 1) +'.jpg)';
}
}
总结:
因为Js语言是单线程的,所以在编程时要注意变量的定义,像for、if这样的代码是主线程代码,本代码中是在for循环中定义函数,函数的执行在for循环之后,所以要是想到调用到循环中的i,就要将i定义为let
本文介绍如何使用JavaScript实现背景图片切换,并探讨单线程问题导致的代码错误。通过点击小图片,根据图片索引改变背景图片地址。在实现过程中,由于JavaScript的单线程特性,导致for循环后的函数引用的i值始终为最后一次循环的值。解决方案是使用let关键字在for循环内定义i,使其成为块级作用域,避免函数外部访问到循环后的i值。这是一次关于理解和规避JavaScript单线程问题的实践。

695

被折叠的 条评论
为什么被折叠?



