我写案例的时候遇到不少笨问题,仔细捋一遍之后其实就能理解了,当然更多的偏向于【瞎猜(就是文章里的内容不一定都是对的......)】,于是就打算自己做个文章给自己提个醒,如果有人能来纠错那我就能更进步一点,没有我就暂且当作是这样了。也不管描述名称什么的准不准了......
----------------------------------------
案例1:定时轮播图简单写法
问题(1) Uncaught DOMException: Failed to execute 'querySelector' on 'Document': '某元素(NaN)' is not a valid selector
如题,要做一个到时自动切换的轮播图。现在还不太熟练,只能一点点写,写到这里的时候总是报错“Failed to execute ...... not a valid selector”:
查了一堆问题,发现其实就是这里忘记写了......
正确写法:一定不要漏了后面的【.length】!
------------------
问题(2) 轮播图第一轮结束之后,会跳过第一张图片进行播放
其他部分ok了,接下来就要等轮播图播放到最后一张图的时候,使其直接回到第一张图片。
刚开始我用的是while循环,但执行了一轮之后,轮播图会从第四张图片直接跳到第二张图片。这个时候,我认为是while的问题:
后面看了老师的讲解思路,明白其实我还没有真正理解代码运行的逻辑,我的逻辑还是太死了......
我的思路:轮播图分别获取并播放了这些图片之后,在【最后】查看i是否已经轮到了数组最后一个对象,如果是,那么就回到i的初始值0,然后从第一张开始播放
(我理解的)实际上的思路:每次i自增完后,【立刻】看i是否满足while的条件,如果没满足,就接着往下;如果满足,就恢复i的值。
两种思路对我来说看着差不多,但while的所在位置是个关键。如果按照上图代码执行,那么就会有下一次播放跳过1.JPG的问题,这也是我的思路中忽略的点。
正确写法:i++后紧跟循环while ( i >= sliderData.length)
i++
while ( i >= sliderData.length) {
i = 0
}
......
运行逻辑:不满足while循环的条件时,正常运行;当 i = 4 时,进入while循环,将i的值恢复为0,然后跳出循环,执行下方代码;由于这时 i = 0 ,下方代码运行无误;li获取的是nth-child(${ i + 1}),所以也不会报错,其实就跟最开始进入定时器的时候一样。这样就能实现无缝循环简单轮播图,执行步骤如下:
![](https://i-blog.csdnimg.cn/blog_migrate/e93d2b77c3e205ae26f9399b276ed68d.png)
第一步:
let i = 0
进入定时器
第二步:
第一张图本身就是页面里写好正在播放的,所以让计时器直接从第二张图片开始切换就好。
i++ (这时 i = 1 )
由于 i 的值为1,不满足while循环条件,不进入循环 × 继续往下执行
接下来【img】、【p】和【li】就会分别按照它们的代码获取相应的内容,也就是会获取并播放:
sliderData[1].url (选择数组中第二个对象,下标为1,即2.JPG)
sliderData[1].title (选择数组中第二个对象,下标为1,即替换文字2)
li则选择了第【nth-child(${ i + 1})】个li,其实就代表【nth-child(2)】,也就是第二个圆点li
...
第...步:
i++ (此时 i = 4,轮播图已经播放到了数组对象中的最后一张图片)
满足条件,进入循环
i的值为0
第二次循环不满足条件
跳出循环,继续往下执行
第二轮开始,获取了数组中下标为0的第一个对象
获取了 第0 + 1个li,添加属性
...
如此循环下去。
-----------
※我理解的为什么while循环的条件不能是【 i == sliderData.length - 1】且不能放到末尾,错误代码执行步骤如下:
第一步:
let i = 0 (变量i最初始的值,在下文会以同样形式表现)
进入计时器
第二步:
代码执行了i++,那么此时【 i = 1 】
获取了数组中下标为1 的第二个对象
获取了 第1 + 1个li,添加属性
执行完给li增加属性这一行代码后,代码会查看当前是否满足进入while的条件,发现并不满足 i == sliderData.length - 1,就会跳过,然后返回执行第二步中的代码;
第三步同理,然后往下运行...
直到第n步,变量i自增到3:
i = 3,此时的轮播图已经获取到了sliderData中的最后一个对象,正在播放:
sliderData[3].url (选择数组中第四个对象,下标为3,即4.JPG)
sliderData[3].title (选择数组中第四个对象,下标为3,即替换文字4)
li:nth-child(3+ 1)
按照我原本的思路,这里应该进入了while,恢复了i的值之后,从1.JPG开始重新轮播。实际上人家是:
此时,i满足了条件( 3 == 4 - 1),进入了while,将i恢复为了0:
之后又执行了一次while,此处的i已经不满足条件了,跳出循环,重新执行计时器内代码。
关键来了!由于代码回到了第一行i++,但是这个时候i的值是0,执行了i++以后,i的值就是1,这就导致代码获取了数组的第二个对象,下标为1,也就是重新开始执行第二步的代码:
步骤如上。所以while循环直接放在i++后,每次自增完查当前是否满足while循环的条件是最好的。其他的写法我就暂时想不出来了。
--------------------------------------
案例2:点击按钮随机抽取问题
问题(1) 疑似没有成功获取随机数random,导致控制台输出同一个问题
我需要做出一个能够实现点击抽取问题的案例,起初,我的代码思路是这样的:
运行之后,我发现代码并没有获取到随机数,导致输出同一个问题:
解决的办法很简单,把random移到“里面”去就是了......说实话我理解了但不多,但我猜想是这样才能触发抽取随机数这个代码?
![](https://i-blog.csdnimg.cn/blog_migrate/da6aac7903aed461cf9f1f9173f4c594.png)
![](https://i-blog.csdnimg.cn/blog_migrate/c1b6254f2a94be60fe74677eb2dc35ec.png)
-----------------------------------
案例3:用户输入评论并按下回车发布,且实现字数统计功能
问题(1) 无法正常显示用户发布的评论(高亮!此案例中说的不一定就是真正的代码错误原因!!!纯属本人瞎想,还请大佬指正)
![](https://i-blog.csdnimg.cn/blog_migrate/16e557efd39c2b57451e3532f660bd6d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/cf4b7c2063bc5c0b5b0ee76a70cb9ba6.png)
经过不严谨的测试,我认为问题出在框出来的部分:
![](https://i-blog.csdnimg.cn/blog_migrate/0b59a33c2ada227ccfc41845acc92a6e.png)
为了进一步了解原因,我做了个不算测试的测试。
首先,我把keyup事件单独拿出来写到下面,然后在input事件里加了一条【usrCom.innerHTML = input.value】
![](https://i-blog.csdnimg.cn/blog_migrate/12b591f8f11f51f2cb0c485638dcc9a9.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ab965915eb32d7d6b0d816790d1cf015.png)
![](https://i-blog.csdnimg.cn/blog_migrate/cf4b7c2063bc5c0b5b0ee76a70cb9ba6.png)
可以看到这里错误代码1和错误代码2的显示结果是一样的,所以我暂时认为错误代码1的问题就在于获取用户评论的值的时候,输入框中用户的评论已经被清空为空字符串【''】,所以无法正常显示。
正确写法:
![](https://i-blog.csdnimg.cn/blog_migrate/71a4de1150e092e7f575c535b61eed5b.png)
--------------------
案例4:电梯导航
问题(1) 点击电梯导航能够正常跳转,但电梯样式显示异常
如图,电梯导航效果如下,效果包括:
- 网页滚动一定高度后,顶部导航栏与电梯导航出现;
- 网页滚动到某一部分后,电梯导航随之改变颜色样式;
- 点击电梯导航,可以跳转到某一部分;
- 点击返回顶部,可回到网页最顶部。
但是代码写到七七八八的时候,出bug了。当时的问题是,电梯导航正常跳转,但是样式不会改变:电梯导航中,只有“部分1”和“部分3”会改变颜色,“部分2”和“部分4”不会改变。我排查了半天的原因,最后因为一个不小心更改了某行代码的符号,发现bug不见了,电梯导航正常运行了......
![](https://i-blog.csdnimg.cn/blog_migrate/b1d7c4ff98a5fe24fce6ba17190c52c4.png)
解决办法:如果有人也遇到了差不多的问题,觉得自己的代码逻辑又没有问题,试试改一些符号,可能就可以了......
------------------
问题(2) 注意属性是否只读/可加减
电梯导航中,我想实现页面滚动到一定高度后,导航栏自动出现,但实际上这样会遮住一部分盒子内容。于是,我就改成:页面滚动到一定高度后,导航栏自动出现且不遮挡盒子内容。
我的写法:
window.addEventListener('scroll', function () {
导航栏.style.top = 页面滚动高度document.documentElement.scrollTop + 导航栏.offsetHeight >=第一个内容盒子.offsetTop ? 0 : '-100px'
......
转化一下就是页面滚了一定高度,还剩下一个导航栏的高度的时候,这时两个相加就相当于版心.offsetHeight(也就是第一个内容盒子.offsetTop:离版心顶部有多少远),那么导航栏“咻”出现,这样就不会挡住盒子1的内容。
虽然这里的部分属性是只读,但是它可以和可读写的属性相加减,反正可读的意思就是可以拿来用嘛。
--------------------
案例5:注册页面表单验证
问题(1) 提交表单后在循环中清空“正确”类名,但没有正确清空,部分清空了,部分没有
今天写注册页面这个案例,写到最后提交表单事件后,发现类名替换出了问题。
![](https://i-blog.csdnimg.cn/blog_migrate/a582bc601bc424578caeb84c998b96cf.png)
![](https://i-blog.csdnimg.cn/blog_migrate/4e15d04d56c6950dee496b2b61137d62.png)
其实问题很简单,把i的值和document.querySelectorAll('.right').length单独拿出来,就知道为什么了。
错误代码运行过程:
第一次循环,此时right集合数组长度为5,i为0:
把数组第一个内容和类名都换掉;
i++;
第二次循环,注意!由于这里获取的是right类名集合的数组,但是你第一次循环中已经把第一个盒子的类名去掉了,那这个时候,数组的长度是4,i已经自增到1了,循环还在继续:
咦,第一个没有类名的元素早就不在数组里了,那我就把现有数组的第二个元素,原有数组的第三个元素的类名去掉。第二个元素就很可怜地被跳过了。因为这时的数组第一个元素是手机号码,而不是用户名称。用户名称被踢出数组了。
![](https://i-blog.csdnimg.cn/blog_migrate/80a5269f5f05a5895e1d449843816b6d.png)
之后的循环同理,重复数组里踢一个,i自增一次,然后跳过一个元素......
解决方法:声明一个变量存放有这些类名的数组。
数组长度固定的话,就不会有这个悲剧出现了。
------------------
问题(2) 定时器内使元素文本包含倒计时,但只减了1秒
页面中要实现“发送验证码”功能,其实就是点击后开启倒计时,“倒计时结束后更改文本为重新发送验证码”。但我开启了计时器后,出现了标题所说的问题。
遇到这个问题的话,务必注意一下你的i变量是否在定时器内声明的。
比如倒计时五秒,let i = 5,然后进行i--一系列操作,但是定时器每调用一次就执行一次let i = 5,i就一直等于4,这就是问题所在。
解决方法:在定时器外声明变量i。
------------------
问题(3)定时器慢一秒
同样是在“发送验证码”模块,当我开启定时器后,发现它延迟了一秒才开。
注意你的代码是不是类似于这种写法:
![](https://i-blog.csdnimg.cn/blog_migrate/1b06a1fb6a34580636393f581a974d0f.png)
注意代码的执行顺序!!!当执行到第三个log时,要等这一句话都执行完毕,i才会执行自增。也就是说,开启定时器的第一秒,你以为它执行了i--,此时的文本就是“4秒后...”,其实要等这句话结束了,它才会执行,因此在这句话的时候,i的值还是5。
解决方法:先执行i--,再把i自减后的值加到文本里。
--------------------
案例6:电商网站-包括图片切换、查看商品细节(图片放大)
问题(1) 鼠标移动到盒子边框或者打开调试台(F12)遮罩层才能出现
简单来说就是标题那样......录不了屏,大概描述下。
![](https://i-blog.csdnimg.cn/blog_migrate/4cddf2cf0050e4689af8f5cea94fb570.png)
解决办法:mouseout改成mouseleave,我也不知道为啥这样......但这样是可以的。