JS 常用知识点整理记录、Demo
1.getBoundingClientRect()
2.获得鼠标的位置信息
1 |
|
3.防抖
原理:
每次点击或滚动,都重新创建一个计时器,重新开始计时
1 | // 2、防抖功能函数,接受传参 |
防抖库—underscore.js-debounce(_.debounce(function, wait, [immediate]))
4.节流
节流定时器写法:
1 | // 2、节流函数体 |
防抖和节流对比
函数防抖(debounce)
概念: 在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
生活中的实例: 如果有人进电梯(触发事件),那电梯将在10秒钟后出发(执行事件监听器),这时如果又有人进电梯了(在10秒内再次触发该事件),我们又得等10秒再出发(重新计时)。
函数节流(throttle)
概念: 规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。
生活中的实例: 我们知道目前的一种说法是当 1 秒内连续播放 24 张以上的图片时,在人眼的视觉中就会形成一个连贯的动画,所以在电影的播放(以前是,现在不知道)中基本是以每秒 24 张的速度播放的,为什么不 100 张或更多是因为 24 张就可以满足人类视觉需求的时候,100 张就会显得很浪费资源。
应用场景
对于函数防抖,有以下几种应用场景:
- 给按钮加函数防抖防止表单多次提交。
- 对于输入框连续输入进行AJAX验证时,用函数防抖能有效减少请求次数。
- 判断
scroll
是否滑到底部,滚动事件
+函数防抖
总的来说,适合多次事件一次响应的情况
对于函数节流,有如下几个场景:
- 游戏中的刷新率
- DOM元素拖拽
- Canvas画笔功能
总的来说,适合大量事件按时间做平均分配触发。
源码
函数防抖:
1 | function debounce(fn, wait) { |
之所以返回一个函数,因为防抖本身更像是一个函数修饰,所以就做了一次函数柯里化。里面也用到了闭包,闭包的变量是timer
。
函数节流—时间戳写法
1 | function throttle(fn, gapTime) { |
如图是实现的一个简单的函数节流,结果是一秒打出一次boom
小结
函数防抖和函数节流是在时间轴上控制函数的执行次数。防抖可以类比为电梯不断上乘客
,节流可以看做幻灯片限制频率播放电影
。
节流库—underscore.js-throttle(_.throttle(function, wait, [options]))
5.懒加载
JavaScript 类数组对象
类数组对象转数组有两种花方法
方法一:Array.from
方法二:Array.prototype.slice.call
1️⃣转换
如果类数组对象需要转化为数组,可以用 Array.prototype.slice.call
1 | var foo = { |
第一, foo
本来是没有 slice
方法的, Array.prototype.slice.call(foo)
这个表达式相当于赋予 foo
这个对象 slice
方法。
第二, Array.prototype.slice.call(foo);
相当于 Array.prototype.slice.call(foo, 0);
是把取一个数组(或者类数组)的子集,并作为一个数组返回。所以当后面的作用对象是一个类数组时,就会把这个类数组对象转换为了一个新的数组。
2️⃣特性
类数组只有索引值和长度,没有数组的各种方法,所以如果要类数组调用数组的方法,就需要使用 Array.prototype.method.call
来实现。
例如,如果遍历一个类数组,可以这样实现:
1 | Array.prototype.forEach.call(foo, function(item){ |
添加一个元素
1 | Array.prototype.push.call(foo, 'PHP'); |
总结:
call,apply,bind的本质是给对象添加一个新的方法,让这个对象能够调用这个方法
懒加载原理
懒加载也叫延迟加载,指的是在长网页中延迟加载图像,是一种很好优化网页性能的方式。用户滚动到它们之前,可视区域外的图像不会加载。这与图像预加载相反,在长网页上使用延迟加载将使网页加载更快。在某些情况下,它还可以帮助减少服务器负载。常适用图片很多,页面很长的电商网站场景中。
将页面上的图片的 src 属性设为空字符串,而图片的真实路径则设置在data-original属性中
当页面滚动的时候需要去监听scroll事件,在scroll事件的回调中,判断我们的懒加载的图片是否进入可视区域
- 如果图片在可视区内,将图片的 src 属性设置为data-original 的值,这样就可以实现延迟加载
- 如果图片不在可视区不做处理
1 | <img src="" class="image-item" lazyload="true" data-original="images/12.png"/> |
1 | //获取可视区高度,documentElement表示html元素 |
问题:为什么要新建一个img对象
6.无缝滚动——scrollTop/srollLeft
element.scrollLeft;滚动条到元素左边的距离
实现的无缝滚动,有两种基本的思想:
第一种:通过父元素的scrollLeft/scrollTop逐渐增加来实现;
第二种:通过css3的translate来实现,这里采用的第二种;
滚动动画实现:主要运用animation动画:
1 | @keyframes move{ |
这里100%的时候移动的距离是你一次性想要展示的所有图片的宽度,并不是ul的宽度;
(1)方法一:当滚动到末尾,将scrollLeft设为0
(2)方法二:利用两个内容相同的div,当第一个div消失,立即让第一个div的scrollLeft为0,由于有第二个一模一样的内容,所以看起来是连续的
这里有两个div,所以当wrap.scrollLeft >= startWidth时,第一个div完全移动到框外,视图区为第二个div,此时再移#回到第一个div
(3)实例三在实例二的基础上进行了部分改进,原理相同
7.无缝滚动插件——seamless-scroll
注:这是一个轻量级的小插件,非常适用于跑马灯等要求不高的无缝滚动,cdn有点问题,可以将插件的js**下载到本地使用
8.百度索索建议API
1️⃣直接返回json数据
http://suggestion.baidu.com/?wd=关键词&action=opensearch
2️⃣json数据当做回调函数的参数传回来
http://suggestion.baidu.com/?wd=关键词
默认回调函数名是window.baidu.sug
等价于
http://suggestion.baidu.com/?wd=关键词&cb=window.baidu.sug
3️⃣http://suggestion.baidu.com/?wd=关键词&cb=自定义函数名
遇到的问题:
1 | fetch('http://suggestion.baidu.com/?wd='+this.value+'&action=opensearch', |
后台服务器没设cors,mode=”cors”,会报错。
这个时候,你 fetch 改成了mode=’no-cors’ 表示不垮域,可以请求成功,单你拿不到服务器返回数据,它被标记了’opaque’,network是有请求成功的记录
针对跨域请求,cors模式是常见跨域请求实现,但是fetch自带的no-cors跨域请求模式则较为陌生,该模式有一个比较明显的特点:
该模式允许浏览器发送本次跨域请求,但是不能访问响应返回的内容,这也是其response type为opaque透明的原因。
也就是说,这个接口后台不支持跨域请求
解决:其他跨域方法
方法一:jsonp,success
bug1:定义jsonp方法时,传到参数对象中的回调函数的属性名必须是cb(这个例子必须是)
bug2:调用jsonp方法时,传给回调函数代表的属性名的属性值必须是一个字符串
Bug3:批量插入多个元素时,用字符串拼接的方法,只在最后插入一次
方法二:nginx反向代理(这个只适合测试页面,实际项目中不可能启动一个nginx)
原理:通过nginx配置一个代理服务器,域名与本地相同,端口不同,设置为允许跨域,本地访问代理服务器,代理服务器访问要访问的地址。因为跨域是请求结果被浏览器拦截,不是请求失败,所以用服务器发起请求就不会被拦截,服务器接受到请求结果再把结果传给本地请求即可
安装nginx:brew install nginx
配置文件地址: /usr/local/etc/nginx/nginx.conf
启动nginx:nginx
重新启动: nginx -s reload
测试nginx语法是否错误:nginx -t
关闭nginx: nginx -s stop
bug:配置nginx时,server_name可以是自定义的域名,可以是127.0.0.1,就是不能是localhost
9.秒表计时器
注意:(1)开始计时器要加清浮动,否则每次点击都会创建一个新的计时器,造成累加效果,秒表越跑越快
(2)时分秒在计算之后要取余,否则会超过60/24
10.轮播图
11.tab标签页
(1)css实现标签页:
原理:利用display:none;或者position:absolute或opacity:0;,触发时display:block;或者z-index增大,display:none;布局更简单
以下都使用display:none;
方法一:利用hover选择器
- 缺点:只有鼠标在元素上面的时候才有效果,无法实现选中和默认显示某一个的效果
HTML布局:滑动门布局
原因:选择器只能拿到hover元素的子元素
CSS:当鼠标移动到 li 上时,li 上有新样式并且li下的div显示出来,非当前li下的div都隐藏display:none;
难点:内容div要相对于tab进行布局
1 | .tab { |
方法二:利用a标签的锚点 + :target选择器
本质:锚点
- 缺点:因为锚点会将选中的元素滚动到页面最上面,每次切换位置都要移动,体验极差。
- 首次加载没有默认值
bug:写选择器时不能只写一个:target,必须加上父选择器,否则权重不够
1 | .tab_b>div:target { |
样式会应用到锚点指定的内容区
方法三:利用label和radio的绑定关系以及radio选中时的:checked
1 | /* 匹配任意被勾选/选中的radio(单选按钮),checkbox(复选框),或者option(select中的一项) */ |
来实现效果
- 缺点:HTML结构元素更复杂
经过实验发现第三种方法达到的效果最好。所以下面讲一下第三种实现的方法。
这种方法的写法不固定,我查资料的时候各种各样的写法都有一度让我一头雾水的。最后看完发现总体思路都是一样的,无非就是下面的几个步骤。
- 绑定label和radio:这个不用说id和for属性绑定
- 隐藏radio按钮:这个方法有很多充分发挥你们的想象力就可以了,我见过的方法有设置
display:none;
隐藏的、设置绝对定位,将left设置为很大的负值,移动到页面外达到隐藏效果、设置绝对定位:使元素脱离文档流,然后opacity: 0;
设置为透明来达到隐藏效果。 - 隐藏多余的tab页:和上面同理,还可以通过
z-index
设置层级关系来相互遮挡。 - 设置默认项:在默认按钮上添加
checked="checked"
属性 - 设置选中效果:利用+选择器 和 ~选择器来设置选中对应元素时下方的tab页的样式,来达到选中的效果
问题1:div相对于公共父元素ul绝对定位,如果给li设置定位,选项卡不能压在div上,原因子压父,只有同一层级的可以设置层级进行比较,所以应该在div的同一层级设置z-index,应该设置在label上
在写样式时,如果有子元素,父元素只负责位置,具体样式都设置在子元素上,在本例中,li只负责定位,具体样式设置在子元素label上
问题2:当input:checked时,label显示左,上,右边框,去背景,其他label如果显示底边框会超出1px
解决:只有当label被激活时,再让它压div,否则,让div压label
问题3:给label设置了relative,div设置了absolute;本应该后一个压前一个,但是前一个压在了后一个上
1 | <label class="test-label" for="testTabRadio3">选项卡三</label> |
原因待查找。。。。
解决方法:将给label设置了relative移到激活状态下,或者给给label的relative和div的absolute;设置z-index
默认堆叠效果:1️⃣平级元素-后来者居上;2️⃣子元素压在父元素之上—-子压父
注意:①取值可以为负,取值为负时,当前元素会位于页面正常显示内容之下
②z-index 是无法改变父子关系的堆叠顺序:**子元素始终压在父元素之上------子压父**
③只有有定位的元素可以使用z-index,只能作用在relative、absolute、fixed定位的元素上
(2)js实现tab切换
方法一:自写版本
HTML :
1 | <div class="tab"> |
CSS:布局——正常文档流
原理:控制li对应的div的display
css关键点:样式要设置在a标签上,不能写在li上,因为:我的点击事件是绑定到公共父元素ul上的(事件代理),由于事件冒泡,这样在触发事件的时候,实际的target会是 a 元素或 li 元素,没办法获取到target
在写样式时,如果有子元素,父元素只负责位置,具体样式都设置在子元素上
需要优化的地方:
1 | .tab_b>div:not(:first-child){ |
如果用js去操作元素css属性的切换时,最好是直接操作class,而不是操作某一个具体的元素或具体的属性
1 | .on{ |
JS:
1 | // 获取元素 |
问题1:样式的切换用class ,不要用js写
1 | tabHead.onclick = function (e) { |
问题2:在移除class执行的是相同的操作,可以用一个函数来封装
问题3:如何获取一个数组或类数组对象中的值的index
var index = Array.prototype.indexOf.call(Items, item);
最终完成版本:
1 | //获取元素 |
方法二:双层for循环
1 | for (var i = 0; i < myLi.length; i++) { |
自定义属性:js可以为任何HTML元素添加任意个自定义属性,且如同元素的本来属性一样进行操作
数组元素本身没有index属性,自定义一个,比方法一获取index方便好用
对比方法一盒方法二:我觉得方法二更好,逻辑清晰,代码简单
12.全屏滚动
全屏滚动原理
全屏滚动插件的实现原理是:所有滚动页面包在一个直接父级容器main中,容器及容器内的页面取当前可视区高度,同时容器的直接父级元素wrap设置 overflow
属性值设为 hidden
,通过更改容器 transform
属性的 translate
或者 top
的值实现全屏滚动效果。
css全屏滚动
全屏滚动分为:横屏滚动和竖屏滚动
竖屏滚动:
html:
1 | <div id="wrap"> |
css
1 | html,body{ |
横屏滚动:
在竖屏滚动的基础上,给wrap设置width:400%;给page设置width:25%;
问题1:html的代码为什么需要两个父元素??
这是为js做准备,第一个设置让滚动条消失,始终在视窗位置,第二个做移动容器
问题2:设置overflow:hidden;的作用是去掉滚动条,这个属性设置在哪个元素上???
设置在固定容器上
JS实现全屏滚动
原理:同胶片和相机的视窗一样,wrap始终不同,main整体移动
html:
1 | <div id="wrap"> |
wrap块为窗口可看到的部分,我们可以通过js获取窗口可视区的大小,并为其设置overflow: hidden属性,使得窗口不出现滚动条,只显示窗口大小的一页内容;
设置main定位为relative,通过改变main块的top属性实现不同页面的切换,具体的css代码如下:
1 | html,body{ |
js代码的主要部分就是对滚动事件的函数绑定,大多数浏览器提供了 “mousewheel” 事件,Firefox 3.5+不支持,但支持相同作用的事件:”DOMMouseScroll”;
mousewheel事件的“event.wheelDelta” 属性值:返回的如果是正值说明滚轮是向上滚动;
DOMMouseScroll事件“event.detail” 属性值:返回的如果是负值说明滚轮是向上滚动;
Js:
1 | var wrap = document.getElementById("wrap"); |
插件实现全屏滚动——fullpage.js
https://github.com/alvarotrigo/fullpage.js
在3.0之前,3.0之后不需要依赖jQuery,但是需要许可证,fullPage.js 是一个基于 jQuery 的插件,它能够很方便、很轻松的制作出全屏网站,主要功能有:
- 支持鼠标滚动
- 支持前进后退和键盘控制
- 多个回调函数
- 支持手机、平板触摸事件
- 支持 CSS3 动画
- 支持窗口缩放
- 窗口缩放时自动调整
- 可设置滚动宽度、背景颜色、滚动速度、循环选项、回调、文本对齐方式等等
兼容性
jQuery 兼容
兼容 jQuery 1.7+。
浏览器兼容
![]() | ![]() | ![]() | ![]() | ![]() |
---|---|---|---|---|
IE8+ | Chrome | Firefox | Opera | Safari |
使用方法
1、引入文件
1 | <link rel="stylesheet" href="css/jquery.fullPage.css"> |
2、HTML
1 | <div id="dowebok"> |
每个 section 代表一屏,默认显示“第一屏”,如果要指定加载页面时显示的“屏幕”,可以在对应的 section 加上 class=”active”,如:
1 | <div class="section active">第三屏</div> |
同时,可以在 section 内加入 slide,如:
1 | <div id="dowebok"> |
3、JavaScript
1 | $(function(){ |
配置
1、选项
选项 | 类型 | 默认值 | 说明 |
---|---|---|---|
verticalCentered | 字符串 | true | 内容是否垂直居中 |
resize | 布尔值 | false | 字体是否随着窗口缩放而缩放 |
slidesColor | 数组 | 无 | 设置背景颜色 |
anchors | 数组 | 无 | 定义锚链接 |
scrollingSpeed | 整数 | 700 | 滚动速度,单位为毫秒 |
easing | 字符串 | easeInQuart | 滚动动画方式 |
menu | 布尔值 | false | 绑定菜单,设定的相关属性与 anchors 的值对应后,菜单可以控制滚动 |
navigation | 布尔值 | false | 是否显示项目导航 |
navigationPosition | 字符串 | right | 项目导航的位置,可选 left 或 right |
navigationColor | 字符串 | #000 | 项目导航的颜色 |
navigationTooltips | 数组 | 空 | 项目导航的 tip |
slidesNavigation | 布尔值 | false | 是否显示左右滑块的项目导航 |
slidesNavPosition | 字符串 | bottom | 左右滑块的项目导航的位置,可选 top 或 bottom |
controlArrowColor | 字符串 | #fff | 左右滑块的箭头的背景颜色 |
loopBottom | 布尔值 | false | 滚动到最底部后是否滚回顶部 |
loopTop | 布尔值 | false | 滚动到最顶部后是否滚底部 |
loopHorizontal | 布尔值 | true | 左右滑块是否循环滑动 |
autoScrolling | 布尔值 | true | 是否使用插件的滚动方式,如果选择 false,则会出现浏览器自带的滚动条 |
scrollOverflow | 布尔值 | false | 内容超过满屏后是否显示滚动条 |
css3 | 布尔值 | false | 是否使用 CSS3 transforms 滚动 |
paddingTop | 字符串 | 0 | 与顶部的距离 |
paddingBottom | 字符串 | 0 | 与底部距离 |
fixedElements | 字符串 | 无 | |
normalScrollElements | 无 | ||
keyboardScrolling | 布尔值 | true | 是否使用键盘方向键导航 |
touchSensitivity | 整数 | 5 | |
continuousVertical | 布尔值 | false | 是否在垂直方向上循环滚动,与 loopTop 及 loopBottom 不兼容 |
animateAnchor | 布尔值 | true | |
normalScrollElementTouchThreshold | 整数 | 5 | |
sectionsColor(同slidesColor) | 数组 | 无 | 给每一屏设置背景色 |
2、方法
名称 | 说明 |
---|---|
moveSectionUp() | 向上滚动 |
moveSectionDown() | 向下滚动 |
moveTo(section, slide) | 滚动到 |
moveSlideRight() | slide 向右滚动 |
moveSlideLeft() | slide 向左滚动 |
setAutoScrolling() | 设置页面滚动方式,设置为 true 时自动滚动 |
setAllowScrolling() | 添加或删除鼠标滚轮/触控板控制 |
setKeyboardScrolling() | 添加或删除键盘方向键控制 |
setScrollingSpeed() | 定义以毫秒为单位的滚动速度 |
3、回调函数
名称 | 说明 |
---|---|
afterLoad | 滚动到某一屏后的回调函数,接收 anchorLink 和 index 两个参数,anchorLink 是锚链接的名称,index 是序号,从1开始计算 |
onLeave | 滚动前的回调函数,接收 index、nextIndex 和 direction 3个参数:index 是离开的“页面”的序号,从1开始计算;nextIndex 是滚动到的“页面”的序号,从1开始计算;direction 判断往上滚动还是往下滚动,值是 up 或 down。 |
afterRender | 页面结构生成后的回调函数,或者说页面初始化完成后的回调函数 |
afterSlideLoad | 滚动到某一水平滑块后的回调函数,与 afterLoad 类似,接收 anchorLink、index、slideIndex、direction 4个参数 |
onSlideLeave | 某一水平滑块滚动前的回调函数,与 onLeave 类似,接收 anchorLink、index、slideIndex、direction 4个参数 |
1 | var myFullpage = new fullpage('#fullpage', { |
延迟加载
fullPage.js提供了一种延迟加载图像、视频和音频元素的方式,这样它们不会减慢网站的加载速度,也不会浪费数据传输。 当使用延迟加载时,所有这些元素只有在进入视口时才会加载。 要启用延迟加载,您只需将src属性更改为data-src,如下所示:
1 | <img data-src="image.png"> |
如果您已经使用另一个使用data-src的延迟加载解决方案,则可以通过设置 lazyLoading: false
选项来禁用fullPage.js延迟加载。
自动播放
对于视频或音频使用属性 autoplay,或者对于youtube iframe使用参数autoplay=1将使得在加载页面时播放媒体元素。 在段落/幻灯片载入使用而不是属性data-autoplay播放。 例如:
1 | <audio data-autoplay> |
暂停
嵌入式HTML5
1 | <audio data-keepplaying> |
此外,fullpage.js还可以使用扩展插件,更多详情请查看fullpage.js项目官网
bootstrap实现滚动监听—scrollspy.js
13.模态框
遮罩层布局
方法一:传统方法(增加额外元素)
增加一个额外的HTML元素用于遮挡背景
1 | <div class="overlay"></div> |
1 | .overlay { |
lightbox盒子放在mask遮罩层之后,压在mask上
这个方法的优点:稳定可靠,缺点:需要增加额外的HTML。
方法二:子压父
1 | <div class="mask"> |
根据子压父原理,不需要设置层级关系
该方法的特点是遮罩层和弹出框无法滚动,但是页面的内容可以滚动。
如果想要出现遮罩层和弹框时页面禁止滚动,则可以使用如下方式:
1、在pc端可以给body设置overflow:hidden;
2、在移动端则需要给遮罩层加一个在touchmove时禁止浏览器默认行为的操作:
1 | $('.mask').on("touchmove",function(e){ |
方法三:target方法
https://developer.mozilla.org/en-US/docs/Web/CSS/:target
传统方法+target
html
1 | <ul> |
css
1 | /* Unopened lightbox */ |
效果图:
模态框实例
传统方法 ,见代码
14.视差滚动
点击预览.html)
15.滚动监听
原理:
通过监听滚动条距离顶部的距离,执行相应的操作,核心代码:
1 | var t = document.documentElement.scrollTop || document.body.scrollTop; |
两种监听页面滚动的方法
①原生js通过window.onscroll监听
1 | window.onscroll = function() { |
②Jquery通过$(window).scroll()监听
1 | $(window).scroll(function() { |
将页面滚动到指定位置
主要使用的是锚点技术,锚点元素通过scrollTop值改变进行定位。
方法一 直接使用scrollTop
使用scrollTop方法,x为滚轮的高度$("body,html").scrollTop(x);
加动画的滚动
1 | // 滚动到指定位置 |
方法二 利用hash
hash 属性是一个可读可写的字符串,该字符串是 URL 的锚部分(从 # 号开始的部分)。
location.hash=anchorname。
例如:以下地址的hash为#hot
http://this.summer.io/is/#hot
等于 location.hash → #hot
以下函数将页面定位到title元素
1 | function aa(){ |
方法三 直接使用超链接锚点
点击a标签页面将会定位到anchor1元素
1 | <a href="#anchor1">锚点1</a> |
知识仓库
1 | //网页可见区域宽: |
通过下面这段js代码就能够实现当页面从顶部向下滑动超过300px时,返回顶部的图片出现,并且点击图片,页面平滑的移动到页面顶部。
1 | <div class="uptop" id="uptop"> |
1 | window.onscroll = function(){ |
插件:
onepage-scroll.js
https://github.com/peachananr/onepage-scroll
16.下拉菜单
html结构:使用滑动门效果
1 | <div class="dropdown"> |
17.工具提示tooltip
定位一个伪元素到父元素之外
18.警告框
1 | <div class="alert"> |
19.手风琴效果
方法一:css+animation
方法二:target
方法三:js
原理
如果不要求有动画效果,通过操作class完成,class为要实现的效果
首先将所有元素的特定class值去除(清空),事件发生时,给当前元素加上该class值
this = event.currentTarget 等于绑定事件的元素,谁绑定就是谁
event.target 是由于冒泡原理而实际触发事件的元素,谁触发就是谁触发的不一定是绑定的,有可能是绑定元素的子元素
注意:通过元素的width获得的宽度由单位px,需要进行处理,通过offsetWidth获得的为数值,不需要处理
有动画效果的手风琴
1 | function accordion() { |
20.获取一个元素样式的函数
1 | function getCSS(obj,style){ |
21.解析URL字符串的函数
1 | function getQueryStringArgs(){ |
22.命名空间写法
1 | var GLOBAL = {}; |
23.location的hasChange事件
1 | //非IE浏览器 |