一些常用的正则验证

1.手机号校验

1
2
3
4
5
6
const phoneReg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/
// test
const phoneStr1 = '18886233487'
console.log(phoneReg.test(phoneStr1)) // true
const phoneStr2 = '17283017203897'
console.log(phoneReg.test(phoneStr2)) // false

2.身份证的校验

1
2
3
4
5
6
const sfzReg = /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
// test
const sfzStr1 = '415106199801012130'
console.log(sfzReg.test(sfzStr1)) // true
const sfzStr2 = '718381298381212183'
console.log(sfzReg.test(sfzStr2)) // false

3.邮箱校验

1
2
3
4
5
6
7
8
const emailReg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/
// test
const emailStrWY = '956666@163.com' // 163邮箱
const emailStrQQ = '956666@qq.com' // qq邮箱
console.log(emailReg.test(emailStrWY)) // true
console.log(emailReg.test(emailStrQQ)) // true
const noEmail = '72873213.com'
console.log(emailReg.test(noEmail)) // false

4.URL的校验

1
2
3
4
5
6
const urlReg = /^((https?|ftp|file):\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/
// test
const urlStr1 = 'https://haha.sunshine.com/xxx/xxx'
console.log(urlReg.test(urlStr1)) // true
const urlStr2 = 'sss://haha.sunshine.com/xxx/xxx'
console.log(urlReg.test(urlStr2)) // false

5.IPv4的校验

1
2
3
4
5
6
const ipv4Reg = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
// test
const ipv4Str1 = '122.12.56.65'
console.log(ipv4Reg.test(ipv4Str1)) // true
const ipv4Str2 = '122.12.56.655'
console.log(ipv4Reg.test(ipv4Str2)) // false

6.16进制颜色的校验

1
2
3
4
5
6
const color16Reg = /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/
// test
const color16Str1 = '#fff'
console.log(color16Reg.test(color16Str1)) // true
const color16Str2 = '#1234567'
console.log(color16Reg.test(color16Str2)) // false

7.日期 YYYY-MM-DD

1
2
3
4
5
6
7
const dateReg = /^\d{4}(\-)\d{1,2}\1\d{1,2}$/

const dateStr1 = '2021-10-10'
console.log(dateReg.test(dateStr1)) // true

const dateStr2 = '2021-01-01 1'
console.log(dateReg.test(dateStr2)) // false

8.日期 YYYY-MM-DD hh:mm:ss

1
2
3
4
5
6
7
const dateReg = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2}) (\d{1,2}):(\d{1,2}):(\d{1,2})$/

const dateStr1 = '2021-10-10 16:16:16'
console.log(dateReg.test(dateStr1)) // true

const dateStr2 = '2021-10-10 16:'
console.log(dateReg.test(dateStr2)) // false

9.整数的校验

1
2
3
4
5
6
7
const intReg = /^[-+]?\d*$/

const intNum1 = 12345
console.log(intReg.test(intNum1)) // true

const intNum2 = 12345.1
console.log(intReg.test(intNum2)) // false

10.小数的校验

1
2
3
4
const floatReg = /^[-\+]?\d+(\.\d+)?$/

const floatNum = 1234.5
console.log(floatReg.test(floatNum)) // true

11.保留n位小数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function checkFloat(n) {
return new RegExp(`^([1-9]+[\d]*(.[0-9]{1,${n}})?)$`)
}
// 保留2位小数
const floatReg = checkFloat(2)

const floatNum1 = 1234.5
console.log(floatReg.test(floatNum1)) // true

const floatNum2 = 1234.55
console.log(floatReg.test(floatNum2)) // true

const floatNum3 = 1234.555
console.log(floatReg.test(floatNum3)) // false

12.邮政编号的校验

1
2
3
4
5
6
7
const postalNoReg = /^\d{6}$/

const postalNoStr1 = '522000'
console.log(postalNoReg.test(postalNoStr1)) // true

const postalNoStr2 = '5220000'
console.log(postalNoReg.test(postalNoStr2)) // false

13.QQ号的校验(5-11位数字)

1
2
3
4
5
6
7
const qqReg = /^[1-9][0-9]{4,10}$/

const qqStr1 = '1915801633'
console.log(qqReg.test(qqStr1)) // true

const qqStr2 = '191580163333'
console.log(qqReg.test(qqStr2)) // false

14.微信号的校验(6至20位,以字母开头,字母,数字,减号,下划线)

1
2
3
4
5
6
7
const wxReg = /^[a-zA-Z]([-_a-zA-Z0-9]{5,19})+$/

const wxStr1 = 'linsanxin885577'
console.log(wxReg.test(wxStr1)) // true

const wxStr2 = '厉害了我的vx'
console.log(wxReg.test(wxStr2)) // false

15.车牌号的校验

1
2
3
4
5
6
7
const carNoReg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1}$/

const carNoStr1 = '粤A12345'
console.log(carNoReg.test(carNoStr1)) // true

const carNoStr2 = '广东A12345'
console.log(carNoReg.test(carNoStr2)) // false

16.只含字母的字符串

1
2
3
4
5
6
7
const letterReg = /^[a-zA-Z]+$/

const letterStr1 = 'sunshineLin'
console.log(letterReg.test(letterStr1)) // true

const letterStr2 = 'sunshine_Lin'
console.log(letterReg.test(letterStr2)) // false

17.包含中文的字符串

1
2
3
4
5
6
7
const cnReg = /[\u4E00-\u9FA5]/

const cnStr1 = '我是sunshine_Lin,林三心'
console.log(cnReg.test(cnStr1)) // true

const cnStr2 = 'sunshine_Lin'
console.log(cnReg.test(cnStr2)) // false

18.密码强度的校验(密码中必须包含字母、数字、特称字符,至少8个字符,最多30个字符)

1
2
3
4
5
6
7
const passwordReg = /(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[^a-zA-Z0-9]).{8,30}/

const password1 = 'sunshine_Lin12345..'
console.log(passwordReg.test(password1)) // true

const password2 = 'sunshineLin12345'
console.log(passwordReg.test(password2)) // false

19.字符串长度n的校验

1
2
3
4
5
6
7
8
9
10
11
12
function checkStrLength(n) {
return new RegExp(`^.{${n}}$`)
}

// 校验长度为3的字符串
const lengthReg = checkStrLength(3)

const str1 = 'hhh'
console.log(lengthReg.test(str1)) // true

const str2 = 'hhhhh'
console.log(lengthReg.test(str2)) // false

20.文件拓展名的校验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function checkFileName (arr) {
arr = arr.map(name => `.${name}`).join('|')
return new RegExp(`(${arr})$`)
}

const filenameReg = checkFileName(['jpg', 'png', 'txt'])

const filename1 = 'sunshine.jpg'
console.log(filenameReg.test(filename1)) // true
const filename2 = 'sunshine.png'
console.log(filenameReg.test(filename2)) // true
const filename3 = 'sunshine.txt'
console.log(filenameReg.test(filename3)) // true
const filename4 = 'sunshine.md'
console.log(filenameReg.test(filename4)) // false

21.匹配img和src

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const imgReg = /<img.*?src=[\"|\']?(.*?)[\"|\']?\s.*?>/ig

const htmlStr = '<div></div><img src="sunshine.png" /><img src="sunshine111.png" />'

console.log(imgReg.exec(htmlStr))
// [
// '<img src="sunshine.png" />',
// 'sunshine.png',
// index: 11,
// input: '<div></div><img src="sunshine.png" /><img src="sunshine111.png" />',
// groups: undefined
// ]
console.log(imgReg.exec(htmlStr))
// [
// '<img src="sunshine111.png" />',
// 'sunshine111.png',
// index: 37,
// input: '<div></div><img src="sunshine.png" /><img src="sunshine111.png" />',
// groups: undefined
// ]

21.匹配img和src

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const imgReg = /<img.*?src=[\"|\']?(.*?)[\"|\']?\s.*?>/ig

const htmlStr = '<div></div><img src="sunshine.png" /><img src="sunshine111.png" />'

console.log(imgReg.exec(htmlStr))
// [
// '<img src="sunshine.png" />',
// 'sunshine.png',
// index: 11,
// input: '<div></div><img src="sunshine.png" /><img src="sunshine111.png" />',
// groups: undefined
// ]
console.log(imgReg.exec(htmlStr))
// [
// '<img src="sunshine111.png" />',
// 'sunshine111.png',
// index: 37,
// input: '<div></div><img src="sunshine.png" /><img src="sunshine111.png" />',
// groups: undefined
// ]

22.匹配html中的注释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const noteReg = /<!--(.*?)-->/g

const htmlStr = '<!--一个div标签--> <div></div> <!--一个div标签--> <div></div>'

console.log(noteReg.exec(htmlStr))
// [
// '<!--一个div标签-->',
// '一个div标签',
// index: 0,
// input: '<!--一个div标签--> <div></div> <!--一个div标签--> <div></div>',
// groups: undefined
// ]
console.log(noteReg.exec(htmlStr))
// [
// '<!--一个div标签-->',
// '一个div标签',
// index: 27,
// input: '<!--一个div标签--> <div></div> <!--一个div标签--> <div></div>',
// groups: undefined
// ]

23.匹配html中的style

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const styleReg = /([(\s+\w+=)|>])/g

const htmlStr = '<div><span></span></div>'

console.log(styleReg.exec(htmlStr))
// [
// '>',
// '>',
// index: 5,
// input: '<div><span></span></div>',
// groups: undefined
// ]
console.log(styleReg.exec(htmlStr))
// [
// '>',
// '>',
// index: 36,
// input: '<div><span></span></div>',
// groups: undefined
// ]

24.匹配html中的颜色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const colorReg = /#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/g

const htmlStr = '<div><span></span></div>'

console.log(colorReg.exec(htmlStr))
// [
// '#000',
// '000',
// index: 23,
// input: '<div><span></span></div>',
// groups: undefined
// ]
console.log(colorReg.exec(htmlStr))
// [
// '#fff',
// 'fff',
// index: 49,
// input: '<div><span></span></div>',
// groups: undefined
// ]

25.匹配htmlTag(html标签)

1
2
3
4
5
const endReg = /<("[^"]*"|'[^']*'|[^'">])*>/g

const htmlStr = '<div><span></span></div><h1></h1>'

console.log(endReg.exec(htmlStr))

JS 正则表达式

正则表达式的创建方式以及区别

pattern:正则表达式  
flags:标识(修饰符)
标识主要包括:
1. i 忽略大小写匹配
2. m 多行匹配,即在到达一行文本末尾时还会继续寻常下一行中是否与正则匹配的项
3. g 全局匹配 模式应用于所有字符串,而非在找到第一个匹配项时停止

字面量创建方式

1
var reg = /pattern/flags

实例创建方式

1
var reg = new RegExp(pattern,flags);

字面量创建方式和构造函数创建方式的区别

1.字面量创建方式不能进行字符串拼接,实例创建方式可以

1
2
3
4
5
var regParam = 'cm';
var reg1 = new RegExp(regParam+'1');
var reg2 = /regParam/;
console.log(reg1); // /cm1/
console.log(reg2); // /regParam/

2.字面量创建方式特殊含义的字符不需要转义,实例创建方式需要转义

1
2
3
var reg1 = new RegExp('\d');  //    /d/ 
var reg2 = new RegExp('\\d') // /\d/
var reg3 = /\d/; // /\d/

元字符

代表特殊含义的元字符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
\d : 0-9之间的任意一个数字  \d只占一个位置
\w : 数字,字母 ,下划线 0-9 a-z A-Z _
\s : 空格或者空白等
\D : 除了\d
\W : 除了\w
\S : 除了\s
. : 除了\n之外的任意一个字符
\ : 转义字符
| : 或者
() : 分组
\n : 匹配换行符
\b : 匹配边界 字符串的开头和结尾 空格的两边都是边界 => 不占用字符串位数
^ : 限定开始位置 => 本身不占位置
$ : 限定结束位置 => 本身不占位置
[a-z] : 任意字母 []中的表示任意一个都可以
[^a-z] : 非字母 []中^代表除了
[abc] : abc三个字母中的任何一个 [^abc]除了这三个字母中的任何一个字符

代表次数的量词元字符

1
2
3
4
5
6
* : 0到多个
+ : 1到多个
? : 0次或1次 可有可无
{n} : 正好n次;
{n,} : n到多次
{n,m} : n次到m次

量词出现在元字符后面 如\d+,限定出现在前面的元字符的次数

1
2
3
4
5
6
7
8
9
var str = '1223334444';
var reg = /\d{2}/g;
var res = str.match(reg);
console.log(res) //["12", "23", "33", "44", "44"]

var str =' 我是空格君 ';
var reg = /^\s+|\s+$/g; //匹配开头结尾空格
var res = str.replace(reg,'');
console.log('('+res+')') //(我是空格君)

正则运算符的优先级

1.正则表达式从左到右进行计算,并遵循优先级顺序,这与算术表达式非常类似。
2.相同优先级的会从左到右进行运算,不同优先级的运算先高后低。

1
2
3
4
5
6
7
8
9
10
11
下面是常见的运算符的优先级排列
依次从最高到最低说明各种正则表达式运算符的优先级顺序:

\ : 转义符
(), (?:), (?=), [] => 圆括号和方括号
*, +, ?, {n}, {n,}, {n,m} => 量词限定符
^, $, \任何元字符、任何字符
| => 替换,"或"操作

字符具有高于替换运算符的优先级,一般用 | 的时候,为了提高 | 的优先级,我们常用()来提高优先级
如: 匹配 food或者foot的时候 reg = /foo(t|d)/ 这样来匹配

正则的特性

贪婪性:所谓的贪婪性就是正则在捕获时,每一次会尽可能多的去捕获符合条件的内容。
如果我们想尽可能的少的去捕获符合条件的字符串的话,可以在量词元字符后加?
懒惰性:懒惰性则是正则在成功捕获一次后不管后边的字符串有没有符合条件的都不再捕获。
如果想捕获目标中所有符合条件的字符串的话,我们可以用标识符g来标明是全局捕获。

1
2
3
4
5
6
7
8
9
var str = '123aaa456';
var reg = /\d+/; //只捕获一次,一次尽可能多的捕获
var res = str.match(reg)
console.log(res)
// ["123", index: 0, input: "123aaa456"]
reg = /\d+?/g; //解决贪婪性、懒惰性
res = str.match(reg)
console.log(res)
// ["1", "2", "3", "4", "5", "6"]

和正则相关的一些方法

这里我们只介绍test、exec、match和replace这四个方法:

reg.test(str) 用来验证字符串是否符合正则 符合返回true 否则返回false

1
2
3
var str = 'abc';
var reg = /\w+/;
console.log(reg.test(str)); //true

reg.exec() 用来捕获符合规则的字符串

1
2
3
4
5
6
7
8
9
10
11
12
var str = 'abc123cba456aaa789';
var reg = /\d+/;
console.log(reg.exec(str))
// ["123", index: 3, input: "abc123cba456aaa789"];
console.log(reg.lastIndex)
// lastIndex : 0

reg.exec捕获的数组中
// [0:"123",index:3,input:"abc123cba456aaa789"]
0:"123" 表示我们捕获到的字符串
index:3 表示捕获开始位置的索引
input 表示原有的字符串

当我们用exec进行捕获时,如果正则没有加’g’标识符,则exec捕获的每次都是同一个,当正则中有’g’标识符时 捕获的结果就不一样了,我们还是来看刚刚的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
var str = 'abc123cba456aaa789';
var reg = /\d+/g; //此时加了标识符g
console.log(reg.lastIndex)
// lastIndex : 0

console.log(reg.exec(str))
// ["123", index: 3, input: "abc123cba456aaa789"]
console.log(reg.lastIndex)
// lastIndex : 6

console.log(reg.exec(str))
// ["456", index: 9, input: "abc123cba456aaa789"]
console.log(reg.lastIndex)
// lastIndex : 12

console.log(reg.exec(str))
// ["789", index: 15, input: "abc123cba456aaa789"]
console.log(reg.lastIndex)
// lastIndex : 18

console.log(reg.exec(str))
// null
console.log(reg.lastIndex)
// lastIndex : 0

每次调用exec方法时,捕获到的字符串都不相同
lastIndex :这个属性记录的就是下一次捕获从哪个索引开始。
当未开始捕获时,这个值为0
如果当前次捕获结果为null。那么lastIndex的值会被修改为0.下次从头开始捕获。
而且这个lastIndex属性还支持人为赋值。

exec的捕获还受分组()的影响

1
2
3
4
5
var str = '2017-01-05';
var reg = /-(\d+)/g
// ["-01", "01", index: 4, input: "2017-01-05"]
"-01" : 正则捕获到的内容
"01" : 捕获到的字符串中的小分组中的内容

str.match(reg) 如果匹配成功,就返回匹配成功的数组,如果匹配不成功,就返回null

1
2
3
4
5
6
7
//match和exec的用法差不多
var str = 'abc123cba456aaa789';
var reg = /\d+/;
console.log(reg.exec(str));
//["123", index: 3, input: "abc123cba456aaa789"]
console.log(str.match(reg));
//["123", index: 3, input: "abc123cba456aaa789"]

上边两个方法console的结果有什么不同呢?二个字符串是一样滴。
当我们进行全局匹配时,二者的不同就会显现出来了.

1
2
3
4
5
6
var str = 'abc123cba456aaa789';
var reg = /\d+/g;
console.log(reg.exec(str));
// ["123", index: 3, input: "abc123cba456aaa789"]
console.log(str.match(reg));
// ["123", "456", "789"]

str.replace() 这个方法大家肯定不陌生,现在我们要说的就是和这个方法和正则相关的东西了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
正则去匹配字符串,匹配成功的字符去替换成新的字符串
写法:str.replace(reg,newStr);

var str = 'a111bc222de';
var res = str.replace(/\d/g,'Q')
console.log(res)
// "aQQQbcQQQde"

replace的第二个参数也可以是一个函数
str.replace(reg,fn);

var str = '2017-01-06';
str = str.replace(/-\d+/g,function(){
console.log(arguments)
})

控制台打印结果:
["-01", 4, "2017-01-06"]
["-06", 7, "2017-01-06"]
"2017undefinedundefined"
从打印结果我们发现每一次输出的值似乎跟exec捕获时很相似,既然与exec似乎很相似,那么似乎也可以打印出小分组中的内容喽

var str = '2017-01-06';
str = str.replace(/-(\d+)/g,function(){
console.log(arguments)
})
["-01", "01", 4, "2017-01-06"]
["-06", "06", 7, "2017-01-06"]
"2017undefinedundefined"
从结果看来我们的猜测没问题。

此外,我们需要注意的是,如果我们需要替换replace中正则找到的字符串,函数中需要一个返回值去替换正则捕获的内容。

通过replace方法获取url中的参数的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(function(pro){
function queryString(){
var obj = {},
reg = /([^?&#+]+)=([^?&#+]+)/g;
this.replace(reg,function($0,$1,$2){
obj[$1] = $2;
})
return obj;
}
pro.queryString = queryString;
}(String.prototype));

// 例如 url为 https://www.baidu.com?a=1&b=2
// window.location.href.queryString();
// {a:1,b:2}

零宽断言

用于查找在某些内容(但并不包括这些内容)之前或之后的东西,如\b,^,$那样用于指定一个位置,这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言。
在使用正则表达式时,捕获的内容前后必须是特定的内容,而我们又不想捕获这些特定内容的时候,零宽断言就可以派上用场了。

零宽度正预测先行断言 (?=exp)
零宽度负预测先行断言 (?!exp)
零宽度正回顾后发断言 (?<=exp)
零宽度负回顾后发断言 (?<!exp)

这四胞胎看着名字好长,给人一种好复杂好难的感觉,我们还是挨个来看看它们究竟是干什么的吧。

(?=exp) 这个简单理解就是说字符出现的位置的右边必须匹配到exp这个表达式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var str = "i'm singing and dancing";
var reg = /\b(\w+(?=ing\b))/g
var res = str.match(reg);
console.log(res)
// ["sing", "danc"]


注意一点,这里说到的是位置,不是字符。
var str = 'abc';
var reg = /a(?=b)c/;
console.log(res.test(str)); // false

// 这个看起来似乎是正确的,实际上结果是false
reg中a(?=b)匹配字符串'abc' 字符串a的右边是b这个匹配没问题,接下来reg中a(?=b)后边的c匹配字符串时是从字符串'abc'中a的后边b的前边的这个位置开始匹配的,
这个相当于/ac/匹配'abc',显然结果是false

(?!exp) 这个就是说字符出现的位置的右边不能是exp这个表达式。

1
2
3
var str = 'nodejs';
var reg = /node(?!js)/;
console.log(reg.test(str)) // false

(?<=exp) 这个就是说字符出现的位置的前边是exp这个表达式。

1
2
3
var str = '¥998$888';
var reg = /(?<=\$)\d+/;
console.log(reg.exec(str)) //888

(?<!exp) 这个就是说字符出现的位置的前边不能是exp这个表达式。

1
2
3
var str = '¥998$888';
var reg = /(?<!\$)\d+/;
console.log(reg.exec(str)) //998

CSS样式整理清单(2)

元素占满整个屏幕

heigth如果使用100%,会根据父级的高度来决定,所以使用100vh单位。

1
2
3
4
.dom{
width:100%;
height:100vh;
}

CSS实现文本两端对齐

1
2
3
4
5
6
7
.wrap {
text-align: justify;
text-justify: distribute-all-lines; //ie6-8
text-align-last: justify; //一个块或行的最后一行对齐方式
-moz-text-align-last: justify;
-webkit-text-align-last: justify;
}

实现文字竖向排版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 单列展示时
.wrap {
width: 25px;
line-height: 18px;
height: auto;
font-size: 12px;
padding: 8px 5px;
word-wrap: break-word;/*英文的时候需要加上这句,自动换行*/
}
// 多列展示时
.wrap {
height: 210px;
line-height: 30px;
text-align: justify;
writing-mode: vertical-lr; //从左向右
writing-mode: tb-lr; //IE从左向右
//writing-mode: vertical-rl; -- 从右向左
//writing-mode: tb-rl; -- 从右向左
}

使元素鼠标事件失效

1
2
3
4
5
.wrap {
// 如果按tab能选中该元素,如button,然后按回车还是能执行对应的事件,如click。
pointer-events: none;
cursor: default;
}

禁止用户选择

1
2
3
4
5
6
7
8
.wrap {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}

使用硬件加速

在浏览器中用css开启硬件加速,使GPU (Graphics Processing Unit) 发挥功能,从而提升性能。
硬件加速在移动端尤其有用,因为它可以有效的减少资源的利用。
目前主流浏览器会检测到页面中某个DOM元素应用了某些CSS规则时就会开启,最显著的特征的元素的3D变换。
如果不使用3D变形,我们可以通过下面方式来开启:

1
2
3
.wrap {
transform: translateZ(0);
}

页面动画出现闪烁问题

在 Chrome and Safari中,当我们使用CSS transforms 或者 animations时可能会有页面闪烁的效果,下面的代码可以修复此情况:

1
2
3
4
5
6
7
8
.cube {
-webkit-backface-visibility: hidden;
backface-visibility: hidden;

-webkit-perspective: 1000;
perspective: 1000;
/* Other transform properties here */
}

在webkit内核的浏览器中,另一个行之有效的方法是

1
2
3
4
5
.cube {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
/* Other transform properties here */
}

字母大小写转换

1
2
3
4
p {text-transform: uppercase}  // 将所有字母变成大写字母
p {text-transform: lowercase} // 将所有字母变成小写字母
p {text-transform: capitalize} // 首字母大写
p {font-variant: small-caps} // 将字体变成小型的大写字母

将一个容器设为透明

1
2
3
4
5
6
.wrap { 
filter:alpha(opacity=50);
-moz-opacity:0.5;
-khtml-opacity: 0.5;
opacity: 0.5;
}

消除transition闪屏

1
2
3
4
5
.wrap {
-webkit-transform-style: preserve-3d;
-webkit-backface-visibility: hidden;
-webkit-perspective: 1000;
}

识别字符串里的 ‘\n’ 并换行

一般在富文本中返回换行符不是
的标签,而且\n。不使用正则转换的情况下,可通过下面样式实现换行。

1
2
3
body {
white-space: pre-line;
}

移除a标签被点链接的边框

1
2
3
4
a {
outline: none;//或者outline: 0
text-decoration:none; //取消默认下划线
}

CSS显示链接之后的URL

1
2
3
4
<a href="//www.webqdkf.com">有课前端网</a>
<style>
a:after {content: " (" attr(href) ")";}
</style>

select内容居中显示、下拉内容右对齐

1
2
3
4
5
6
7
select{
text-align: center;
text-align-last: center;
}
select option {
direction: rtl;
}

修改input输入框中光标的颜色不改变字体的颜色

1
2
3
4
input{
color: #fff;
caret-color: red;
}

子元素固定宽度 父元素宽度被撑开

1
2
3
4
5
6
7
8
9
// 父元素下的子元素是行内元素
.wrap {
white-space: nowrap;
}
// 若父元素下的子元素是块级元素
.wrap {
white-space: nowrap; // 子元素不被换行
display: inline-block;
}

让div里的图片和文字同时上下居中

这里不使用flex布局的情况。通过vertival-align

1
2
3
4
5
6
7
8
9
.wrap {
height: 100,
line-height: 100
}
img {
vertival-align:middle
}
// vertical-align css的属性vertical-align用来指定行内元素(inline)或表格单元格(table-cell)元素的垂直对齐方式。只对行内元素、表格单元格元素生效,不能用它垂直对齐块级元素
// vertical-align:baseline/top/middle/bottom/sub/text-top;

实现宽高等比例自适应矩形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.scale {
width: 100%;
padding-bottom: 56.25%;
height: 0;
position: relative;
}
.item {
position: absolute;
width: 100%;
height: 100%;
background-color: 499e56;
}
<div class="scale">
<div class="item">
这里是所有子元素的容器
</div>
</div>

transfrom的rotate属性在span标签下失效

1
2
3
span {
display: inline-block
}

CSS加载动画

主要是通过css旋转动画的实现:

1
2
3
4
5
6
7
.dom{
-webkit-animation:circle 1s infinite linear;
}
@keyframes circle{
0%{ transform: rotate(0deg); }
100%{ transform: rotate(360deg); }
}

文字渐变效果实现

1
2
3
4
5
6
7
8
9
<div class="text_signature " >fly63前端网,一个免费学习前端知识的网站</div>
<style>
.text_signature {
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-image: linear-gradient(to right, #ec2239, #40a4e2,#ea96f5);
width: 320px;
}
</style>

好看的边框阴影

1
2
3
4
5
6
7
8
<div class="text_shadow"></div>
<style>
.text_shadow{
width:500px;
height:100px;
box-shadow: 0px 0px 13px 1px rgba(51, 51, 51, 0.1);
}
</style>

好看的背景渐变

1
2
3
4
5
6
7
8
<div class="text_gradient"></div>
<style>
.text_gradient{
width:500px;
height:100px;
background: linear-gradient(25deg, rgb(79, 107, 208), rgb(98, 141, 185), rgb(102, 175, 161), rgb(92, 210, 133)) rgb(182, 228, 253);
}
</style>

实现立体字的效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div class="text_solid">世界那么大我想去看看</div>
<style>
.text_solid{
font-size: 32px;
text-align: center;
font-weight: bold;
line-height:100px;
text-transform:uppercase;
position: relative;
background-color: #333;
color:#fff;
text-shadow:
0px 1px 0px #c0c0c0,
0px 2px 0px #b0b0b0,
0px 3px 0px #a0a0a0,
0px 4px 0px #909090,
0px 5px 10px rgba(0, 0, 0, 0.6);
}
</style>

全屏背景图片的实现

1
2
3
4
5
6
7
8
9
10
11
12
.swiper{
background-image: url(./img/bg.jpg);
width:100%;
height:100%;//父级高不为100%请使用100vh
zoom: 1;
background-color: #fff;
background-repeat: no-repeat;
background-size: cover;
-webkit-background-size: cover;
-o-background-size: cover;
background-position: center 0;
}

实现文字描边的2种方法

方式一:

1
2
3
4
.stroke {
-webkit-text-stroke: 1px greenyellow;
text-stroke: 1px greenyellow;
}

方式2:

1
2
3
4
5
6
.stroke {
text-shadow:#000 1px 0 0,#000 0 1px 0,#000 -1px 0 0,#000 0 -1px 0;
-webkit-text-shadow:#000 1px 0 0,#000 0 1px 0,#000 -1px 0 0,#000 0 -1px 0;
-moz-text-shadow:#000 1px 0 0,#000 0 1px 0,#000 -1px 0 0,#000 0 -1px 0;
*filter: Glow(color=#000, strength=1);
}

元素透明度的实现

1
2
3
4
.dom{
opacity:0.4;
filter:alpha(opacity=40); /* IE8 及其更早版本 */
}

解决1px边框变粗问题

出现1px变粗的原因,比如在2倍屏时1px的像素实际对应2个物理像素。

1
2
3
4
5
.dom{
height: 1px;
background: #dbdbdb;
transform:scaleY(0.5);
}

CSS不同单位的运算

css自己也能够进行简单的运算,主要是用到了calc这个函数。实现不同单位的加减运算:

1
2
3
.div{ 
width: calc(100% - 50px);
}

CSS实现文字模糊效果

1
2
3
4
.vague_text{
color: transparent;
text-shadow: #111 0 0 5px;
}

通过滤镜让图标变灰

一张彩色的图片就能实现鼠标移入变彩色,移出变灰的效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<a href='' class='icon'><img src='01.jpg' /></a>
<style>
.icon{
-webkit-filter: grayscale(100%);
-moz-filter: grayscale(100%);
-ms-filter: grayscale(100%);
-o-filter: grayscale(100%);
filter: grayscale(100%);
filter: gray;
}
.icon:hover{
filter: none;
-webkit-filter: grayscale(0%);
}
</style>

图片自适应object-fit

当图片比例不固定时,想要让图片自适应,一般都会用background-size:cover/contain,但是这个只适用于背景图。
css3中可使用object-fit属性来解决图片被拉伸或是被缩放的问题。使用的提前条件:图片的父级容器要有宽高。

1
2
3
4
5
img{
width: 100%;
height: 100%;
object-fit: cover;
}

fill: 默认值。内容拉伸填满整个content box, 不保证保持原有的比例。
contain: 保持原有尺寸比例。长度和高度中长的那条边跟容器大小一致,短的那条等比缩放,可能会有留白。
cover: 保持原有尺寸比例。宽度和高度中短的那条边跟容器大小一致,长的那条等比缩放。可能会有部分区域不可见。
none: 保持原有尺寸比例。同时保持替换内容原始尺寸大小。
scale-down:保持原有尺寸比例,如果容器尺寸大于图片内容尺寸,保持图片的原有尺寸,不会放大失真;容器尺寸小于图片内容尺寸,用法跟contain一样。

行内标签元素出现间隙问题

方式一:父级font-size设置为0

1
2
3
.father{
font-size:0;
}

方式二:父元素上设置word-spacing的值为合适的负值

CSS实现文字模糊效果

1
2
3
.father{
word-spacing:-2px
}

其它方案:1将行内元素写为1行(影响阅读);2使用浮动样式(会影响布局)。

解决vertical-align属性不生效

在使用vertical-align:middle实现垂直居中的时候,经常会发现不生效的情况。这里需要注意它生效需要满足的条件:

作用环境:父元素设置line-height。需要和height一致。或者将display属性设置为table-cell,将块元素转化为单元格。
作用对象:子元素中的inline-block和inline元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div class="box">
<img src=".\test.jpg"/>
<span>内部文字</span>
</div>
<style>
.box{
width:300px;
line-height: 300px;
font-size: 16px;
}
.box img{
width: 30px;
height:30px;
vertical-align:middle
}
.box span{
vertical-align:middle
}
</style>

vertical-align不可继承,必须对子元素单独设置。同时需要注意的是line-height的高度基于font-size(即字体的高度),如果文字要转行会出现异常。

CSS样式整理清单

文字超出部分显示省略号

单行文本的溢出显示省略号(一定要有宽度)

1
2
3
4
5
6
p{
width:200rpx;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
}

多行文本溢出显示省略号

1
2
3
4
5
6
 p {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
}

中英文自动换行

word-break:break-all;只对英文起作用,以字母作为换行依据word-wrap:break-word;
只对英文起作用,以单词作为换行依据white-space:pre-wrap; 只对中文起作用,强制换行white-space:nowrap; 强制不换行,都起作用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
p{
word-wrap: break-word;
white-space: normal;
word-break: break-all;
}
//不换行
.wrap {
white-space:nowrap;
}
//自动换行
.wrap {
word-wrap: break-word;
word-break: normal;
}
//强制换行
.wrap {
word-break:break-all;
}

文字阴影

text-shadow 为网页字体添加阴影,通过对text-shadow属性设置相关的属性值。
属性与值的说明如下:text-shadow: [X-offset,Y-offset,Blur,Color];

X-offset:指阴影居于字体水平偏移的位置。
Y-offset:指阴影居于字体垂直偏移的位置。
Blur:指阴影的模糊值。
color:指阴影的颜色;

1
2
3
 h1{
text-shadow: 5px 5px 5px #FF0000;
}

设置placeholder的字体样式

1
2
3
4
5
6
7
8
9
10
11
12
  input::-webkit-input-placeholder { /* Chrome/Opera/Safari */
color: red;
}
input::-moz-placeholder { /* Firefox 19+ */
color: red;
}
input:-ms-input-placeholder { /* IE 10+ */
color: red;
}
input:-moz-placeholder { /* Firefox 18- */
color: red;
}

不固定高宽 div 垂直居中的方法

方法一:伪元素和 inline-block / vertical-align(兼容 IE8)

1
2
3
4
5
6
7
8
9
10
11
.box-wrap:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -0.25em;
}
.box {
display: inline-block;
vertical-align: middle;
}

方法二:flex(不兼容 ie8 以下)

1
2
3
4
5
6
7
.box-wrap {
height: 300px;
justify-content:center;
align-items:center;
display:flex;
background-color:#666;
}

方法三:transform(不兼容 ie8 以下)

1
2
3
4
5
6
7
8
9
10
11
12
13
 .box-wrap {
width:100%;
height:300px;
background:rgba(0,0,0,0.7);
position:relative;
}
.box{
position:absolute;
left:50%;
top:50%;
transform:translateX(-50%) translateY(-50%);
-webkit-transform:translateX(-50%) translateY(-50%);
}

方法四:设置 margin:auto(该方法得严格意义上的非固定宽高,而是 50%的父级的宽高。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.box-wrap {
position: relative;
width:100%;
height:300px;
background-color:#f00;
}
.box-content{
position: absolute;
top:0;
left:0;
bottom:0;
right:0;
width:50%;
height:50%;
margin:auto;
background-color:#ff0;
}

解决IOS页面滑动卡顿

1
2
3
body,html{
-webkit-overflow-scrolling: touch;
}

设置滚动条样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
.test::-webkit-scrollbar{
/*滚动条整体样式*/
width : 10px; /*高宽分别对应横竖滚动条的尺寸*/
height: 1px;
}
.test::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius : 10px;
background-color: skyblue;
background-image: -webkit-linear-gradient(
45deg,
rgba(255, 255, 255, 0.2) 25%,
transparent 25%,
transparent 50%,
rgba(255, 255, 255, 0.2) 50%,
rgba(255, 255, 255, 0.2) 75%,
transparent 75%,
transparent
);
}
.test::-webkit-scrollbar-track {
/*滚动条里面轨道*/
box-shadow : inset 0 0 5px rgba(0, 0, 0, 0.2);
background : #ededed;
border-radius: 10px;
}

实现隐藏滚动条同时又可以滚动

1
2
3
4
5
6
7
8
9
10
.demo::-webkit-scrollbar {
display: none; /* Chrome Safari */
}

.demo {
scrollbar-width: none; /* firefox */
-ms-overflow-style: none; /* IE 10+ */
overflow-x: hidden;
overflow-y: auto;
}

css 绘制三角形(通过透明(transparent)来控制三角方向)

1
2
3
4
5
6
7
div {
width: 0;
height: 0;
border-width: 0 40px 40px;
border-style: solid;
border-color: transparent transparent red;
}

实现带边框的三角形:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div id="blue"><div>

#blue {
position:relative;
width: 0;
height: 0;
border-width: 0 40px 40px;
border-style: solid;
border-color: transparent transparent blue;
}
#blue:after {
content: "";
position: absolute;
top: 1px;
left: -38px;
border-width: 0 38px 38px;
border-style: solid;
border-color: transparent transparent yellow;
}

注: 如果想绘制右直角三角,则将左 border 设置为 0;如果想绘制左直角三角,将右 border 设置为 0 即可(其它情况同理)。

Table表格边框合并

1
2
3
4
5
6
table,tr,td{
border: 1px solid #666;
}
table{
border-collapse: collapse;
}

css 选取第 n 个标签元素

1
2
3
4
5
6
7
8
 first-child 表示选择列表中的第一个标签。
last-child last-child 表示选择列表中的最后一个标签
nth-child(3) 表示选择列表中的第 3 个标签
nth-child(2n) 这个表示选择列表中的偶数标签
nth-child(2n-1) 这个表示选择列表中的奇数标签
nth-child(n+3) 这个表示选择列表中的标签从第 3 个开始到最后。
nth-child(-n+3) 这个表示选择列表中的标签从 0 到 3,即小于 3 的标签。
nth-last-child(3) 这个表示选择列表中的倒数第 3 个标签。

移动端软键盘变为搜索方式

默认情况下软键盘上该键位为前往或者确认等文字,要使其变为搜索文字,需要在 input 上加上 type 声明:

1
2
3
<form action="#">
<input type="search" placeholder="请输入..." name="search" />
</form>

需要一个 form 标签套起来,并且设置 action 属性,这样写完之后输入法的右下角就会自动变成搜索,同时,使用了 search 类型后,搜索框上会默认自带删除按钮。

onerror 处理图片异常

使用 onerror 异常处理时,若 onerror 的图片也出现问题,则图片显示会陷入死循环,所以要在赋值异常图片之后,将地址置空

1
<img onerror="this.src='url;this.onerror=null'" />

背景图片的大小

1
2
3
4
5
6
.bg-img{
background:url(../img/find_pw_on_2.png) no-repeat center center !important;
background-size: 27px auto !important;
/*background-size: 100% 100%;*/
/*background-size: 50px 100px*/
}

文字之间的间距

单词text-indent抬头距离,letter-spacing字与字间距

1
2
3
4
p{
text-indent:10px;//单词抬头距离
letter-spacing:10px;//间距
}

网页版word编译器插件以及layui时间插件使用

富文本编辑器

指定容器引入

1
2
3
4
5
<div>
type="text/javascript" src="../ueditor/ueditor.config.js"
type="text/javascript" src="../ueditor/ueditor.all.js"
<script id="container" name="content" type="text/plain"></script>
</div>

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 在全局注册
var ue = null;
// 富文本编辑器初始化 在渲染结束后初始化
ue = UE.getEditor('container', {
// initialFrameWidth: 800,
initialFrameHeight: 400,
toolbars: [
['fullscreen', 'undo', 'redo', 'formatmatch', 'removeformat', '|',
'fontsize', 'bold', 'italic', 'underline', 'forecolor', 'backcolor',
'|',
'justifyleft', 'justifycenter', 'justifyright', '|',
'rowspacingtop', 'rowspacingbottom', 'lineheight', '|',
'insertorderedlist', 'insertunorderedlist', '|',
'imagenone', 'imageleft', 'imageright', 'imagecenter', '|',
'simpleupload', 'attachment', '|', 'inserttable', 'deletetable',
'insertparagraphbeforetable', 'insertrow', 'deleterow', 'insertcol',
'deletecol', 'mergecells', 'mergeright', 'mergedown',
'splittocells', 'splittorows', 'splittocols', '|', 'drafts'
]
],
autoHeightEnabled: true,
autoFloatEnabled: true
});


方法

1
2
3
4
5
// 设置初始内容
ue.setContent("内容");

// 获取内容
ue.getContent();

layui时间插件

1
2
3
4
5
6
7
8
9
10
11
12
13
var _this = this;
layui.use(['laydate'], function () {
var laydate = layui.laydate;
laydate.render({
elem: "#app", //指定元素
theme: "#000", //主题色
done: function (value, date) {
// 选择时间的回调
console.log(value,date)
}
});
});

西瓜视频插件使用

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
    let player = new Player({
id: 'xgVideo',
url: './video.mp4',
poster: './show_img_2.png', //设置封面图
playbackRate: [0.5, 0.75, 1, 1.5, 2], //传入倍速可选数组
defaultPlaybackRate: 1, //默认倍速
width: 800,
height: 400,
fluid: true, //流式布局,可使播放器宽度跟随父元素的宽度大小变化,且高度按照配置项中的高度和宽度的比例来变化(播放器宽高未设置时按照内部默认值来计算)。
// fitVideoSize: 'fixHeight', //1、fitVideoSize设置为fixWidth,表示容器宽度固定,容器高度按照视频内容比例增大或减小;2、fitVideoSize设置为fixHeight,表示容器高度固定,容器宽度按照视频内容比例增大或减小;3、fitVideoSize设置为auto,表示容器高度或宽度按照视频内容比例增大。
volume: 0.6, //音量大小
autoplay: true, //自动播放
loop: false, //循环播放
videoInit: false, //设置视频初始帧 该配置与autoplay配置项不可同时设置为true。该配置在移动端无效。
//lastPlayTime: 10, //视频起播时间(单位:秒)播放器支持设置视频起播时间。
//lastPlayTimeHideDelay: 5, //提示文字展示时长(单位:秒)
rotateFullscreen: true, //部分移动端场景的系统默认全屏功能不支持横屏,播放器支持通过配置 rotateFullscreen: true 使触发全屏时实现样式横屏全屏。使用该配置时不需配置rotate和cssFullscreen。
// 视频跳转播放下一集,需提供视频资源列表。
// playNext: {
// urlList: [
// 'url1',
// 'url2',
// 'url3'
// ],
// },
download: true, //下载控件
controls: true,//关闭控制键
pip: true, //小屏画中画
screenShot: true, //截图
keyShortcut: 'on', //键盘快捷键可通过该配置项开启键盘快捷键:按 → 键快进10秒, 按 ← 键后退10秒,按 ↑ 键调高音量,按 ↓ 键调低音量,按 space 键切换播放/暂停状态。
errorTips: `请<span>刷新</span>试试`, //自定义错误提示
// 播放器使用自执行的插件机制,如需要在插件生效前执行某些方法,开发者可将相关方法写在execBeforePluginsCall配置项数组中
execBeforePluginsCall: [() => {
console.log('Execute before plugins call')
}],

danmu: {
panel: true, //弹幕控制面板
comments: [ //弹幕数组
{
duration: 15000, //弹幕持续显示时间,毫秒(最低为5000毫秒)
id: '1', //弹幕id,需唯一
start: 3000, //弹幕出现时间,毫秒
prior: true, //该条弹幕优先显示,默认false
color: true, //该条弹幕为彩色弹幕,默认false
txt: '长弹幕长弹幕长弹幕长弹幕长弹幕长弹幕长弹幕长弹幕长弹幕长弹幕', //弹幕文字内容
style: { //弹幕自定义样式
color: '#ff9500',
fontSize: '20px',
border: 'solid 1px #ff9500',
borderRadius: '50px',
padding: '5px 11px',
backgroundColor: 'rgba(255, 255, 255, 0.1)'
},
mode: 'scroll' //显示模式,top顶部居中,bottom底部居中,scroll滚动,默认为scroll
// el: DOM //直接传入一个自定义的DOM元素作为弹幕,使用该项的话会忽略所提供的txt和style
// eventListeners: [{ //支持自定义DOM设置DOM监听事件
// event: 'click',
// listener: function (e) {
// console.log('click')
// },
// useCapture: false,
// }]
}
],
area: { //弹幕显示区域
start: 0, //区域顶部到播放器顶部所占播放器高度的比例
end: 1 //区域底部到播放器顶部所占播放器高度的比例
},
closeDefaultBtn: true, //开启此项后不使用默认提供的弹幕开关,默认使用西瓜播放器提供的开关
defaultOff: false //开启此项后弹幕不会初始化,默认初始化弹幕
}

// player.danmu.start() //弹幕初始化并播放(内部默认已调用)
// player.danmu.pause() //弹幕暂停
// player.danmu.play() //弹幕继续播放
// player.danmu.stop() //弹幕停止并消失
// player.danmu.sendComment({ //发送弹幕
// duration: 15000,
// id: 'id',
// start: 3000,
// txt: '弹幕内容',
// style: {
// color: '#ff9500',
// fontSize: '20px',
// border: 'solid 1px #ff9500',
// borderRadius: '50px',
// padding: '5px 11px',
// backgroundColor: 'rgba(255, 255, 255, 0.1)'
// }
// })
// player.danmu.setCommentDuration(id, duration) //按照id改变某一个弹幕的持续显示时间
// player.danmu.setAllDuration(mode, duration) //改变所有已加入队列弹幕的持续显示时间
// player.danmu.setCommentID(oldID, newID) //改变某一个弹幕的id
// player.danmu.hide(mode) //屏蔽某一类弹幕(参数可选值 scroll | top | bottom | color)
// player.danmu.show(mode) //显示某一类弹幕(参数可选值 scroll | top | bottom | color)
});

事件

play播放  playing继续播放  pause暂停 ended视频结束  error视频错误 seeking seek播放
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 // 永久注册 
// 结束回调 在配置为loop为true时无效
player.on('ended',function(){
alert("end")
})
// 一次注册
player.once('事件名',function(){

})
// 事件注销
player.off('事件名',function(){

})
// 时间触发
player.emit('事件名')

生命周期

1
2
3
4
5
6
7
8
9
10
11
12
// 生命周期
// 实例化完成
// 播放器调用Player进行实例化,实例化结束后会触发 ready 事件,通过对 ready 的监听可以确定实例化是否完成。实例化主要包括自定义UI生成、事件绑定、插件化实例化工作。
player.once('ready',()=>{console.log('ready')})

// 视频生成结束
// 考虑到节约视频流量和HTTP连接数的限制,PC端播放器在实例化的时候只是UI生效并未生成video视频,只有点击播放后才会创建video标签拉取视频进行播放。如果想捕获创建video的时机,监听 complete 事件。
player.once('complete',()=>{console.log('complete')})

// 实例已销毁
// 播放器在销毁实例的时候会触发 destroy 事件
player.once('destroy',()=>{console.log('destroy')})

ready事件和complete事件是在实例化的时候已经触发,为了保证“后监听”方式能捕获到事件,请勿使用异步操作来监听,如setTimeout、Promise等,如果需要使用这些异步操作,请在响应函数内完成。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 错误的方式
let player=new Player({/*配置*/});
setTimeout(function () {
player.once('ready',()=>{console.log('ready')})
}, 1000);


// 正确的方式

let player=new Player({/*配置*/});
player.once('ready',()=>{
setTimeout(function () {
console.log('ready')
}, 1000);
})

插件使用

Waves

引入css和js配置

wavesList中配置相关类名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//按钮 配置点击水纹
( function(){
setTimeout(function () {
var config = {
duration: 1000,
delay: 100,
};
Waves.init(config);
var wavesList = [
"he_tr_add ",
"he_tr_btn_info",
"he_btn_info",
]
for(let i = 0; i < wavesList.length; i++){
wavesList[i] = '.'+wavesList[i]
Waves.attach(wavesList[i], 'waves-light');
// Waves.attach(wavesList[i], 'waves-black');
}
// console.log("waves!初始化完毕!")
}, 1000);
})()

jsmind 思维导图

引入 ../js/jsmind-master/style/jsmind.css 和 ../js/jsmind-master/js/jsmind.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// js 思维导图
jsMind: function () {
var _this = this;
var mind = {
/* 元数据,定义思维导图的名称、作者、版本等信息 */
"meta": {
"name": "",
"author": "",
"version": ""
},
/* 数据格式声明 */
"format": "node_tree",
/* 数据内容 */
"data": this.data

};
var options = { // options
container: 'main', // [必选] 容器的ID,或者为容器的对象
editable: true, // [可选] 是否启用编辑
theme: 'belizehole', // [可选] 主题
support_html: false,
view: {
engine: 'canvas', // 思维导图各节点之间线条的绘制引擎
hmargin: 100, // 思维导图距容器外框的最小水平距离
vmargin: 50, // 思维导图距容器外框的最小垂直距离
line_width: 2, // 思维导图线条的粗细
line_color: '#cccccc' // 思维导图线条的颜色
},
};
var jm = new jsMind(options);
jm.show(mind);
},


// 数据渲染完成之后 再更新
this.jsMind();
this.jm = jsMind.current;

// 获取当前选择的节点
get_selected_nodeid: function () {
var selected_node = this.jm.get_selected_node();
if (!!selected_node) {
return selected_node.id;
} else {
return null;
}
},

// 删除
jm_del: function () {
var _this = this;
var selected_node = this.jm.get_selected_node();
var selected_id = this.get_selected_nodeid();
if (!selected_id) {
alert('请选中一个节点来进行添加操作');
return;
}
console.log(selected_id, selected_node.data.u_id);
this.jm.remove_node(selected_id);
},

// 新增子级
jm_add_child: function () {
var _this = this
var selected_node = this.jm.get_selected_node(); // as parent of new node
if (!selected_node) {
alert('请选中一个节点来进行添加操作');
return;
}
var nodeid = jsMind.util.uuid.newid();
var topic = '请输入名称';
console.log(selected_node);
},

notyf 轻提示

引入min.css和min.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
  this.notyf = new Notyf({
// 持续时间
duration:2000,
// 是否显示关闭
dismissible:true,
// 位置
position:{
x:'center',
y:'top'
},
// 自定义框的颜色图标
types:[
{ duration:0,
type:'a',
dismissible:true,
background:'#f99',
color:'#fff',
icon:{
className:'',
tagName:'i'
}
}
]
});

// 用法
this.notyf.open({
type:'a',
message:'sssssssssssssssssssssssss'
})
this.notyf.success({
message:'sssssssssssssssssssssssss'
})
this.notyf.error({
message:'sssssssssssssssssssssssss'
})

常用js技巧

1,声明变量

1
let x, y = 20;

2,给多个变量赋值

1
let [a, b, c] = [5, 8, 12];

3,三元运算符

1
2
3
4
5
6
7
8
9
10
//Longhand
let marks = 26;
let result;
if(marks >= 30){
result = 'Pass';
}else{
result = 'Fail';
}
//Shorthand
let result = marks >= 30 ? 'Pass' : 'Fail';

4,默认值

如果预期值不正确的情况下,我们可以使用 OR(||) 短路运算来给一个变量赋默认值。

1
2
//Shorthand
let imagePath = getImagePath() || 'default.jpg';

5,与运算

如果你只有当某个变量为 true 时调用一个函数,那么你可以使用与 (&&)短路形式书写。

1
2
3
4
5
6
//Longhand
if (isLoggedin) {
goToHomepage();
}
//Shorthand
isLoggedin && goToHomepage();

6,双非位运算符 (~~)

向下取整 是Math.floor()方法的缩写。
双非位运算符只对 32 位整数有效,例如 (2**31)-1 = 2147483647。
所以对于任何大于 2147483647 的数字,双非位运算符 (~~) 都会给出错误的结果,这种情况下推荐使用 Math.floor() 方法。

1
2
3
4
//Longhand
const floor = Math.floor(6.8); // 6
// Shorthand
const floor = ~~6.8; // 6

7,找出数组中的最大和最小数字

1
2
3
const arr = [2, 8, 15, 4];
Math.max(...arr); // 15
Math.min(...arr); // 2

8,For 循环

为了遍历一个数组,我们一般使用传统的for循环。
我们可以使用for…of来遍历数组。为了获取每个值的索引,我们可以使用for…in循环。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let arr = [10, 20, 30, 40];
//Longhand
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
//Shorthand
//for of loop
for (const val of arr) {
console.log(val);
}
//for in loop
for (const index in arr) {
console.log(arr[index]);
}
// 我们还可以使用for...in循环来遍历对象属性。
let obj = {x: 20, y: 50};
for (const key in obj) {
console.log(obj[key]);
}

9,合并数组

1
2
3
4
5
6
7
let arr1 = [20, 30];
//Longhand
let arr2 = arr1.concat([60, 80]);
// [20, 30, 60, 80]
//Shorthand
let arr2 = [...arr1, 60, 80];
// [20, 30, 60, 80]

promise封装ajax

用Promise封装一个AJAX函数

AJAX即“Asynchronous JavaScript and XML”(异步的JavaScript与XML技术),
AJAX的优点是不重载当前页面的情况下,可以向服务器请求新内容。

发起AJAX的过程:

1,创建XMLHttpRequest对象

1
const xhr = new XMLHttpRequest();

2,监听xhr的readyState变化

1
2
3
4
5
6
7
8
9
10
11
    xhr.onreadystatechange = function () {
// readyState为4的时候已接收完毕
if (xhr.readyState === 4) {
// 状态码200表示成功
if (xhr.status === 200) {
console.log(xhr.responseText);
} else {
console.log(xhr.status);
}
}
};

3,open 规划请求参数

1
2
3
4
// method  Get Post
// URL 请求地址
// bool 是否异步
xhr.open(method, url, true);

4,send 发送请求

1
xhr.send();

利用promise封装

接下来,用Promise简单的封装一个AJAX函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

function ajax(method, url, params) {
return new Promise((resolve, reject) => {
// 创建XMLHttpRequest对象
const xhr = new XMLHttpRequest();
// 状态改变时的回调
xhr.onreadystatechange = function () {
// readyState为4的时候已接收完毕
if (xhr.readyState === 4) {
// 状态码200表示成功
if (xhr.status === 200) {
resolve(xhr.responseText);
} else {
reject(xhr.status);
}
}
};

// get
if (method === 'get' || method === 'GET') {
if (typeof params === 'object') {
// params拆解成字符串
params = Object.keys(params).map(function (key) {
return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
}).join('&');
}
url = params ? url + '?' + params : url;
xhr.open(method, url, true);
xhr.send();
}

//post
if (method === 'post' || method === 'POST') {
xhr.open(method, url, true);
xhr.setRequestHeader("Content-type", "application/json; charset=utf-8");
xhr.send(JSON.stringify(params));
}
});
}


// 用法

ajax('GET' , '127.0.0.1/data.json', {
data:{
name:'www',
age:14,
}
}).then(res=>{
console.log(res);
})

2d看板娘

放到html中就可以用啦!

L2Dwidget.init初始化
要改的话需要更改 jsonPath 模板名称 https://unpkg.com/[模板全称]@1.0.5/assets/[模板名称].model.json

https://unpkg.com/【live2d-widget-model-shizuku】@1.0.5/assets/【shizuku】.model.json

所有的名称如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
https://unpkg.com/live2d-widget-model-chitose@1.0.5/assets/chitose.model.json 
https://unpkg.com/live2d-widget-model-haruto@1.0.5/assets/haruto.model.json
https://unpkg.com/live2d-widget-model-hibiki@1.0.5/assets/hibiki.model.json
https://unpkg.com/live2d-widget-model-hijiki@1.0.5/assets/hijiki.model.json
https://unpkg.com/live2d-widget-model-izumi@1.0.5/assets/izumi.model.json
https://unpkg.com/live2d-widget-model-koharu@1.0.5/assets/koharu.model.json
https://unpkg.com/live2d-widget-model-miku@1.0.5/assets/miku.model.json
https://unpkg.com/live2d-widget-model-ni-j@1.0.5/assets/ni-j.model.json
https://unpkg.com/live2d-widget-model-nico@1.0.5/assets/nico.model.json
https://unpkg.com/live2d-widget-model-nipsilon@1.0.5/assets/nipsilon.model.json
https://unpkg.com/live2d-widget-model-nito@1.0.5/assets/nito.model.json
https://unpkg.com/live2d-widget-model-shizuku@1.0.5/assets/shizuku.model.json
https://unpkg.com/live2d-widget-model-tororo@1.0.5/assets/tororo.model.json
https://unpkg.com/live2d-widget-model-tsumiki@1.0.5/assets/tsumiki.model.json
https://unpkg.com/live2d-widget-model-unitychan@1.0.5/assets/unitychan.model.json
https://unpkg.com/live2d-widget-model-wanko@1.0.5/assets/wanko.model.json
https://unpkg.com/live2d-widget-model-z16@1.0.5/assets/z16.model.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<script src="https://eqcn.ajz.miesnfu.com/wp-content/plugins/wp-3d-pony/live2dw/lib/L2Dwidget.min.js"></script>
<script>
L2Dwidget.init({
"model": {
jsonPath: "https://unpkg.com/live2d-widget-model-shizuku@1.0.5/assets/shizuku.model.json",
"scale": 1
},
"display": {
"position": "right",
"width": 150,
"height": 300,
"hOffset": 0,
"vOffset": -20
},
"mobile": {
"show": true,
"scale": 0.5
},
"react": {
"opacityDefault": 0.7,
"opacityOnHover": 0.2
}
});
</script>