小黑子的JavaScript入土过程第四章
- JavaScript系列教程第四章
- 4.1 初识DOM
- 4.2 操作元素属性
- 4.3 密码可视案例
- 4.4 购物车全选案例
- 4.5 操作元素文本内容
- 4.6 渲染页面案例
- 4.7 操作元素样式
- 4.8 操作元素类名
- 4.9 选项卡案例
- 4.10 DOM节点
- 4.11 获取节点的方式
- 4.11.1 childNodes:获取某一个节点下所有的子一级节点
- 4.11.2 children :获取某一节点下所有的子一级 元素节点
- 4.11.3 firstChild:获取某一节点下子一级的 第一个节点
- 4.11.4 firstElementChild:获取某一节点下子一级 第一个元素节点
- 4.11.5 lastChild:获取某一节点下子一级的 最后一个节点
- 4.11.6 lastElementChild:获取某一节点下子一级 最后一个元素节点
- 4.11.7 previousSibling:获取某一个节点的 上一个兄弟节点
- 4.11.8 previousElementSibling:获取某一个节点的 上一个元素节点
- 4.11.9 nextSibling:获取某一个节点的下一个兄弟节点
- 4.11.10 nextElementSibling:获取某一个节点的 下一个元素节点
- 4.11.11 parentNode:获取某一个节点的父节点
- 4.11.12 parentElement:获取父一个节点的元素
- 4.11.13 attributes:获取某一个元素节点的所有属性节点
- 4.12 节点操作
- 4.13 动态删除案例
- 4.14 节点属性
- 4.15 获取元素尺寸
- 4.16 获取元素的偏移量
- 4.17 获取浏览器窗口尺寸
- 4.18 懒加载案例
- 4.19 初识事件
- 4.20 事件解绑
- 4.21 事件类型
- 4.22 事件对象
- 4.23 事件对象鼠标事件
- 4.24 鼠标跟随案例
- 4.25 鼠标拖拽案例
- 4.26 DOM事件流
- 4.27 节点.stopPropagation() 阻止事件传播
- 4.28 阻止默认行为
- 4.29 自定义右键菜单案例
- 4.30 事件委托
JavaScript系列教程第四章
4.1 初识DOM
4.1.1 获取一个元素
通过 js 代码来获取页面中的标签
获取到以后我们就可以操作这些标签了
<script>
console.log(document.documentElement)//获取html的标签
console.log(document.head)//获取head的标签
console.log(document.body)//获取body的标签
</script>
4.1.2 非常规的标签获取
一、getElementById(id获取)
因为在一个页面中 id 是唯一的,所以获取到的就是一个元素
<div id="obox"></div>
<script>
var obox = document.getElementById('obox')//字符串
console.log(obox)
</script>
获取到的就是页面中的那个 id 为 obox 的 div 标签
二、getElementsByClassName(class获取)
> 因为页面中可能有多个元素的 class 名称一样,所以获取到的是一组元素
> 哪怕你获取的 class 只有一个,那也是获取一组元素,只不过这一组中只有一个 DOM 元素而已
> 获取到的是一组元素,是一个长得和数组一样的数据结构,但是不是数组,是 伪数组,有length的属性
> 这个一组数据也是按照索引排列的,所以我们想要准确的拿到这个 li,需要用索引来获取
> 即返回值是一个伪数组
<ul>
<li class="newsitem">11111</li>
<li class="newsitem">11111</li>
<li class="newsitem">11111</li>
<li class="newsitem">11111</li>
<li class="newsitem">11111</li>
<li class="newsitem">11111</li>
</ul>
<script>
var item = document.getElementsByClassName("newsitem")
console.log(item.fillter)//无定义,是伪数组
// item[0].innerHTML="news-11111"可以用其改变第一个li的值为news-11111
for(var i=0;i<item.length;i++)
{
item[i].innerHTML ="news-"+i
}//利用for循环对每个li的值进行顺序修改
</script>
可以利用set结构的Array.form属性来使伪数组转化为真数组
var newitem = Array.from(item)//将伪数组转换为真数组
console.log(newitem.map)
三、getElementsByTagName(标签名获取)
getElementsByTagName 是用过标签的标签名称来获取标签的
因为页面中可能有多个元素的 标签 名称一样,所以获取到的是一组元素
哪怕真的只有一个这个标签名,那么也是获取一组元素,只不过这一组中只有一个 DOM 元素而已
和 getElementsByClassName 一样,获取到的是一个长得很像数组的元素
必须要用索引才能得到准确的 DOM 元素
<ul>
<li class="newsitem">11111</li>
<li class="newsitem">11111</li>
<li class="newsitem">11111</li>
<li class="newsitem">11111</li>
<li class="newsitem">11111</li>
<li class="newsitem">11111</li>
</ul>
<ul>
<li class="aditem">11111</li>
<li class="aditem">11111</li>
<li class="aditem">11111</li>
<li class="aditem">11111</li>
<li class="aditem">11111</li>
<li class="aditem">11111</li>
</ul>
<script>
var item =document.getElementsByTagName("li")//找到标签一样的全部显示
console.log(item)
</script>
四、getElementsByName(name属性获取)
一般只适用于input标签
<input type="text" name="username">
<input type="password" name="password">
<script>
var item = document.getElementsByName("username")
console.log(item[0])
item[0].value = "steve"
</script>
五、querySelector(选择器获取,返回一个)
有兼容性问题,不过现在基本上没太大问题
querySelector 是按照选择器的方式来获取元素
也就是说,按照我们写 css 的时候的选择器来获取
这个方法只能获取到一个元素,并且是页面中第一个满足条件的元素
<ul>
<li>111</li>
<li>111</li>
<li>111</li>
<li>111</li>
<li>111</li>
</ul>
<script>
var item = document.querySelector("ul li")
console.log(item)
</script>
六、querySelectorAll(选择器获取,返回所有满足条件的)
也有兼容性问题,不过现在基本上没太大问题
querySelectorAll 是按照选择器的方式来获取元素
这个方法能获取到所有满足条件的元素,以一个伪数组的形式返回
获取到的是一组数据,也是需要用索引来获取到准确的每一个 DOM 元素
<ul>
<li class="newsitem">111</li>
<li class="newsitem">111</li>
<li class="newsitem">111</li>
<li class="newsitem">111</li>
<li class="newsitem">111</li>
<li class="newsitem">111</li>
<li>111</li>
</ul>
<script>
var item = document.querySelectorAll("ul li.newsitem")
console.log(item)
</script>
4.2 操作元素属性
我们通过各种获取元素的方式获取到页面中的标签以后
可以直接操作 DOM 元素的属性,就能直接把效果展示在页面上
4.2.1 元素自带(原生)属性
可以通过class或id来直接操作原生的属性
<div id="box" kerwin="hello">hello</div>
<input type="text" value="hello" id="username">
<input type="checkbox" checked id="rember">
<script>
box.innerHTML ="22222"
username.type = "password"
rember.checked = false
</script>
原本的属性在sript中被修改了
4.2.2 自定义属性
一、setAttribute ,getAttibute ,removeAttibute
添加自定义属性setAttribute
获取自定义属性getAttibute
删除自定义属性removeAttibute
案例:
<ul>
<li>11111</li>
<li >2222</li>
<li >3333</li>
<li ">44444</li>
</ul>
<script>
var item = document.getElementsByTagName("li")//获取li
for(var i=0;i<item.length;i++)
{
item[i].setAttribute("van",i)
}
</script>
利用for循环将每个li赋予顺序的自定义属性
二、dataset属性
利用dataset属性可以获取和设置自定义属性
删除自定义属性
delete 名字.自定义属性
案例:
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
var item=document.getElementsByTagName("li")
for(var i=0;i<item.length;i++){
item[i].dataset.tiechui=i
}
</script>
4.3 密码可视案例
<input type="password" id="password">
<button id="eyebtn">eye</button>
<script>
var passinput = document.getElementById("password")
var eyebtn = document.querySelector("#eyebtn")
eyebtn.onclick = function () {
console.log(passinput.type)
if (passinput.type == "password")
{
passinput.type = "text"
}
else
{
passinput.type = "password"
}
}
</script>
点击前
点击后
4.4 购物车全选案例
<input type="checkbox" id="all">全选/全不选
<hr>
<ul class="shop">
<li>
<input type="checkbox">商品1
</li>
<li>
<input type="checkbox">商品2
</li>
<li>
<input type="checkbox">商品3
</li>
<li>
<input type="checkbox">商品4
</li>
</ul>
<script>
var oAll = document.querySelector("#all")
var item = document.querySelectorAll(".shop input")
oAll.onclick = function ()
{
console.log(oAll.checked)
for (var i = 0; i < item.length; i++)
{
item[i].checked = oAll.checked
}//利用for循环实现全选选框给每个li顺序赋与选上,当全选或不选时所以相应
}
//每点其中的任何一项,都可以把四个循环一遍,看看里面是否被勾选
//如果被勾,在以count为0的基础上加1,每点一个,都把count值重新赋值成0
//再次地开始循环一下这四个,把里面勾了的数量找出来,加加
for (var i = 0; i < item.length; i++)
{
item[i].onclick = handler//这个for循环只是给每个li赋值一个函数
}
function handler() //每次li勾选这个函数,count都为0,开始循环判断被选上的count加加
{
var count = 0
for (var i = 0;i<item.length; i++)
{
if (item[i].checked)
{count++}
}//for判断每一项如果checked count++
if (count === item.length) //如果count自增到了整个数组一样就相当于每个li用户全选了
{
oAll.checked = true//li全选了那么就控制全选框也勾选上
}
else
{
oAll.checked = false
}
}
</script>
4.5 操作元素文本内容
4.5.1 innerHTML获取元素内部的 HTML 结构(所有内容)
<div id="box">
<span>hello</span>
<div>steve</div>
</div>
<script>
console.log(box.innerHTML)
box.innerHTML="<h1>111111</h1>"//将box里的文本全部改成111,并且解析HTEML
</script>
4.5.1innerText 获取元素内部的文本(只能获取到文本内容,获取不到 html 标签)
<div id="box">
<span>hello</span>
<div>steve</div>
</div>
<script>
console.log(box.innerText)//获取只有文本
box.innerText = "<h1>111111</h1>"//不解析HTML
</script>
4.5.1 value
可以读取,也可以赋值,大多时候用于表单元素
<input type="text" id="username" value="hello">
<select name="" id="select">
<option value="1">11111</option>
<option value="2" selected>22222</option>
<option value="3">33333</option>
</select>
<script>
console.log(username.value)
username.value = "22222"
console.log(select.value)
</script>
4.6 渲染页面案例
<style>
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
li {
overflow: hidden;
}
li img {
float: left;
width: 200px;
height: 200px;
}
</style>
<ul>
<!-- <li>
<img src="" alt="">
<h3></h3>
<p></p>
</li> 这样写不利于后面更新改写-->
</ul>
<script>
var filmlist = [
{
url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100",
title: "神奇麻瓜",
grade: "7.4",
},
{
url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100",
title: "神奇麻瓜",
grade: "7.4",
},
{
url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100",
title: "神奇麻瓜",
grade: "7.4",
},
]
var newfilmitem = filmlist.map(function (item)
{//用map映射可以把数组映射成想要的结构,把每个item进来函数之后变成了同一个li结构
return `<li>
<img src="${item.url}" alt="">
<h3>${item.title}</h3>
<p>${item.grade}</p>
</li>`//因为要后期要改的数据不一样,所以要用${}可以替换后台的变量
})
console.log(newfilmitem.join(""))//通过数组转换成字符串,就可以链接起来
var oul = document.querySelector("ul")//通过获取ul的方式
oul.innerHTML = newfilmitem.join("")//通过能解析的innerHTML就可以变除图片了
</script>
4.7 操作元素样式
4.7.1 获取行间样式-行内样式方法
容易进行读写,更改样式数值
访问和更改复合样式时,不能使用常规的方法来获取
有以下两种方法
// 使用[](中括号)
// 使用驼峰式命名法
<style>
#box {
height: 100px;
background-color: yellow;
}
</style>
<div id="box" style="width: 100px;color: black; background-color: yellow;">111111</div>
<script>
console.log(box.style.width)
console.log(box.style.height)
// 访问复合样式时,不能使用常规的方法来获取
// 有以下两种方法
// 使用[](中括号)
// 使用驼峰式命名法
console.log(box.style["background-color"])
console.log(box.style.backgroundColor)
box.style.width = "200px"
box.style.backgroundColor = "red"//或者box.style["background-color"]
</script>
改前
改后
4.7.2 获取的非行间样式getComputedstyle 获取
内部样式,外部样式,行内getComputedstyle 获取,不能用于赋值修改样式
可以获取,但是不能更改样式,可以读取
在操作 DOM 的时候,很重要的一点就是要操作元素的 css 样式
那么在操作 css 样式的时候,我们避免不了就要获取元素的样式
之前说过可以用 元素.style.xxx 来获取
但是这个方法只能获取到元素行间样式,也就是写在行内的样式
<style>
#box {
height: 100px;
background-color: yellow;
}
</style>
<div id="box" style="width: 100px;color: black; background-color: yellow;">111111</div>
<script>
var obox = document.getElementById("box")//严格获取obox放到下面函数作参数
console.log(getComputedStyle(obox).height)
console.log(getComputedStyle(obox).width)
console.log(getComputedStyle(obox)["background-color"])
console.log(getComputedStyle(obox).backgroundColor)
</script>
4.8 操作元素类名
4.8.1 .className用来读取和赋值html里的class值
专门用来操作元素的类名
<style>
.item{
width: 100px;
height: 100px;
background-color: red;
color: black;
border-radius: 10px;
}
</style>
<div id="box" class="item item1 item2">16116</div>
<script>
box.className = ""
//box.className = "item"可以设置留下几个属性,或者新建属性
console.log(box.className)
</script>
4.8.1 .classList用来读取和赋值html里的class值,但是是以伪数组的形式来读取或修改
一、.add()增加class值,不会添加相同的class值,一次只能添加一个值
二、.remove()删除class值
<style>
.item{
width: 100px;
height: 100px;
background-color: red;
color: black;
border-radius: 10px;
}
</style>
<div id="box" class="item item1 item2">16116</div>
<script>
console.log(box.classList)
box.classList.add("item3")//.add()增加class值,不会添加相同的class值,一次只能添加一个值
console.log(box.classList)
box.classList.remove("item")//.remove()删除class值
console.log(box.classList)
</script>
三、toggle 切换
如果原本有这个class值,就会删除这个class值,如果没有,就会添加上这个class值
应用点击实现删除再现效果:
<style>
.item{
width: 100px;
height: 100px;
background-color: red;
color: black;
border-radius: 10px;
}
</style>
<div id="box" class="item item1 item2">16116</div>
<button id="btn">wdnmd</button>
<script>
btn.onclick = function(){
box.classList.toggle("item")
}
</script>
点击前
点击后
4.9 选项卡案例
4.9.1 简易选项卡原理
<style>
* {
margin: 0;
padding: 0;
}
ul {
display: flex;
list-style: none;
}
li {
height: 50px;
line-height: 50px;
text-align: center;
flex: 1;
}
.active {
color: red;
border-bottom: 1px solid red;
}
</style>
<ul>
<!-- 实现点击不同的li有下划线切换 -->
<li class="active" id="item1">正在上映</li>
<li id="item2">即将上映</li>
</ul>
<script>
// 实现点击不同的li有下划线切换
item1.onclick = function () {
item1.classList.add("active")
item2.classList.remove("active")
}
item2.onclick = function () {
item1.classList.remove("active")
item2.classList.add("active")
}
</script>
4.9.2 复杂选项卡
<style>
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
.header {
display: flex;
width: 500px;
margin: 0 auto;
}
.header li {
flex: 1;
height: 50px;
line-height: 50px;
text-align: center;
border-bottom: 1px solid black;
}
.box {
width: 500px;
position: relative;
margin: 0 auto;
}
.box li {
position: absolute;
left: 0;
top: 0;
width: 500px;
height: 200px;
background-color: yellow;
display: none;
}
.header .active {
background-color: red;
}
.box .active {
display: block;
/* 与li的display: none呼应,实现点击切换的效果 */
}
</style>
<ul class="header">
<li class="active">1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<ul class="box">
<li class="active">1111</li>
<li>2222</li>
<li>3333</li>
<li>4444</li>
</ul>
<script>
var oheaderitem = document.querySelectorAll(".header li")
var oboxitem = document.querySelectorAll(".box li")
// for (var i = 0; i< oheaderitem.length; i++ )
// {
// oheaderitem[i].onclick = function ()
// {
// console.log(i)
// }
// }由于单线程和人的手速没有这么快,导致for循环执行的比onclick这个事件快,进而i就会变成4,就有点像异步执行,不采用
for (var i = 0; i < oheaderitem.length; i++)
{
//在for循环中,给每个头部li设置自定义属性加索引,在点击时获取属性给外部函数执行
oheaderitem[i].dataset.index = i
//为了防止没点之前就执行完,将点击执行在外部
oheaderitem[i].onclick = handler
}
//在外部定义好
function handler()
{
var index = this.dataset.index //this实现点击返回的是当前这一项,再利用dataset.index就可以知道点击时,是第几个
for (var j = 0; j < oheaderitem.length; j++) //要给第几个加active,又要记住对上一个的actibe进行移除,太麻烦。对每一个的active先移除一遍,在点击时加active就行了
{
oheaderitem[j].classList.remove("active")
oboxitem[j].classList.remove("active")
}
oheaderitem[index].classList.add("active")
oboxitem[index].classList.add("active")
}
</script>
4.10 DOM节点
DOM 的节点我们一般分为常用的三大类 元素节点 / 文本节点 / 属性节点
什么是分类,比如我们在获取元素的时候,通过各种方法获取到的我们叫做元素节点(标签节点)
比如我们标签里面写的文字,那么就是文本节点
写在每一个标签上的属性,就是属性节点
4.10.1 元素节点
我们通过 getElementBy… 获取到的都是元素节点
4.10.2 属性节点
我们通过 getAttribute 获取的就是元素的属性节点
4.10.3 文本节点
我们通过 innerText 获取到的就是元素的文本节点
4.10.4 注释节点
例子:
上面div中有5个节点
4.11 获取节点的方式
4.11.1 childNodes:获取某一个节点下所有的子一级节点
<div>
<p>hello</p>
</div>
<script>
// 这个 Div 获取的是页面中的 div 元素,就是一个元素节点
var Div = document.querySelector('div')
console.log(Div.childNodes)
</script>
拿到以后是一个伪数组,里面有三个节点
一个 text:从 <div> 一直到 <p> 中间有一个换行和一堆空格,这个是第一个节点,是一个文本节点
一个 p:这个 p 标签就是第二个节点,这个是一个元素节点
一个 text:从 </p> 一直到 </div> 中间有一个换行和一堆空格,这个是第三个节点,是一个文本节点
这个时候就能看到我们有不同的节点类型了
4.11.2 children :获取某一节点下所有的子一级 元素节点
上例加
console.log(Div.children)
只有一个节点了,因为 children 只要元素节点
div 下面又只有一个元素节点,就是 p
所以就只有一个,虽然只有一个,但是也是一个伪数组
4.11.3 firstChild:获取某一节点下子一级的 第一个节点
上例加
console.log(Div.firstChild)
这个是只获取一个节点,不再是伪数组
获取的是第一个
第一个就是 <div> 一直到 <p> 的那个换行和空格,是文本节点
4.11.4 firstElementChild:获取某一节点下子一级 第一个元素节点
上例加
console.log(Div.firstElementChild)
只获取一个节点,不在是伪数组
获取的是第一个 元素节点
第一个元素节点就是 p 标签,是一个元素节点
4.11.5 lastChild:获取某一节点下子一级的 最后一个节点
上例加
console.log(Div.lastChild)
只获取一个节点,不再是伪数组
获取的是最后一个
最后一个就是 </p> 一直到 </div> 之间的换行和空格,是个文本节点
4.11.6 lastElementChild:获取某一节点下子一级 最后一个元素节点
<div>
<p>hello</p>
<p>22222</p>
</div>
<script>
var Div = document.querySelector('div')
console.log(Div.lastChild)
</script>
只获取一个节点,不再是伪数组
获取的是最后一个元素节点
最后一个元素节点是 <p>22222</p>,是一个元素节点
4.11.7 previousSibling:获取某一个节点的 上一个兄弟节点
<ul>
<li id="a">11111</li>
<li id="b">22222</li>
<li id="c">33333</li>
</ul>
<script>
var Li = document.querySelector('#b')
console.log(Li.previousSibling)
</script>
只获取一个节点,不是伪数组
获取的是 id="b" 这个 li 的上一个兄弟节点
因为 id="b" 的上一个节点,是两个 li 标签之间的换行和空格,所以是一个文本节点
4.11.8 previousElementSibling:获取某一个节点的 上一个元素节点
上例加
console.log(Li.previousElementSibling)
只获取一个节点,不是伪数组
获取的是 id="b" 这个 li 的上一个兄弟元素节点
因为 id="b" 的上一个兄弟元素节点就是 id="a" 的 li,是一个元素节点
parentNode
4.11.9 nextSibling:获取某一个节点的下一个兄弟节点
上例加
console.log(Li.nextSibling)
只获取一个节点,不是伪数组
获取的是 id="b" 这个 li 的下一个兄弟节点
因为 id="b" 的下一个节点,是两个 li 标签之间的换行和空格,所以是一个文本节点
4.11.10 nextElementSibling:获取某一个节点的 下一个元素节点
上例加
console.log(Li.nextElementSibling)
只获取一个节点,不是伪数组
获取的是 id="b" 这个 li 的下一个兄弟元素节点
因为 id="b" 的下一个兄弟元素节点就是 id="c" 的 li,是一个元素节点
4.11.11 parentNode:获取某一个节点的父节点
上例加
console.log(Li.parentNode)
只获取一个节点,不是伪数组
获取的是当前这个 li 的父元素节点
因为这个 li 的父亲就是 ul,所以获取到的就是 ul,是一个元素节点
4.11.12 parentElement:获取父一个节点的元素
上例加
console.log(Li.parentElement.parentElement)
4.11.13 attributes:获取某一个元素节点的所有属性节点
上例加
console.log(Li.attributes)
获取的是一组数据,是该元素的所有属性,是一个伪数组
4.12 节点操作
我们所说的操作无非就是 增删改查
创建一个节点(因为向页面中增加之前,我们需要先创建一个节点出来)
向页面中增加一个节点
删除页面中的某一个节点
修改页面中的某一个节点
获取页面中的某一个节点
4.12.1 创建一个节点
一、createElement:用于创建一个元素节点
<div id="box">
<div id="child">111111</div>
</div>
<script>
var odiv = document.createElement("div")
odiv.innerHTML = "我是新创建的节点"
console.log(odiv)
</script>
二、createTextNode:用于创建一个文本节点
4.12.2 向页面中增加一个节点
四、appendChild:是向一个元素节点插入一个节点
<div id="box">
<div id="child">111111</div>
</div>
<script>
var odiv = document.createElement("div")
odiv.innerHTML = "我是新创建的节点"
odiv.id="aaa"
odiv.style.background="yellow"
console.log(odiv)
box.appendChild(odiv)
</script>
五、insertBefore:向某一个节点前插入一个节点
上例代码将 box.appendChild(odiv)改成如下
box.insertBefore(odiv)
4.12.3 删除页面中的某一个节点
六、removeChild:移除某一节点下的某一个节点
上例
box.removeChild(child)//删除后代
box.remove()//删除自己以及后代
4.12.5 修改页面中的某一个节点
七、replaceChild:将页面中的某一个节点替换掉
<div id="box">
<div id="child">111111</div>
</div>
<script>
var odiv = document.createElement("div")
odiv.innerHTML = "我是新创建的节点"
odiv.id="aaa"
odiv.style.background="yellow"
console.log(odiv)
var odiv2 = document.createElement("div")
odiv2.innerHTML = "222222222"
box.replaceChild(odiv2,child)
</script>
4.12.6 克隆页面中的某一个节点
八、cloneNode 克隆
克隆节点()
false 不克隆后代
true克隆后代
<div id="box">
<div id="child">111111</div>
</div>
<script>
var odiv = document.createElement("div")
odiv.innerHTML = "我是新创建的节点"
odiv.id="aaa"
odiv.style.background="yellow"
console.log(odiv)
var oCloneBox = box.cloneNode(true)
console.log(oCloneBox)
oCloneBox.id = "box2"
document.body.appendChild(oCloneBox)
</script>
4.13 动态删除案例
<ul id="list"></ul>
<script>
var arr = ["111", "2222", "333"]
for (var i = 0; i < arr.length; i++)
{
var oli = document.createElement("li")
//把按钮追加到li中
oli.innerHTML = arr[i]
var obutton = document.createElement("button")
// 再按钮里放内容
obutton.innerHTML = "delate"
// 将函数赋予点击属性
obutton.onclick = handlr
oli.appendChild(obutton)
list.appendChild(oli)
}
function handlr()
{
this.parentNode.remove()//利用this选择到点击的部分,如果没有parentNode则点击只会删除按钮不会删除li部分
}
</script>
4.14 节点属性
<ul test="我是 ul 的一个属性">
<li>hello</li>
</ul>
<script>
// 先获取 ul
var oUl = document.querySelector('ul')
// 获取到 ul 下的第一个子元素节点,是一个元素节点
var eleNode = oUl.firstElementChild
// 获取到 ul 的属性节点组合,因为是个组合,我们要拿到节点的话要用索引
var attrNode = oUl.attributes[0]
// 获取到 ul 下的第一个子节点,是一个文本节点
var textNode = oUl.firstChild
</script>
4.14.1 nodeType:获取节点的节点类型,用数字表示
console.log(eleNode.nodeType) // 1
nodeType === 1 就表示该节点是一个 元素节点
console.log(attrNode.nodeType) // 2
nodeType === 2 就表示该节点是一个 属性节点
console.log(textNode.nodeType) // 3
nodeType === 3 就表示该节点是一个 注释节点
4.14.2 nodeName:获取节点的节点名称
console.log(eleNode.nodeName) // LI
元素节点的 nodeName 就是大写标签名
console.log(attrNode.nodeName) // test
属性节点的 nodeName 就是属性名
console.log(textNode.nodeName) // #text
文本节点的 nodeName都是#text
4.14.3 nodeValue: 获取节点的值
console.log(eleNode.nodeValue) // null
元素节点没有 nodeValue
console.log(attrNode.nodeValue) // 我是 ul 的一个属性
属性节点的 nodeValue 就是属性值
console.log(textNode.nodeValue) // 换行 + 空格
文本节点的 nodeValue 就是文本内容
4.15 获取元素尺寸
就是获取元素的 “占地面积”,而不是元素的大小
可以实现懒加载的效果(像京东的商品栏)
好处:当滑块滑到底部时再加载,可以减少用户的缓存
注意:
获取到的尺寸是没有单位的数字
不会对box-sizing有影响
当元素在页面中不占位置的时候, 获取到的是 0
display: none; 元素在页面不占位
visibility: hidden; 元素在页面占位
4.15.1 offsetWith 和 offsetHeight
offsetWidth : 获取的是元素 内容 + padding + border 的宽度
offsetHeight : 获取的是元素 内容 + padding + border 的高度
4.15.2 clientWidth 和 clientHeight
clientWidth : 获取的是元素 内容 + padding 的宽度
clientHeight : 获取的是元素 内容 + padding 的高度
<style>
div{
width: 100px;
height: 100px;
padding: 10px;
border: 5px solid red;
background-color: yellow;
}
</style>
<div id="box"></div>
<script>
console.log(box.offsetWidth,box.offsetHeight)
console.log(box.clientWidth,box.clientHeight)
</script>
4.16 获取元素的偏移量
元素在页面上相对于参考父级的左边和上边的距离
4.16.1 offsetParent
获取元素的偏移量参考父级
其实就是假设要给一个元素绝对定位的时候
它是根据谁来进行定位的
那么这个元素的偏移量参考父级就是谁
4.16.2 offsetLeft 和 offsetTop
获取的是元素左边的偏移量和上边的偏移量
offsetLeft : 该元素相对于参考父级的左侧偏移量
offsetTop : 该元素相对于参考父级的上侧偏移量
4.17 获取浏览器窗口尺寸
前面学过一个 innerWidth 和 innerHeight获取到的是窗口包含滚动条的尺寸
下面学习两个不包含滚动条的尺寸获取方式
document.documentElement.clientWidth : 可视窗口的宽度
document.documentElement.clientHeight : 可视窗口的高度
4.18 懒加载案例
<style>
* {
margin: 0;
padding: 0;
}
html,body{
height: 100%;
}
ul li{
overflow: hidden;
height: 150px;
}
ul li img{
float: left;
width: 120px;
}
</style>
<h1>标题</h1>
<ul id="list"></ul>
<script>
var arr1 =[
{
name: "哆啦A梦:大雄的宇宙小战争2021",
url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
},
{
name: "哆啦A梦:大雄的宇宙小战争2021",
url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
},
{
name: "哆啦A梦:大雄的宇宙小战争2021",
url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
},
{
name: "哆啦A梦:大雄的宇宙小战争2021",
url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
},
{
name: "哆啦A梦:大雄的宇宙小战争2021",
url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
},
{
name: "哆啦A梦:大雄的宇宙小战争2021",
url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
},
{
name: "哆啦A梦:大雄的宇宙小战争2021",
url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
},
{
name: "哆啦A梦:大雄的宇宙小战争2021",
url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
}
]
var arr2 =[
{
name: "哆啦A梦:大雄的宇宙小战争2021",
url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
},
{
name: "哆啦A梦:大雄的宇宙小战争2021",
url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
},
{
name: "哆啦A梦:大雄的宇宙小战争2021",
url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
},
{
name: "哆啦A梦:大雄的宇宙小战争2021",
url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
},
{
name: "哆啦A梦:大雄的宇宙小战争2021",
url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
},
{
name: "哆啦A梦:大雄的宇宙小战争2021",
url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
},
{
name: "哆啦A梦:大雄的宇宙小战争2021",
url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
},
{
name: "哆啦A梦:大雄的宇宙小战争2021",
url: "https://i.vzan.cc/zt/image/HomeImage/jpeg/2017/12/20/19530418efddd9eba34b789d4942c7d8a98b8d.jpeg?x-oss-process=image/resize,limit_0,m_fill,w_200,h_200/quality,q_100"
}
]
renderHTML(arr1)//因为函数声明都是会预读到前面,所以实际调用写在函数声明前也可以
function renderHTML(arr){
// list.innerHTML += arr.map//+=用作与下滑到底时叠加arr2,直接=会覆盖掉前面的
// (//映射出arr数组的每个元素,利用函数调用返回显示
// function(item){
// return `<li>
// <img src="${item.url}" alt="">
// <h3>${item.name}</h3>
// </li>`//将静态网页写的形式套用进来,要变的量写成${}形式在标签内
// }
// ).join("")//对映射部分的逗号起到消除作用
for(var i=0;i<arr.length;i++){//对上面代码的优化,可以在加载数据时不出现闪动
var oli = document.createElement("li")
oli.innerHTML = `<img src="${arr[i].url}" alt="">
<h3>${arr[i].name}</h3>`
list.appendChild(oli)
}
}
isLoading = false//用于触发到底了停止打印
window.onscroll = function()
{
// console.log("111111")
var listHeight = list.offsetHeight
var listTop = list.offsetTop
// console.log(listHeight+listTop)
var scrollTop = document.documentElement.scrollTop ||
document.body.scrollTop
var windowHeight = document.documentElement.clientHeight
if(isLoading) return
if((listHeight+listTop)-Math.round(windowHeight+scrollTop)<50)//快到底时触发
{
console.log("到底了")
isLoading = true
//渲染下一个数据
setTimeout(function(){//设置拉到底之后过段实际再加载数据
renderHTML(arr2)
isLoading = false//下一次到底事件再次触发
},1000
)
}
}
</script>
4.19 初识事件
一个事件由什么东西组成
触发谁的事件:事件源
触发什么事件:事件类型
触发以后做什么:事件处理函数
4.19.1 dom0 类型—但如果后面另外写了函数会覆盖前面的
<script>
var obox = document.querySelector('div')
obox.onclick = function () {}
// 谁来触发事件 => Div => 这个事件的事件源就是 Div
// 触发什么事件 => onclick => 这个事件类型就是 click事件
// 触发之后做什么 => function(){} => 这个事件的处理函数就会执行
</script>
我们想要在点击 div 以后做什么事情,就把我们要做的事情写在事件处理函数里面
<script>
var obox = document.querySelector('div')
obox.onclick = function () {
console.log('你点击了 div')
}
</script>
当我们点击 div 的时候,就会执行事件处理函数内部的代码
每点击一次,就会执行一次事件处理函数
419.1 dom2 类型—绑定多个事件处理函数按照顺序执行
一、addEventListener : 非 IE6 7 8下使用
语法: 元素.addEventListener(‘事件类型’, 事件处理函数, 冒泡还是捕获)
但是对IE6、7、8有兼容性问题
<div id="box2">bbbb</div>
<script>
box2.addEventListener("click",function(){
console.log("111111")
})
box2.addEventListener("click",function(){
console.log("222222")
})
box2.addEventListener("click",function(){
console.log("333333")
})
</script>
当点击 div 的时候,两个函数都会执行,并且会按照你注册的顺序执行
注意: 事件类型的时候不要写 on,点击事件就是 click,不是 onclick
二、attachEvent :IE 6 7 8 下使用(不推荐)
可以用attachEvent让IE兼容反应
<script>
box2.attachEvent("click",function(){
console.log("111111")
})
box2.attachEvent("click",function(){
console.log("2222222")
})
box2.attachEvent("click",function(){
console.log("3333333")
})
</script>
4.20 事件解绑
<button id="btn">抽奖</button>
<script>
btn.onclick = function () {
console.log("谢谢惠顾")
// console.log(this)
this.disabled = "disabled"
}
</script>
当点击抽奖时被禁用,但是可以在开发者工具中删除就能再次抽奖,为了防止这种情况,需要事件解绑
4.20.1 dom节点.onclick = null 赋值为空
上例修改
<script>
btn.onclick = function () {
console.log("谢谢惠顾")
this.onclick = null
}
</script>
点击之后无法再次修改
4.20.2 dom2类型 removeEventListener
上例修改,对同一对象使用removeEventListener值,需要用到 addEventListener 的方式添加事件
<script>
function handler(){
console.log("谢谢惠顾")
thie.removeEventListener("click",handler)
}
//在外部设置函数相当于设定了个函数钥匙,调用时就可以用多把这种钥匙来调用
btn.addEventListener("click",handler)
</script>
但是存在IE兼容性问题,可以使用detachEvent
<script>
function handler() {
console.log("谢谢惠顾" )
btn.detachEvent("onclick",handler)
}
btn.attachEvent("onclick",handler)
</script>
4.21 事件类型
常见的事件
我们在写页面的时候经常用到的一些事件
大致分为几类,浏览器事件 / 鼠标事件 / 键盘事件 / 表单事件 / 触摸事件
不需要都记住,但是大概要知道
4.21.1 鼠标事件
click :单击事件
dblclick :双击事件
contextmenu : 右键单击事件
mousedown :鼠标左键按下事件
mouseup :鼠标左键抬起事件
mousemove :鼠标移动在上方就触发
mouseover :鼠标移入事件
mouseout :鼠标移出事件
区别:
当盒子有父子关系时,mouseover和mouseout移入移出也会触发
而mouseenter和mouseleave则不会
mouseenter :鼠标移入事件
mouseleave :鼠标移出事件
4.21.2 键盘事件
keyup : 键盘抬起事件
keydown : 键盘按下事件
keypress : 键盘按下再抬起事件
4.21.3 焦点事件
focus:获取焦点事件
blur: 失去焦点事件
change 获取焦点和失去焦点的对比里面内容不一样才会触发
4.21.4 表单事件
change : 表单内容改变事件
input : 表单内容输入事件
submit : 表单提交事件
4.21.5 触摸事件(移动端)
touchstart : 触摸开始事件
touchend : 触摸结束事件
touchmove : 触摸移动事件
touchcancel: 正在触摸手机屏幕,突然有电话这种消息打来就会触发
4.21.5 浏览器事件
load : 页面全部资源加载完毕
scroll : 浏览器滚动的时候触发
4.22 事件对象
什么是事件对象?
就是当你触发了一个事件以后,对该事件的一些描述信息
例如:
你触发一个点击事件的时候,你点在哪个位置了,坐标是多少
你触发一个键盘事件的时候,你按的是哪个按钮
每一个事件都会有一个对应的对象来描述这些信息,我们就把这个对象叫做事件对象
浏览器给了我们一个 黑盒子,叫做 window.event,就是对事件信息的所有描述
比如点击事件
你点在了 0,0 位置,那么你得到的这个事件对象里面对应的就会有这个点位的属性
你点在了 10, 10 位置,那么你得到的这个事件对象里面对应的就会有这个点位的属性
odiv.onclick = function () {
console.log(e.X轴坐标点信息)
console.log(e.Y轴坐标点信息)
}
但是一般来说,好用的东西就会有兼容性问题
在 IE低版本 里面这个东西好用,但是在高版本IE 和 Chrome 里面不好使了
就得用另一种方式来获取 事件对象
在每一个事件处理函数的行参位置,默认第一个就是 事件对象
我们以后在每一个事件里面,想获取事件对象的时候,都用兼容写法
odiv.onclick = function (e) {
e = e || window.event
console.log(e.X轴坐标点信息)
console.log(e.Y轴坐标点信息)
}
4.23 事件对象鼠标事件
4.23.1 clientX和clientY 距离浏览器可视窗口的左上角的坐标值
相对于可视窗口
这里的可视窗口就是窗口的大小
4.23.2 pageX和pageY 距离页面文档流的左上角的坐标值
相对于整个文档的x和y
4.23.3 offsetX和offsetY 距离触发元素的左上角的坐标值
相对点击盒子左上角的位置
若大盒子包裹小盒子,点击小盒子,就会显示距离小盒子左上角的距离
4.24 鼠标跟随案例
<style>
* {
margin: 0;
padding: 0;
}
div {
width: 200px;
height: 50px;
background-color: yellow;
position: relative;
margin: 100px;
}
div p {
width: 300px;
height: 200px;
background-color: red;
position: absolute;
left: 100px;
top: 100px;
display: none;
pointer-events: none;
/* 鼠标事件穿透——可以让移动时不会出现抖动 */
z-index: 100;
}
</style>
<div id="box">
steve头像
<p>
steve介绍
</p>
</div>
<div>22222222</div>
<script>
box.onmouseover = function () {
this.firstElementChild.style.display = "block"//移入显出
}
box.onmouseout = function () {
this.firstElementChild.style.display = "none"//移开消失
}
box.onmousemove = function (evt) {//鼠标移动在上方触发
this.firstElementChild.style.left = evt.offsetX + "px"//让p标签距离父盒子box左上角贴合
this.firstElementChild.style.top = evt.offsetY + "px"
}
</script>
4.25 鼠标拖拽案例
方案一
<style>
* {
margin: 0;
padding: 0;
}
div {
width: 100px;
height: 100px;
background-color: skyblue;
position: absolute;
}
</style>
<div id="box"></div>
<script>
box.onmousedown = function () {
console.log("down")
//move放在down的处理函数中,可以让点击之后才触发跟随
document.onmousemove = function (evt) {//用document表示在浏览器窗口中跟随,用box的话只能在box中跟随
//用于鼠标移动时位于盒子中心
var x = evt.clientX - box.offsetWidth/2
var y = evt.clientY - box.offsetHeight/2
//设置无法超出可视窗口边界
if(y<=0)y=0
if(x<=0)x=0
if(x>=document.documentElement.clientWidth-box.offsetWidth)
x = document.documentElement.clientWidth-box.offsetWidth
if(y>=document.documentElement.clientHeight-box.offsetHeight)
y = document.documentElement.clientHeight-box.offsetHeight
//用于点击后能够移动盒子
box.style.left = x + "px"
box.style.top = y + "px"
}
}
box.onmouseup = function () {
console.log("up")
document.onmousemove = null //对松开抬起按键时进行解绑
}
</script>
方案二
<style>
* {
margin: 0;
padding: 0;
}
div {
width: 100px;
height: 100px;
background-color: skyblue;
position: absolute;
}
</style>
<div id="box"></div>
<script>
isDown = false
box.onmousedown = function () {
console.log("down")
isDown = true
//move放在down的处理函数中,可以让点击之后才触发跟随
box.onmouseup = function () {
console.log("up")
isDown = false
// document.onmousemove = null //对松开抬起按键时进行解绑
}
document.onmousemove = function (evt) {//用document表示在浏览器窗口中跟随,用box的话只能在box中跟随
if(!isDown) return
//用于鼠标移动时位于盒子中心
var x = evt.clientX - box.offsetWidth / 2
var y = evt.clientY - box.offsetHeight / 2
//设置无法超出可视窗口边界
if (y <= 0) y = 0
if (x <= 0) x = 0
if (x >= document.documentElement.clientWidth - box.offsetWidth)
x = document.documentElement.clientWidth - box.offsetWidth
if (y >= document.documentElement.clientHeight - box.offsetHeight)
y = document.documentElement.clientHeight - box.offsetHeight
//用于点击后能够移动盒子
box.style.left = x + "px"
box.style.top = y + "px"
}
}
</script>
4.26 DOM事件流
标准的dom事件流:
- 捕获: window=>docuemtn=> body= >outer
- 目标: inner
- 冒泡: outer= > body= >docuemnt= >window、
默认情况只在冒泡触发
按照dom2事件绑定,并进行配置才能看到捕获的回调函数被触发。
4.27 节点.stopPropagation() 阻止事件传播
拿动态删除举例
1.大部分浏览器
<ul id="list"></ul>
<script>
var arr = ["111", "2222", "333"]
for (var i = 0; i < arr.length; i++)
{
var oli = document.createElement("li")
//把按钮追加到li中
oli.innerHTML = arr[i]
var obutton = document.createElement("button")
// 再按钮里放内容
obutton.innerHTML = "delate"
// 将函数赋予点击属性
obutton.onclick = handlr
oli.appendChild(obutton)
oli.onclick = function(){
location.href = "http://www.baidu.com"
}//点击li部分会跳转,但是由于DOM事件传播影响点删除也会跳转
list.appendChild(oli)
}
function handlr(evt)
{
console.log(this.parentNode)
this.parentNode.remove()//利用this选择到点击的部分,如果没有parentNode则点击只会删除按钮不会删除li部分
//阻止事件传播
evt.stopPropagation()
}
</script>
2.IE的兼容性问题
function handlr(evt) 修改
function handlr(evt)
{
this.parentNode.parentNode.removeChild(this.parentNode)
//阻止事件传播
evt.cancelBubble = true
}
4.28 阻止默认行为
4.28.1 dom0 return 阻止默认行为
<script>
//dom0 return 阻止默认行为
document.oncontextmenu = function(){
console.log("右键单击,自定义右键菜单")
return false//阻止右键默认出现浏览器的菜单
}
</script>
4.28.2 dom2 evt.preventDefault
<script>
//dom2 evt.preventDefault
document.addEventistener ("contextmenu",function(evt){
console.log("右键单击,自定义右键菜单")
return false//阻止右键默认出现浏览器的菜单
})
</script>
4.29 自定义右键菜单案例
<style>
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
width: 200px;
padding: 10px;
border: 1px solid black;
display: none;
position: absolute;
}
ul li:hover {
background-color: skyblue;
}
</style>
<ul id="list">
<li class="aaa">111111</li>
<li class="bbb">222222</li>
<li class="ccc">333333</li>
</ul>
<script>
document.addEventListener("contextmenu",function(evt){
evt.preventDefault()
list.style.display = "block"
var x = evt.clientX
var y = evt.clientY
if(x>=document.documentElement.clientWidth-list.offsetWidth)
x = document.documentElement.clientWidth
if(x>=document.documentElement.clientHeight-list.offsetHeight)
x = document.documentElement.clientHeight
list.style.left = x + "px"
list.style.top = y + "px"
})
//加个左键单击事件消失
document.addEventListener(
"click",()=>{
list.style.display = "none"
}
)
</script>
4.30 事件委托
- 就是把我要做的事情委托给别人来做
- 因为我们的冒泡机制,点击子元素的时候,也会同步触发父元素的相同事件
- 所以我们就可以把子元素的事件委托给父元素来做
- 好处:
- 减少多个函数的绑定的性能损耗
动态添加li,也会有事件处理
4.30.1 target 表示点击的目标
- target这个属性是事件对象里面的属性,表示你点击的目标
- 当你触发点击事件的时候,你点击在哪个元素上,target 就是哪个元素
- 这个target也不兼容,在IE’下要使用srcElement
<ul id="list">
<li>
111111
<button>add</button>
</li>
</ul>
<script>
list.onclick = function (evt) {
console.log(evt.target || evt.srcElement)//IE才用后面的那个
}
</script>
当点击li就返回li,当点击按钮就返回按钮
动态删除采用委托
<ul id="list"></ul>
<script>
var arr = ["111", "2222", "333"]
for (var i = 0; i < arr.length; i++)
{
var oli = document.createElement("li")
//把按钮追加到li中
oli.innerHTML = arr[i]
var obutton = document.createElement("button")
// 再按钮里放内容
obutton.innerHTML = "delate"
// 将函数赋予点击属性
oli.appendChild(obutton)
list.appendChild(oli)
}
//给ul进行绑定,让父委托
list.onclick = function(evt){
console.log(evt.target.nodeName)
if(evt.target.nodeName==="BUTTON")
evt.target.parentNode.remove()
}
</script>