封装Swiper为Vue组件

载入

安装swiper

1
yarn add swiper@4.5.0

另外, 也可以使用cdn载入

1
2
3
4
// css
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.0/css/swiper.min.css">
// js
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.0/js/swiper.min.js"></script>

结构

一个swiper所需的html结构如下

1
2
3
4
5
6
7
8
9
10
11
12

<div class="swiper-container">
<!-- Additional required wrapper -->
<!-- swiper通过更改swiper-wrapper的transform属性来轮播内容 -->
<div class="swiper-wrapper">
<!-- Slides 单个内容-->
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
...
</div>
</div>

class属性值swiper-wrapper和swiper-slide是必有的,没找到可以更改这两个class的设置项.

创建swiper

1
var mySwiper = new Swiper ('.swiper-container', { params...}

https://idangero.us/swiper/get-started/

圆形运算相关知识点

弧度

角度: 圆被平分为360分(人为定义),其中的一份为 1deg, 1deg = π / 180

弧度: 圆上弧长等于半径时的圆心角, 1rad ~ 57.2958deg
51987688-08c55300-24de-11e9-81ba-e4aa61fb0446.png
整圆弧度 2π (2πr / r)

角弧度换算

弧度转角度

1
2
3
function toAngle(radian) {
return (180 / Math.PI) * radian
}

角度转弧度

1
2
3
function toRadian(angle) {
return (Math.PI / 180) * angle
}

储存keep-alive内组件的滚动位置

keep-alive一般被用来缓存组件实例.当从一个组件切换到另一个时, 这个组件不会被销毁, 而会被保存起来供下次调用时使用.
遗憾的是, 如果被keep-alive包裹的组件中有滚动元素,keep-alive不会储存滚动位置.
需要在滚动时储存位置, 然后在组件被激活时还原.

keep-alive 组件有两个特殊的生命周期钩子: activated和deactivated.
activated在keep-alive组件激活时调用.
deactivated在keep-alive组件被停用时调用.
API — Vue.js

event loop

JavaScript 支持处理并发事件,其并发模型基于 event loop.
Untitled Diagram (2).jpg

并发与并行

并发和并行是两个不同的概念,很容易被弄混.
并发(concurrency)指的是同一时间有能力应对多件事,而并行(Parallel )指的是同一时间有能力做多件事.

举个例子:
妈妈一边打小明,一边和老王通电话.妈妈先打一下小明, 然后和老王聊一句.如此交替,这是并发.
小明的妈妈是个妖怪,长了两个脑袋.一个脑袋骂小明,同时另一个脑袋通电话.这即是并行,也是并发.
但如果妈妈的两个脑袋同时骂小明,那这就只能是并行了,不是并发.因为骂小明是同一个事件.

Js是一门"单线程"语言

什么是"线程", 和"进程"有什么区别?

"进程"(process)是运行中的"程序"(program)实例, 一个"程序"可以拥有多个"进程".
进程之间彼此独立,有独立的内存空间.

Windows中的Chrome进程大军:
捕获.PNG

"线程"(thread)是操作系统分配CPU控制时间的基本单位, 一个"进程"可以拥有一个或多个"线程",这些"线程"共享进程内的资源.

单个进程内的线程数量:
2.PNG

移动端浏览器对audio标签的限制总结

往往在桌面写好的播放功能,到移动端各种出错.
这是因为在移动端,对于audio的使用有很多限制,特别是safari.
而且现在的各种框架, 极大加深了程序的复杂程度,使调试变得异常困难.

测试环境

本文测试环境为iPad ios12,没有条件进行iphone/桌面端safari环境下audio的表现

不支持autoplay/preload

大部分移动端浏览器都不允许网页自动播放/预加载音乐.
例如下面这个示例, 桌面浏览器可以自动播放,而移动浏览器没有任何反应.

1
<audio controls src="./music/1.mp3" autoplay></audio>

除非用户点了播放按钮/手动触发了某个事件(这个事件里调用了audio.play()方法)
为啥这么设计?据说是怕网页偷跑流量.

只有用户手动触发的事件能调用play/load

既然autoplay不能用,那能不能用play方法来自动播放呢?
很遗憾的是, 不行.
例如下面这样,在移动端没效果:

1
2
3
4
5
<audio controls src="./music/1.mp3"></audio>
<script>
const audioEl = document.querySelector('audio')
audioEl.play()
</script>

先来看看水果的文档:

In Safari on iOS (for all devices, including iPad), where the user may be on a cellular network and be charged per data unit, preload and autoplay are disabled. No data is loaded until the user initiates it. This means the JavaScript play() and load() methods are also inactive until the user initiates playback, unless the play() or load() method is triggered by user action. In other words, a user-initiated Play button works, but an onLoad="play()" event does not.

iOS-Specific Considerations

也就是说,只有当用户手动触发某个事件时,audio.play才能被调用.

1
2
3
4
click由用户触发, 有效
<input type="button" value="Play" onclick="document.myMovie.play()">
onload事件不是用户触发的,无效
<body onload="document.myMovie.play()">

因此,可以给外层元素绑定一个click事件.
只要用户点了这个元素,就能播放音乐.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div>
<audio controls src="./music/1.mp3"></audio>
</div>

<script>
const audioEl = document.querySelector('audio')
const played = false
document.querySelector('div').addEventListener('click', ()=> {
if (!played) {
audioEl.play()
played = true
}
})
</script>

transform导致fixed失效

transform是个超级常用的属性, 需要居中/动画/开启cpu加速时经常会用到.
但这个属性也有很多副作用, 例如把后边的元素盖住了,或者是后代absolute元素被overflow:hidden剪裁.
除此之外还有个影响, 让拥有固定定位(fixed)属性的子元素变的像个绝对定位(absolute)元素.

1.PNG

如上图所示, 黑色子元素为固定定位元素(fixed), 由于黄色父元素transfrom属性的影响, 表现的像个绝对定位元素(absolute).

height百分比值不生效

有时候要给父元素定一个最小高度,然后让子元素与父元素等高.
往往第一反应是设置min-height和height: 100%,但这么作通常不会生效.

1.PNG
如上图所示,外层容器的高度为min-height: 100px,内部黄色子元素的高度为height: 50%.
可以观察到,子元素的height: 50%并未生效.

JSONP

JSONP(JSON with Padding)是在早期浏览器不允许跨域的背景下,诞生的 一种通信方式

什么是跨域

前端获取数据一般都通过XMLHttpRequest发送请求,但有一定的限制
在CORS之前, 浏览器不允许通过XMLHttpRequest向不同于当前域名/端口/协议的地址发送请求
另外,这种(向不同域名)发送请求的行为通常称为"跨域"

例如

当前域名 http://www.example.com/foo
允许 http://www.example.com
允许 http://www.example.com/api/foo
禁止 https://www.example.com
禁止 http://bar.example.com
禁止 https://www.example.com:4000

获取元素位置/尺寸的方法

clientWidth offsetWidth scrollWidth

  • clientWidth|clientHeight 元素内容可视部分的宽度/高度,不包括 滚动条 border margin
  • offsetWidth|offsetHeight 元素整体宽度/高度,包括滚动条和border,不包括margin
  • scrollWidth|scrollHeight 元素内容实际宽度/高度,包含被隐藏的部分

示例
50424091-e23a4980-0899-11e9-8b18-e8b210cbf876.png

如上所示,两容器元素的宽/高均为200px, border为1px,padding为10px. 背景颜色为黄色, padding无颜色
两容器内均有一斜线为背景的子元素,其宽/高均为300px
容器1的overflow属性值为auto(可滚动).滚动条宽度为17px,颜色为蓝色
容器2的overflow的属性值为static(默认值,无滚动条)
clientWidth长度的计算不包含滚动条.当容器有滚动条时,clientWidth值为203px(220px - 17px).没有滚动条时,clientWidth值为220px
在chrome中,padding-right不参与scrollWidth值的计算.而padding-bottom相反,参与scrollHeight值的计算.因此, 可滚动元素的scrollWidth为310px,scrollHeight为320px