01-事件冒泡原理
<style>
.box {
width: 200px;
height: 200px;
background-color: pink;
position: relative;
}
.son {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
left: 300px;
top: 200px;
}
</style>
</head>
<body>
<div class="box">
<div class="son"></div>
</div>
<script>
// 给box和son都添加点击事件
document.querySelector('.box').onclick = function () {
alert('box被点击了')
console.log('box被点击了')
}
document.querySelector('.son').onclick = function () {
alert('son被点击了')
console.log('son被点击了')
}
// son元素被点击后:会执行自己的点击事件
// 等结束了,会找父元素box,也触发点击事件
// 冒泡的顶级是:window
window.onclick = function () {
console.log('再来一次的冒泡')
}
</script>
</body>
注意:
1.冒泡的顶级是:window
2.此案例给box和son都添加点击事件,但是son元素被点击后:会执行自己的点击事件。 等结束了,会找父元素box,也触发点击事件
02-事件冒泡-阻止冒泡e.stopPropagation()
-点击登录框案例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.login-header {
width: 100%;
text-align: center;
height: 30px;
font-size: 24px;
line-height: 30px;
}
html,
body,
ul,
li,
ol,
dl,
dt,
dd,
div,
p,
span,
h1,
h2,
h3,
h4,
h5,
h6,
a {
padding: 0px;
margin: 0px;
}
.login {
width: 512px;
position: absolute;
border: #ebebeb solid 1px;
height: 280px;
left: 50%;
right: 50%;
background: #ffffff;
box-shadow: 0px 0px 20px #ddd;
z-index: 9999;
margin-left: -256px;
margin-top: 140px;
display: none;
}
.login-title {
width: 100%;
margin: 10px 0px 0px 0px;
text-align: center;
line-height: 40px;
height: 40px;
font-size: 18px;
position: relative;
cursor: move;
}
.login-input-content {
margin-top: 20px;
}
.login-button {
width: 50%;
margin: 30px auto 0px auto;
line-height: 40px;
font-size: 14px;
border: #ebebeb 1px solid;
text-align: center;
}
.login-bg {
width: 100%;
height: 100%;
position: fixed;
top: 0px;
left: 0px;
background: #000000;
opacity: 0.3;
display: none;
}
a {
text-decoration: none;
color: #000000;
}
.login-button a {
display: block;
}
.login-input input.list-input {
float: left;
line-height: 35px;
height: 35px;
width: 350px;
border: #ebebeb 1px solid;
text-indent: 5px;
}
.login-input {
overflow: hidden;
margin: 0px 0px 20px 0px;
}
.login-input label {
float: left;
width: 90px;
padding-right: 10px;
text-align: right;
line-height: 35px;
height: 35px;
font-size: 14px;
}
.login-title span {
position: absolute;
font-size: 12px;
right: -20px;
top: -30px;
background: #ffffff;
border: #ebebeb solid 1px;
width: 40px;
height: 40px;
border-radius: 20px;
}
</style>
</head>
<body>
<div class="login-header">
<a href="javascript:void(0);">点击,弹出登录框</a>
</div>
<div class="login">
<div class="login-title">登录会员
<span>
<a href="javascript:void(0);" class="close-login"> 关闭</a>
</span>
</div>
<div class="login-input-content">
<div class="login-input">
<label>用户名:</label>
<input type="text" placeholder="请输入用户名" name="info[username]" class="list-input">
</div>
<div class="login-input">
<label>登录密码:</label>
<input type="password" placeholder="请输入登录密码" name="info[password]" class="list-input">
</div>
</div>
<div class="login-button"><a href="javascript:void(0);" id="login-button-submit">登录会员</a></div>
</div>
<div class="login-bg"></div>
<script>
// 需求1:点击弹出登录框链接,显示登录框和背景
// a增加点击事件
document.querySelector('.login-header a').onclick = function (e) {
document.querySelector('.login').style.display = 'block'
document.querySelector('.login-bg').style.display = 'block'
// 由于a链接与document是父子关系:产生了点击事件的冒泡事件
// 刚好做的事情相反:点a链接没有了显示的效果(父元素document把a元素的效果给覆盖掉了)
// 阻止冒泡
e.stopPropagation()
}
// 需求2:点击页面的空白处,隐藏登录框和背景
// 空白处:document或者window对象
document.onclick = function () {
document.querySelector('.login').style.display = ''
document.querySelector('.login-bg').style.display = ''
}
// 不希望点击登录框产生冒泡:专门加一个阻止冒泡的点击事件
document.querySelector('.login').onclick = function (e) {
e.stopPropagation()
}
</script>
</body>
</html>
注意:
1.冒泡是父子级关系,从下往上逐级。
2.去除冒泡影响可以加阻止冒泡事件:e.stopPropagation()
03-事件冒泡-事件委托
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
// 入口事件(加载事件)
window.onload = function () {
// 老做法:获取所有li,然后遍历绑定事件
// 新做法:给父元素ul绑定事件
let ul = document.querySelector('ul')
ul.onmouseover = function (e) {
// 事件对象中:会记录事件发生的最底层的元素(最小的孩子)
console.log(e.target)
// 如何区分:目标的真的是li呢?
// 如果区分一个元素是li标签还是ul?
// 节点都有三要素:nodeType(ul和li都一样:1),nodeValue(ul和li都一样:null),nodeName(大写表签名)
console.log(e.target.nodeName)
if (e.target.nodeName == 'LI') {
e.target.style.backgroundColor = 'green'
}
// 事件委托:减少子元素绑定事件的次数
// 提升浏览器的解析性能(代码量也会减少)
}
ul.onmouseout = function (e) {
// console.log(2)
e.target.style.backgroundColor = ''
}
}
</script>
</head>
<body>
<ul>
<li>隔壁老王1</li>
<li>隔壁老王2</li>
<li>隔壁老王3</li>
<li>隔壁老王4</li>
<li>隔壁老王5</li>
<li>隔壁老王6</li>
<li>隔壁老王7</li>
<li>隔壁老王8</li>
<li>隔壁老王9</li>
<li>隔壁老王10</li>
<li>隔壁老王11</li>
<li>隔壁老王12</li>
<li>隔壁老王13</li>
<li>隔壁老王14</li>
<li>隔壁老王15</li>
<li>隔壁老王16</li>
<li>隔壁老王17</li>
<li>隔壁老王18</li>
<li>隔壁老王19</li>
<li>隔壁老王20</li>
<li>隔壁老王21</li>
<li>隔壁老王22</li>
<li>隔壁老王23</li>
<li>隔壁老王24</li>
<li>隔壁老王25</li>
<li>隔壁老王26</li>
<li>隔壁老王27</li>
<li>隔壁老王28</li>
<li>隔壁老王29</li>
<li>隔壁老王30</li>
<li>隔壁老王31</li>
<li>隔壁老王32</li>
<li>隔壁老王33</li>
<li>隔壁老王34</li>
<li>隔壁老王35</li>
<li>隔壁老王36</li>
<li>隔壁老王37</li>
<li>隔壁老王38</li>
<li>隔壁老王39</li>
<li>隔壁老王40</li>
<li>隔壁老王41</li>
<li>隔壁老王42</li>
<li>隔壁老王43</li>
<li>隔壁老王44</li>
<li>隔壁老王45</li>
<li>隔壁老王46</li>
<li>隔壁老王47</li>
<li>隔壁老王48</li>
<li>隔壁老王49</li>
<li>隔壁老王50</li>
<li>隔壁老王51</li>
<li>隔壁老王52</li>
<li>隔壁老王53</li>
<li>隔壁老王54</li>
<li>隔壁老王55</li>
<li>隔壁老王56</li>
<li>隔壁老王57</li>
<li>隔壁老王58</li>
<li>隔壁老王59</li>
<li>隔壁老王60</li>
<li>隔壁老王61</li>
<li>隔壁老王62</li>
<li>隔壁老王63</li>
<li>隔壁老王64</li>
<li>隔壁老王65</li>
<li>隔壁老王66</li>
<li>隔壁老王67</li>
<li>隔壁老王68</li>
<li>隔壁老王69</li>
<li>隔壁老王70</li>
<li>隔壁老王71</li>
<li>隔壁老王72</li>
<li>隔壁老王73</li>
<li>隔壁老王74</li>
<li>隔壁老王75</li>
<li>隔壁老王76</li>
<li>隔壁老王77</li>
<li>隔壁老王78</li>
<li>隔壁老王79</li>
<li>隔壁老王80</li>
<li>隔壁老王81</li>
<li>隔壁老王82</li>
<li>隔壁老王83</li>
<li>隔壁老王84</li>
<li>隔壁老王85</li>
<li>隔壁老王86</li>
<li>隔壁老王87</li>
<li>隔壁老王88</li>
<li>隔壁老王89</li>
<li>隔壁老王90</li>
<li>隔壁老王91</li>
<li>隔壁老王92</li>
<li>隔壁老王93</li>
<li>隔壁老王94</li>
<li>隔壁老王95</li>
<li>隔壁老王96</li>
<li>隔壁老王97</li>
<li>隔壁老王98</li>
<li>隔壁老王99</li>
<li>隔壁老王100</li>
</ul>
</body>
</html>
注意:
1.利用节点都有三要素:nodeType(ul和li都一样:1),nodeValue(ul和li都一样:null),nodeName(大写表签名)
2.父级绑定事件。但是注意适用于部分标签。