当我们获取到一个 DOM 元素之后,就可以对 DOM 元素做一些操作,这里介绍我们可以对一个 DOM 元素做哪些操作。
首先,这里先了解一下什么是元素的事件,元素的事件说白了就是某个元素发生了一件事,比如点击了这个 DOM 元素,甚至包括敲击键盘,这些都是事件。由于事件的种类非常多,所以会在后面单独再详细学习,这里只了解一个事件,就是点击事件,也就是这个元素被点击 (click) 的事件。我们学习事件,说白了就是让事件发生之后干一些事,比如被点击之后跳转一个网页,被点击之后输出一段文字,对吧,那这种事件发生之后执行的程序,我们称为事件处理程序。比如这个 DOM 元素,被点击之后,应该输出一段文字,那么就应该给这个 DOM 元素添加一个点击事件,让这个点击事件发生的时候执行一个函数,这个函数的功能就是输出一段文字,这其实就是 DOM 事件的原理。
简而言之,DOM 事件的原理就是,给这个 DOM 添加一个事件,比如鼠标点击事件,当这个事件发生的时候,也就是被点击的时候,执行一段函数。此时我们应该把这个 DOM 对象的点击事件和这个函数绑定起来,说专业一点就是和事件处理程序绑定起来。这个过程叫做事件对象。
所以如果我们用专业一点的术语,我们只要给 DOM 对象注册一个点击事件,就是将一个函数绑定到 DOM 对象的点击事件上去,绑定之后,当 DOM 对象触发了这个点击事件,也就是被点击的时候,就会自动执行这个函数。
html
<!DOCTYPE html>
<html lang="cmn-hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
</style>
</head>
<body>
<button id="btn">点我</button>
<script>
var btn = document.getElementById('btn');//获取到DOM元素
btn.onclick = function () {//给DOM对象绑定事件
console.log("你点了我");
}
</script>
</body>
</html>由上面的例子可知,要给 DOM 元素绑定一个点击事件,只需要给这个 DOM 元素的 onclick 属性赋值为一个函数即可,此时当点击这个按钮的时候,就会执行该函数,这个函数就是事件处理程序。实际上,DOM 元素上有非常多用于注册事件的属性,这些属性都以 on 开头,如下所示,目前只介绍点击事件

接下来就是正题了,一个元素可以添加属性对吧,比如 img 元素就有 src 属性,alt 属性对吧,我们拿到一个 DOM 元素之后,可以读取和修改这个 DOM 元素的属性。DOM 元素的属性大致可以分为两类,一类是可识别属性,一类是自定义属性,这里简要介绍一下。
- 可识别属性:即正常的 HTML 属性,也就是有实际意义的属性,例如 input 元素的 value,例如 img 元素的 src。
- 自定义属性:没有实际意义的属性,例如 value 属性在 input 元素上就有意义,但是在 div 元素上就毫无意义,又例如我就给 div 元素加一个名字叫 a 的属性,这个是我自己取的属性名,没有实际意义。自定义属性主要用来在 DOM 元素上保存一些信息。
对于可识别属性,要获取一个属性的属性值,可以直接使用 DOM元素.属性名 即可,例如下面的例子,再点击按钮的时候,输出文本框的内容,也就是 input 元素的 value 属性值
html
<!DOCTYPE html>
<html lang="cmn-hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
</style>
</head>
<body>
<input id="input" type="text">
<button id="btn" a="b">点我</button>
<script>
var btn = document.getElementById('btn'); // 获取id为btn的按钮元素
var input = document.getElementById('input'); // 获取id为input的输入框元素
// 给按钮绑定点击事件
btn.onclick = function () {
// 在控制台输出输入框的值
console.log(input.value);
}
</script>
</body>
</html>此时当点击 btn 的时候,就可以获取到 input 的 value 属性,也就相当于获取到文本框的值。从这里我们可以看到,对于可识别的属性,它直接就是 DOM 元素的属性,这个属性即可读又可写,也就是说我们完全可以给这个属性赋值,从而修改 DOM 元素的属性值。但是对于自定义属性,是不会绑定在 DOM 元素属性上的,我们也没有办法通过 DOM元素.属性名 来获取,如下所示:
html
<button id="btn" a="b">点我</button>
<script>
var btn = document.getElementById('btn'); // 获取id为btn的按钮元素
// 给按钮绑定点击事件
btn.onclick = function () {
console.log(btn.a);//无法获取到属性a,所以输出永远是undefined
}
</script>如果属性是布尔属性,那么得到的属性值为布尔值
有的属性名本身和关键字冲突,例如label元素的for属性,由于for是一个关键字,所以无法直接通过label.for获取,于是浏览器给你简答修改了一下,将属性名修改为了htmlFor。同样,class也是一个关键字,如果要获取class属性,需要使用className。
这里我们来一个实际的例子,当点击的时候,我要实现点击按钮随机切换图片的效果,随机图片使用 Lorem Picsum 生成
html
<!DOCTYPE html>
<html lang="cmn-hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
</style>
</head>
<body>
<img id="img" src="https://picsum.photos/200/200" alt="">
<button id="btn" a="b">点我</button>
<script>
var btn = document.getElementById('btn'); // 获取id为btn的按钮元素
var img = document.getElementById('img'); // 获取id为img的输入框元素
// 给按钮绑定点击事件
btn.onclick = function () {
img.src = "https://picsum.photos/200/200?random=" + Math.floor(Math.random() * 100);
}
</script>
</body>
</html>
JS 可以修改属性,从而切换图片,有了这个知识,读者应该去尝试一下自行实现一个轮播图效果。
我们考虑一个问题,为什么可识别属性可以通过这种方式来获取,但是自定义属性不行呢?原因很简单,因为可识别属性本身就在 DOM 元素上,例如
input元素的 DOM 元素,这个 DOM 元素上本身就有 value 这个属性,所以我们可以通过这种方式直接获取属性值,哪怕我们的 input 元素没有写 value 属性,我们也可以获取到一个空字符串,而不是 undefined。但自定义属性这个东西,DOM 元素上就根本没有,哪怕我们在 HTML 元素上加上了这个属性,DOM 元素也不会将这些自定义属性加在
那我前面提到过,有时候我们需要在 HTML 元素上设置一些自定义属性,用于在这个 HTML 元素上保存一些数据,那我现在就要得到这些自定义属性怎么办呢?很简单,DOM 元素上有两个方法,分别是 setAttribute() 和 getAttribute(),分别可以设置和得到属性,第一个参数为属性名,第二个参数为属性值。这种方式不管是自定义属性还是可识别属性都可以正常使用。
html
<button id="btn" a="b">点我</button>
<script>
var btn = document.getElementById('btn');
console.log(btn.getAttribute("a"));//可以输出b
btn.setAttribute("a","c");
console.log(btn.getAttribute("a"));//可以输出c
</script>注意,这种方式虽然可以用于获取和设置属性,但对于一些元素,并不具备交互效果,例如使用这种方式给文本框设置 value 属性后,虽然文本框的 value 属性会发生改变,但是不会在浏览器中显示出来,所以这种方式一般只用来设置自定义属性,对于可识别属性,推荐使用上面的那种直接获取的方式。如果我们要删除自定义属性,使用元素节点上的 removeAttribute(属性名) 方法即可。
关于自定义属性
HTML 5 建议自定义属性使用 data- 作为前缀,例如 data-a,data-abc 这种,写成这样之后,如果尊重这种规范,HTML 5 提供了 dom对象.dataset.属性名 的方式来获取和修改这些自定义属性,也就是说所有以 data 开头的属性都会被维护在一个对象中,我们对自定义属性的管理就可以变成对这个对象的管理,非常方便。
注意,由于 HTML 不区分大小写,所以自定义属性应该使用横杠来分割多个单词,例如我需要添加一个属性为 first name,自定义属性名应该为 data-first-name,此时在 DOM 对象的 dataset 对象中,属性名会被自动转变为 firstName,即自动转换为小驼峰命名法。
上面介绍了如何获取和设置元素的属性,下面就是获取和设置元素的内容,这个很简单,涉及到三个属性
dom.innerHTML:获取和设置元素内部的 HTML 文本,也就是源代码。dom.innerText:获取和设置元素内部的纯文本,可以认为是显示出来的文本。dom.textContent:获取和设置元素内部的纯文本,和innerText不同的是,这个属性得到是所有文本,而innerText得到的仅仅是内容文本。
和
innerHTML对应的是outerHTML,innerHTML可以获取元素内部的 HTML 文本,而outerHTML获取到的文本会包含元素本身,同时也可以为其赋值。
html
<div id="test">
<p>测试</p>
</div>
<script>
var div = document.getElementById('test');
console.log(div.innerHTML);//<p>测试</p>
console.log(div.innerText);//测试
div.innerHTML = `<h1>测试</h1>`
</script>接下来我有这样一个需求,我想把 HTML 的元素顺序打乱,如下所示:
html
<ul id="ul1">
<li>选项1</li>
<li>选项2</li>
<li>选项3</li>
<li>选项4</li>
</ul>
<ul id="ul2">
<li>选项1</li>
<li>选项2</li>
<li>选项3</li>
<li>选项4</li>
</ul>在这个结构中,我想把 ul1 中的选项 2 拿出来插入到 ul2 中的末位,为了实现这个操作,就需要引入插入操作,插入操作使用 Node.appendChild(achild),这个方法的作用是在 Node 节点的最后插入一个 achild 节点。
html
<ul id="ul1">
<li>选项1</li>
<li>选项2</li>
<li>选项3</li>
<li>选项4</li>
</ul>
<ul id="ul2">
<li>选项1</li>
<li>选项2</li>
<li>选项3</li>
<li>选项4</li>
</ul>
<script>
var ul1 = document.getElementById("ul1");//获取ul1
var ul2 = document.getElementById("ul2");//获取ul2
var li = ul1.children[1];//获取ul1下的第2个li
ul2.appendChild(li);//将li添加到ul2
</script>
注意,这个
appendChild函数是用于节点操作的,也就是说哪怕是非元素节点,我们依然可以使用这个方法来追加。
但是 appendChild 其实并没有那么好用,因为这个方法只能传入一个参数,如果我要插入 100 个节点,我就得有 100 个 appendChild 操作,同时,插入的必须是一个节点对象,哪怕要插入一个文本,也需要将这文本转换为节点对象后作为参数传入(创建文本节点可以使用 createTextNode 方法),其实有一个更好用的方法是 append,语法为 Element.append(Node1,Node2,...),其作用为将 Node1,Node2,... 这些元素依次插入到 Element 元素的最后,成为其子元素。
append函数的参数不仅可以接收节点对象,还可以接收字符串,例如"test",此时append函数将把"test"自动转换为一个文本节点进行插入。
html
<ul id="ul1">
<li>选项1</li>
<li>选项2</li>
<li>选项3</li>
<li>选项4</li>
</ul>
<ul id="ul2">
<li>选项1</li>
<li>选项2</li>
<li>选项3</li>
<li>选项4</li>
</ul>
<script>
var ul1 = document.getElementById("ul1");//获取ul1
var ul2 = document.getElementById("ul2");//获取ul2
var li1 = ul1.children[1];//获取ul1下的第2个li
var li2 = ul1.children[2];//获取到ul1下的第3个li
ul2.append(li1,li2,"test");//依次添加
</script>
append 方法是一个比较新的方法,在一些很老的浏览器上可能存在兼容性问题,edge 直到 2018 年才支持这个方法。
上面我提到的方法是将元素插入到另一个元素末尾,但是有时候我希望一个元素插入指定位置,比如将下面的 ul1 中的选项 1 插入到 ul2 中选项 2 和选项 3 中间,要实现这种插入就需要引入到一个新方法:Node.insertBefore(newNode,reference),该方法中的 reference 应该是 Node 的子元素,这个方法可以将 newNode 插入到 Node 中成为 Node 的子元素,并且插入位置应该是 reference 之前。
html
<ul id="ul1">
<li>选项1</li>
<li>选项2</li>
<li>选项3</li>
<li>选项4</li>
</ul>
<ul id="ul2">
<li>选项1</li>
<li>选项2</li>
<li>选项3</li>
<li>选项4</li>
</ul>
<script>
var ul1 = document.getElementById("ul1");//获取ul1
var ul2 = document.getElementById("ul2");//获取ul2
var li1 = ul1.children[0];//获取ul1的选项1
var li2 = ul2.children[2];//获取ul2的选项3
ul2.insertBefore(li1, li2);//在ul2的选项3之前插入ul1的选项1
</script>
注意,原生JS 只提供了 insertBefore 方法,并没有提供 insertAfter 方法,也就是说我们只能把一个元素插入到指定元素之前,并不能插入到指定元素之后,实际上,我们完全可以自己封装出 insertAfter 方法
html
<ul id="ul1">
<li>选项1</li>
<li>选项2</li>
<li>选项3</li>
<li>选项4</li>
</ul>
<ul id="ul2">
<li>选项1</li>
<li>选项2</li>
<li>选项3</li>
<li>选项4</li>
</ul>
<script>
/**
* 将新节点插入到父节点中指定参考节点之后。
* @param {Element} parentNode - 父节点,新节点将被插入到这个节点中。
* @param {Element} newNode - 新节点,将被插入到父节点中。
* @param {Element} referenceNode - 参考节点,新节点将被插入到这个节点之后。
*/
function insertAfter(parentNode, newNode, referenceNode) {
parentNode.insertBefore(newNode, referenceNode.nextElementSibling);
}
// 获取id为'ul1'和'ul2'的两个<ul>元素
var ul1 = document.getElementById('ul1');
var ul2 = document.getElementById('ul2');
// 获取ul1的第二个子节点(<li>元素)和ul2的第三个子节点(<li>元素)
var li1 = ul1.children[1];
var li2 = ul2.children[2];
// 将ul1的第二个<li>元素插入到ul2的第三个<li>元素之后
insertAfter(ul2, li1, li2);
</script>
读者可能会有一些疑问,如果
referenceNode是parentNode的最后一个元素,那么referenceNode.nextElementSibling得到的结果就是null,这样并不会产生问题,因为insertBefore的第二个参数是可以传入null的,当第二个参数传入null的情况下,相当于是appendChild。
很多时候可能我们还需要用到替换操作,即将一个父元素的一个子元素替换为另一个元素,语法也很简单,即 Node.replaceChild(newChild,oldChild),该方法中 oldChild 必须是 Node 节点的子节点,该方法可以将 Node 节点中的 oldChild 替换为 newChild。
以上操作其实都会更改页面的元素结构,更改元素结构之后,会导致页面大面积的重新渲染,所以性能不佳,读者只需要知道,尽量少用即可,但使用 JS 动态改变元素结构也是不可避免的操作。
我们前面提到的都是如何从页面上获取一个已有的元素,实际上,我们还可以凭空创造一个元素,使用 document.createElement() 即可,例如 document.createElement("p"); 就会创建一个 p 元素,此时这个创建的元素和我们获取到的元素是一模一样的,我们也可以使用 innerHTML 修改内部的文本,一样可以给他添加子元素,一样可以把它插入到页面中去。
html
<ul id="ul">
<li>选项1</li>
<li>选项2</li>
<li>选项3</li>
<li>选项4</li>
</ul>
<script>
var ul = document.getElementById('ul');
var li = document.createElement('li');
li.innerText = "选项5";
ul.append(li);
</script>我们最常用的就是 createElement,也就是创建一个元素,因为我们绝大多数情况下都是对元素节点进行操作,当然,除此之外,我们还可以创建其他类型的节点:
document.createElement():创建元素节点,参数为元素名document.createTextNode():创建文本节点,参数为文本内容document.createComment():创建注释节点,参数为注释内容document.createAttribute():创建属性节点,参数为属性名,如果要给属性赋值,直接给该节点下的nodeValue属性赋值即可document.createFragment():创建文档片段
这里有必要介绍一下文档片段了,我们先来看下面的例子
html
<ul id="ul">
</ul>
<script>
var ul = document.getElementById('ul');
for (var i = 1; i <= 30; i++) {
var li = document.createElement("li");
li.innerHTML = `选项${i}`;
ul.append(li);
}
</script>
此时使用循环,向 ul 元素内部加入了 30 个 li,但是按照我们刚才介绍过的知识,这种方式并不好,因为我们执行了 30 次的插入操作,也就改变了 30 次的 DOM 结构,所以浏览器会重新渲染 30 次,这是似乎很浪费效率。我们其实可以先创建好 30 个 li 元素,把它放到一个容器里面,然后创建完毕之后一次性插入到 ul 中,这样整个页面只会重新渲染一次。那这 30 个 li 元素应该如何保存在一个容器里面呢,显然,一个变量只能保存一个 li 元素,但如果用一个数组来保存,我要把数组中的所有元素都插入到页面中,一样需要遍历一个一个插入,所以数组其实也不行。这个时候就要用到这个文档片段了,文档片段就可以看做是一个容器,它就是一个普普通通的容器,他不表现出任何内容。我们每创建一个元素,就插入到这个容器里面,等创建完成之后,再将这个容器直接插入到页面中即可。由于在文档片段中插入我们创建的 DOM 元素,这一整个操作都是在内存中的,都不改变 DOM 结构,所以并不会影响什么性能,只有最后一次将文档片段一整个插入的时候,才会改变 DOM 结构,导致重新渲染,所以这样可以大大提升效率。
html
<ul id="ul">
</ul>
<script>
var ul = document.getElementById('ul');
var frag = document.createDocumentFragment();//创建文档碎片
for (var i = 1; i <= 30; i++) {
var li = document.createElement("li");
li.innerHTML = `选项${i}`;
frag.append(li);//每次插入到文档碎片
}
ul.append(frag);//创建完成后插入到页面中
</script>有时候我们希望克隆出一个一模一样的元素,就需要使用
Node.cloneNode(deep),该方法用于克隆一个一模一样的元素,即返回一个和Node一模一样的元素。这个 deep 是一个布尔参数,用于选择是否深度克隆,如果填入 false,那么只克隆节点本身(包括自己的属性节点),并不克隆其子节点,如果传入 true,则会把这个元素以及其所有子节点全部克隆。
最后一个对 DOM 元素本身的操作就是删除了,要删除页面上的一个 DOM 元素,可以使用两种方式,一种是父元素删除他的子元素,另一种是自己把自己删掉。
Node.removeChild(childNode):该方法可以删除Node元素的childNode子元素Node.remove():该方法可以删除掉Node元素自身
这两种方法可以将一个 DOM 节点从页面上删除,并返回被删除的这个 DOM 对象。
以下是一些练习:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.container {
width: 400px;
margin: 0 auto;
}
.container li {
margin: 20px 0;
}
.container button {
margin-left: 10px;
}
</style>
</head>
<body>
<div class="container">
<p>
<button>清空</button>
</p>
<ul class="list">
<li>项目1<button>删除</button></li>
<li>项目2<button>删除</button></li>
<li>项目3<button>删除</button></li>
<li>项目4<button>删除</button></li>
<li>项目5<button>删除</button></li>
<li>项目6<button>删除</button></li>
<li>项目7<button>删除</button></li>
<li>项目8<button>删除</button></li>
<li>项目9<button>删除</button></li>
<li>项目10<button>删除</button></li>
</ul>
</div>
<script>
// 获取页面中特定的元素
var clear = document.querySelector(".container p button"); // 获取容器中段落内的按钮
var list = document.getElementsByClassName("list")[0]; // 获取第一个类名为 "list" 的元素
var removes = document.querySelectorAll(".container li button"); // 获取容器中所有列表项内的按钮
// 为每个移除按钮添加点击事件处理程序
for (var i = 0; i < removes.length; i++) {
removes[i].onclick = function () {
this.parentElement.remove(); // 当点击按钮时,移除其父元素(即列表项)
}
}
// 为清除按钮添加点击事件处理程序
clear.onclick = function () {
list.innerHTML = ""; // 当点击按钮时,清空列表内容
}
</script>
</body>
</html>该练习需要知道 this 指向的问题,在事件处理函数中,this 指向注册该事件的对象
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
span {
min-width: 50px;
display: inline-block;
text-align: center;
color: red;
}
</style>
</head>
<body>
<p>
库存的最小值为0
</p>
<div class="btns">
库存:
<button>-1000</button>
<button>-100</button>
<button>-10</button>
<button>-1</button>
<span>0</span>
<button>+1</button>
<button>+10</button>
<button>+100</button>
<button>+1000</button>
</div>
<script>
/**
* 初始化页面中的按钮点击事件,实现库存数量的加减操作。
* 当点击按钮时,会根据按钮的文本值(代表加减的数值)对当前库存数量进行相应调整。
* 如果操作后库存数量小于0,则会提示库存不足。
*/
var btns = document.querySelectorAll(".btns button"); // 获取页面上所有类名为btns的元素下的button元素
var text = document.querySelector(".btns span"); // 获取页面上类名为btns的元素下的第一个span元素,用于显示当前库存数量
for (var i = 0; i < btns.length; i++) {
// 为每个按钮绑定点击事件
btns[i].onclick = function () {
// 获取当前按钮的文本值,转换为数字
var add = Number(this.innerText);
// 获取当前库存数量,转换为数字
var currentNum = Number(text.innerText);
// 如果加减操作后的库存数量小于0,则提示库存不足,并终止操作
if (currentNum + add < 0) {
alert("库存不足");
return;
}
// 更新库存数量的显示
text.innerText = currentNum + add;
}
}
</script>
</body>
</html>html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.container {
width: 400px;
margin: 0 auto;
}
p {
text-align: center;
}
</style>
</head>
<body>
<div class="container">
<p>不能添加空的文本</p>
<div class="input">
<input type="text">
<button>添加</button>
</div>
<ul class="list">
<li>项目1</li>
<li>项目2</li>
</ul>
</div>
<script>
// 获取页面中类名为.list的元素、输入类型为text的input元素以及类名中包含input的button元素
var list = document.querySelector(".list");
var input = document.querySelector("input[type=text]");
var button = document.querySelector(".input button");
// 给按钮添加点击事件处理函数
button.onclick = function () {
// 获取输入框中的值,并去除首尾空格
var value = input.value.trim();
// 清空输入框
input.value = "";
// 如果输入值为空,则弹窗提示并返回
if (!value) {
alert("输入框不能为空");
return;
}
// 创建一个li元素,并将输入的值设置为li的文本内容
var li = document.createElement("li");
li.innerText = value;
// 将新创建的li元素添加到列表中
list.append(li);
}
</script>
</body>
</html>html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.banner {
width: 500px;
margin: 0 auto;
text-align: center;
}
.banner img {
width: 100%;
height: 300px;
object-fit: contain;
border: 1px solid;
display: block;
}
</style>
</head>
<body>
<div class="banner">
<img src="img/1.jpg" alt="">
<p>
<button>上一张</button>
<button>下一张</button>
</p>
</div>
<script>
// 初始化当前图片索引
var currentImg = 1;
// 获取下一个按钮元素
var next = document.querySelectorAll(".banner button")[1];
// 获取上一个按钮元素
var previous = document.querySelectorAll(".banner button")[0];
// 获取图片元素
var img = document.querySelector(".banner img");
// 点击下一个按钮时的事件处理函数
next.onclick = function () {
// 如果当前图片索引超过总数,则重置为1
if (++currentImg > 5) {
currentImg = 1;
}
// 更新图片源为当前索引对应的图片
img.src = `img/${currentImg}.jpg`;
}
// 点击上一个按钮时的事件处理函数
previous.onclick = function () {
// 如果当前图片索引小于1,则重置为总数
if (--currentImg < 1) {
currentImg = 5;
}
// 更新图片源为当前索引对应的图片
img.src = `img/${currentImg}.jpg`;
}
</script>
</body>
</html>html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.container {
overflow: hidden;
width: 550px;
margin: 0 auto;
}
.container .left {
float: left;
margin: 0 30px;
}
.container select {
width: 100%;
height: 200px;
}
.container .mid {
padding-top: 70px;
}
</style>
</head>
<body>
<div class="container">
<div class="left">
<h2>成哥的现任女友</h2>
<select id="sel1" multiple>
<option value="1">幂幂</option>
<option value="2">花花</option>
<option value="3">春春</option>
<option value="4">盈盈</option>
<option value="5">红红</option>
</select>
</div>
<div class="left mid">
<p>
<button title="右移动选中的">>></button>
</p>
<p>
<button title="右移动全部">>>|</button>
</p>
<p>
<button title="左移动选中的"><<</button>
</p>
<p>
<button title="左移动全部">|<<</button>
</p>
</div>
<div class="left">
<h2>成哥的前女友</h2>
<select id="sel2" multiple>
<option value="6">坤坤</option>
</select>
</div>
</div>
<script>
// 获取页面中具有特定title属性的按钮元素和两个目标选框
var right = document.querySelector('button[title="右移动选中的"]'); // 右移选中项按钮
var left = document.querySelector('button[title="左移动选中的"]'); // 左移选中项按钮
var rightAll = document.querySelector('button[title="右移动全部"]'); // 右移全部项按钮
var leftAll = document.querySelector('button[title="左移动全部"]'); // 左移全部项按钮
var leftBox = document.getElementById('sel1'); // 左侧选择框
var rightBox = document.getElementById('sel2'); // 右侧选择框
// 设置右移按钮点击事件处理函数
right.onclick = function () {
// 循环遍历左侧选择框的子元素,将选中的元素移动到右侧选择框
for (var i = leftBox.children.length - 1; i >= 0; i--) {
if (leftBox.children[i].selected) {
rightBox.appendChild(leftBox.children[i]);
}
}
}
// 设置左移按钮点击事件处理函数
left.onclick = function () {
// 循环遍历右侧选择框的子元素,将选中的元素移动到左侧选择框
for (var i = rightBox.children.length - 1; i >= 0; i--) {
if (rightBox.children[i].selected) {
leftBox.appendChild(rightBox.children[i]);
}
}
}
// 设置左移全部按钮点击事件处理函数
leftAll.onclick = function () {
// 将右侧选择框的所有内容移动到左侧选择框,并清空右侧选择框
leftBox.innerHTML += rightBox.innerHTML;
rightBox.innerHTML = "";
}
// 设置右移全部按钮点击事件处理函数
rightAll.onclick = function () {
// 将左侧选择框的所有内容移动到右侧选择框,并清空左侧选择框
rightBox.innerHTML += leftBox.innerHTML;
leftBox.innerHTML = "";
}
</script>
</body>
</html>