0%

问题描述

当使用委托给一个元素添加click事件时,如果事件是委托到 document 或 body 上,并且委托的元素是默认不可点击的(如 div, span 等),此时 click 事件会失效。

解决办法

解决办法有 4 种可供选择:

​1.将 click 事件直接绑定到目标​元素(​​即 .target)上

2.将目标​元素换成或者button等可点击的​元素

3.​将click事件委托到​​​​​非document或body的​​父级元素上

4.​给​目标元素加一条样式规则cursor: pointer;

​推荐后两种。从解决办法来看,​推测在 safari 中,不可点击的元素的点击事件不会冒泡到父级元素。通过添加 cursor: pointer 使得元素变成了可点击的了。

concat

concat() 方法用于连接两个或多个数组。

该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。

arrayObject.concat(arrayX,arrayX,......,arrayX)

返回值

返回一个新的数组。该数组是通过把所有 arrayX 参数添加到 arrayObject 中生成的。如果要进行 concat() 操作的参数是数组,那么添加的是数组中的元素,而不是数组。

// create two arrays
var arr1 = ['a', 'b', 'c'];
var arr2 = ['d', 'e', 'f'];

/* call concat() on the first array passing
   the second as an argument */
var arr3 = arr1.concat(arr2);

// log the result
console.log(arr3);
// expected output: a,b,c,d,e,f    
阅读全文 »

入门
全局安装 gulp
$ npm install --global gulp
在项目中运用(git barsh)
$ npm install --save-dev gulp
在项目根目录下创建 gulpfile.js 文件
var gulp = require('gulp');

gulp.task('auto',function(){
    //默认执行的任务代码放在这里
})

然后使用下面命令即可:

$ gulp auto
阅读全文 »

服务器安装docker

yum install docker

安装jenkins

docker pull jenkins/jenkins:lts

查看已经安装的jenkins镜像

docker images

创建一个jenkins目录

mkdir /home/jenkins_home

启动一个jenkins容器

docker run -d --name jenkins_01 -p 8081:8080 -v /home/jenkins_01:/home/jenkins_01 jenkins/jenkins:lts

查看jenkins服务

docker ps

启动服务端:localhost:8081 (会需要jenkins密码)

进入容器内部

docker exec -it jenkins_01 bash;

执行(得到密码并粘贴过去):

cat /var/jenkins_home/secrets/initialAdminPassword

输入密码之后,重启docker镜像,安装完毕

docker restart 镜像ID

作者根据 Robert C. Martin 《代码整洁之道》总结了适用于 JavaScript 的软件工程原则《Clean Code JavaScript》

本文是对其的翻译。

不必严格遵守本文的所有原则,有时少遵守一些效果可能会更好,具体应根据实际情况决定。这是根据《代码整洁之道》作者多年经验整理的代码优化建议,但也仅仅只是一份建议。

软件工程已经发展了 50 多年,至今仍在不断前进。现在,把这些原则当作试金石,尝试将他们作为团队代码质量考核的标准之一吧。

最后你需要知道的是,这些东西不会让你立刻变成一个优秀的工程师,长期奉行他们也并不意味着你能够高枕无忧不再犯错。千里之行,始于足下。我们需要时常和同行们进行代码评审,不断优化自己的代码。不要惧怕改善代码质量所需付出的努力,加油。

阅读全文 »

防抖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function debounce(fn, delay) {
var delay1 = delay || 1000
var timer
return function () {
var th = this
var args = arguments
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(function () {
timer = null
fn.apply(th, args)
}, delay1)
}
}
节流
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function throttle(fn, interval) {
var last
var timer
var interval1 = interval || 2000
return function () {
var th = this
var args = arguments
var now = +new Date()
if (last && now - last < interval) {
clearTimeout(timer)
timer = setTimeout(function () {
last = now
fn.apply(th, args)
}, interval1)
} else {
last = now
fn.apply(th, args)
}
}
}
校验车牌
1
2
3
4
5
6
7
8
9
function isCarNum(val) {
var patrn = /^([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1})$/
var patrn2 = /^([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF])|([DF]([A-HJ-NP-Z0-9])[0-9]{4})))$/
if (!patrn.test(val) && !patrn2.test(val)) {
return false
} else {
return true
}
}
校验车架号
1
2
3
4
5
6
7
8
function isVehicle(val) {
var patrn = /^[A-HJ-NP-Za-hj-np-z0-9]+$/
if (!patrn.test(val) || val === '') {
return false
} else {
return true
}
}
检验身份证号码
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
funtion isSfz(idcard) {
var Errors = [1, '身份证号码位数不对', '出生日期错误', '身份证号码错误', '身份证地区非法']
var area = {
11: '北京',
12: '天津',
13: '河北',
14: '山西',
15: '内蒙古',
21: '辽宁',
22: '吉林',
23: '黑龙江',
31: '上海',
32: '江苏',
33: '浙江',
34: '安徽',
35: '福建',
36: '江西',
37: '山东',
41: '河南',
42: '湖北',
43: '湖南',
44: '广东',
45: '广西',
46: '海南',
50: '重庆',
51: '四川',
52: '贵州',
53: '云南',
54: '西藏',
61: '陕西',
62: '甘肃',
63: '青海',
64: '宁夏',
65: 'xinjiang',
71: '台湾',
81: '香港',
82: '澳门',
91: '国外'
}
var Y, JYM
var S, M, ereg, Err
var arr = []
arr = idcard.split('')
if (area[parseInt(idcard.substr(0, 2))] == null) {
Err = Errors[4]
return Err
}
switch (idcard.length) {
case 15:
if ((parseInt(idcard.substr(6, 2)) + 1900) % 4 === 0 || ((parseInt(idcard.substr(6, 2)) + 1900) % 100 === 0 && (parseInt(idcard.substr(6, 2)) + 1900) % 4 === 0)) {
ereg = /^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}$/ // 测试出生日期的合法性
} else {
ereg = /^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}$/ // 测试出生日期的合法性
}
if (ereg.test(idcard)) {
Err = Errors[0]
} else {
Err = Errors[2]
}
return Err
case 18:
if (parseInt(idcard.substr(6, 4)) % 4 === 0 || (parseInt(idcard.substr(6, 4)) % 100 === 0 && parseInt(idcard.substr(6, 4)) % 4 === 0)) {
ereg = /^[1-9][0-9]{5}19[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}[0-9Xx]$/ // 闰年出生日期的合法性正则表达式
} else {
ereg = /^[1-9][0-9]{5}19[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}[0-9Xx]$/ // 平年出生日期的合法性正则表达式
}
if (ereg.test(idcard)) {
S = (parseInt(arr[0]) + parseInt(arr[10])) * 7 + (parseInt(arr[1]) + parseInt(arr[11])) * 9 + (parseInt(arr[2]) + parseInt(arr[12])) * 10 + (parseInt(arr[3]) + parseInt(arr[13])) * 5 + (parseInt(arr[4]) + parseInt(arr[14])) * 8 + (parseInt(arr[5]) + parseInt(arr[15])) * 4 + (parseInt(arr[6]) + parseInt(arr[16])) * 2 + parseInt(arr[7]) * 1 + parseInt(arr[8]) * 6 + parseInt(arr[9]) * 3
Y = S % 11
M = 'F'
JYM = '10X98765432'
M = JYM.substr(Y, 1)
if (M === arr[17]) {
Err = Errors[0]
} else {
Err = Errors[3]
}
} else {
Err = Errors[2]
}
return Err
default:
Err = Errors[1]
return Err
}
}
格式化字符串(去掉空格、回车符)
1
2
3
4
5
6
function iGetInnerText(testStr) {
var resultStr = testStr.replace(/\ +/g, "");
resultStr = testStr.replace(/[ ]/g, "");
resultStr = testStr.replace(/[\r\n]/g, "");
return resultStr;
}
正则表达式获取地址栏参数
1
2
3
function getURLParameter(t){
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [null, ''])[1].replace(/\+/g, '%20')) || null;
}
阅读全文 »