刚刚走完JavaScript阶段,感觉挺爽的。但在总结的时候,我发现一些在做网页中容易错的地方,还有一些比较重要的方面。为了避免其他人在这一阶段也遇到这些问题。我今天就着重说一下在JavaScript这一阶段我容易出现的问题,从而让大家在遇到相同问题的时候可以快速解决。
一.盒子覆盖问题
只要我们做网页总会发生盒子覆盖的问题。我们在下HTML样式的时候没有注意各个盒子的层级关系,导致一些上层盒子放在了下面。当我们在 js 中通过document来获取盒子进行一些操作如:点击事件。
var boy = document.querySelector('.boy');
boy.addEventListener('click', function() {
boy.style.background="red"
})
我们获取到盒子后对它注册点击事件,点击后,盒子的背景颜色变成红色。但如果这个 boy 的盒子被其他盒子覆盖,我们及时获得盒子并注册点击事件也不能对它进行我们想要的操作。解决的办法就是提升这个盒子的层级,让我们的鼠标可以点击到我们注册监听的盒子。这一部分容易被大家遗忘,如果出现使用js获取某一元素但不能进行想要的操作的时候,我们可以检查一下自己的盒子的层级关系。
二.var 和 let 的正确使用
我们走JavaScript这一阶段的时候var和let的区别与联系一定要理解透彻,否则在使用的时候就容易出现一个错误。
相似点:
局部变量:在函数体内使用 var 和 let 关键字声明的变量有点类似。它们的作用域都是 局部的: 全局变量:在函数体内或则代码块外使用 var 和 let 关键字声明的变量有点类似。它们的作用域都是 全局的:
不同点:
1.在 HTML 中, 全局作用域是针对 window 对象。使用 var 关键字声明的全局作用域变量属于 window 对象:使用 let 关键字声明的全局作用域变量不属于 window 对象: 2. 在相同的作用域或块级作用域中,不能使用 let 关键字来重置 var 关键字声明的变量,var可以重置var关键紫的变量。
<!DOCTYPE html>
<html lang="en">
<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>
</head>
<body>
<h2>使用 var 声明变量</h2>
<p id="demo"></p>
<script>
var x = 10;
// 这里输出 x 为 10
{
var x = 2;
// 这里输出 x 为 2
}
// 这里输出 x 为 2
document.getElementById("demo").innerHTML = x;
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<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>
</head>
<body>
<h2>使用 let 声明变量</h2>
<p id="demo"></p>
<script>
var x = 10;
// 这里输出 x 为 10
{
let x = 2;
// 这里输出 x 为 2
}
// 这里输出 x 为 10
document.getElementById("demo").innerHTML = x;
</script>
</body>
</html>
- 在相同的作用域或块级作用域中,不能使用 let 关键字来重置 let 关键字声明的变量: 在相同的作用域或块级作用域中,不能使用 var 关键字来重置 let 关键字声明的变量: let 关键字在不同作用域,或不同块级作用域中是可以重新声明赋值的:
<h2>JavaScript let</h2>
<p id="demo"></p>
<script>
var i = 5;
for (let i = 0; i < 10; i++) { // 使用 let 关键字, 它声明的变量作用域只在循环体内,循环体外的变量不受影响。
// 一些代码...
}
//这里输出的是 10;
document.getElementById("demo").innerHTML = i;
</script>
<h2>JavaScript let</h2>
<p id="demo"></p>
<script>
var i = 5;
for (let i = 0; i < 10; i++) { // 使用 let 关键字, 它声明的变量作用域只在循环体内,循环体外的变量不受影响。
// 一些代码...
}
//这里输出的是 10;
document.getElementById("demo").innerHTML = i;
</script>
三.DOM 事件流 三个阶段
1.JS 代码中只能执行捕获或则冒泡其中的一个阶段; 2.像onclick 和 attachEvent(ie) 这些事件只能得到冒泡阶段。
DOM事件流
1.事件流描述的是从页面中接受时间的顺序; 2.事件发生时会在元素节点之间按照特定的顺序传播 这个传播的过程即DOM事件流。
比如我们给一个div注册一个点击事件: 1.捕获阶段 2.当前目标阶段 3.冒泡阶段
冒泡事件:IE最早提出的,事件开始的时候由最具体的元素进行接收,然后逐级向上传播到DOM最顶层节点的过程。
事件捕获:网景最早提出,由DOM最顶层的节点开始,然后逐级往下传播到最具体的元素接受的过程。
我们可以这样理解:我们向水里扔一块石头,首先它会有一个下降的过程,这个过程就可以理解为从顶层向事件发生的最具体元素(目标点)的捕获过程;之后会产生泡泡,会在最低点(最具体元素)之后漂浮到水面上,这个过程就相当于事件冒泡。
我们可以通过代码来更深了解捕获阶段和冒泡阶段:
<!DOCTYPE html>
<html lang="en">
<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>
</head>
<body>
<div class="father">
父亲
<div class="son">儿子</div>
</div>
<script>
// 3.捕获阶段 如addEventLister 第三个参数是 true 那么则处于捕获阶段 document ->HTML->body->father->son
var son = document.querySelector('.son');
var father = document.querySelector('.father');
son.addEventListener('click', function() {
alert("son");
}, true);
father.addEventListener('click', function() {
alert("father");
}, true);
// 4.冒泡阶段 如addEventLister 第三个参数是 false 那么则处于冒泡阶段 son->father->body->HTML-> documentson
var son = document.querySelector('.son');
var father = document.querySelector('.father');
son.addEventListener('click', function(e) {
alert("son");
// e.stopPropagation();
}, false);
father.addEventListener('click', function(e) {
alert("father");
}, false);
document.addEventListener('click', function(e) {
alert("document");
}, false);
</script>
</body>
</html>
根据上面的代码我进行展开解释:
我们写一个father盒子,然后在father盒子里面写一个son盒子;给两个盒子都注册点击监听事件,当点击相对应的盒子的时候,弹出对应盒子的警告框。
addEventLister 第三个参数是 true 那么则处于捕获阶段,addEventLister 第三个参数是 false 那么则处于冒泡阶段。
我们先将第三个参数写成true处于捕获阶段,来看一下捕获阶段的事件流。当我们只执行捕获阶段时,我们执行代码点击son盒子。我们发现第一个出现的是father的警告框,然后才是son的警告框。这一阶段就是捕获阶段。
然后我们在将第三个参数改成false处于冒泡阶段,来看一下冒泡阶段的事件流。当我们只执行冒泡阶段,我们执行代码块点击son盒子。son盒子的警告框弹出,然后是father和document的警告框。这一阶段就是冒泡阶段。
解决冒泡的的方法:
冒泡事件常会导致一些其他的问题,如:我对网页中的某一模块进行滚轮监听,然后我的整个网页也有一个滚轮监听,当我对某一模块进行滚轮事件的之后页面也在进行滚轮事件。对网页的制作有很大的影响,这个时候我们就要想一下解决方法了。其实解决的办法很简单,该属性阻止冒泡即可。通常我们做项目话都会使用
e.stopPropagation();
来阻止某一阶段的冒泡阶段,如我上面的冒泡阶段写的阻止son的冒泡。但只是阻止了son的冒泡,如果我点击father盒子出现警示框之后document的警示框还是会出来。所以大家在使用的时候要注意。它还有一个弊端就是不适应ie6-ie8的浏览器。如果你想考虑兼容性可以加上
e.cancelBubble;
来取消冒泡。 注意: 1.实际开发中我们很少使用事件捕获,我们更加关注事件冒泡。 2.有些事件是没有冒泡的。比如:onblur, onfocus,onmouseenter,onmouseleave 3.事件冒泡有时候会带来麻烦,有时候又会很有帮助巧妙地做某些事。
这就是我走完JavaScript阶段后认为比较重要的三点。大家可以参考一下。如果有错误,希望大家之处。我们一起进步。中间有不懂得地方可以留言。我看后回应。
标签:盒子,--,JavaScript,son,作用域,let,冒泡,var From: https://blog.51cto.com/u_16191822/7325445