JS 原生对象与数组拷贝

浅拷贝单层对象

1
2
let obj = { id: 1, title: "1" }
let copyOfObj = Object.assign({}, obj)

深拷贝多层对象

1
2
3
4
5
6
7
let obj = {
id: 1,
title: "1",
tag: ['js', 'javascript'],
category: { id: 1001, title: 'frontend' }
}
let copyOfObj = JSON.parse(JSON.stringify(obj))

浅拷贝简单类型数组

1
2
let arr = [1, 2, 3]
let copyOfArr = [...arr]

深拷贝单层对象组成的数组

1
2
3
4
5
6
7
let arr = [
{ id: 1, title: "1" },
{ id: 2, title: "2" },
{ id: 3, title: "3" }
]
let copyOfArr1 = arr.map((item) => Object.assign({}, item))
let copyOfArr2 = JSON.parse(JSON.stringify(arr))

深拷贝多层对象组成的数组

1
2
3
4
5
6
7
let arr = [
{ id: 1, title: "1", subObj: { name: 'subObj1' } },
{ id: 2, title: "2", subObj: { name: 'subObj2' } },
{ id: 3, title: "3", subObj: { name: 'subObj3' } }
]
let copyOfArr1 = arr.map((item) => JSON.parse(JSON.stringify(item)))
let copyOfArr2 = JSON.parse(JSON.stringify(arr))

总结

不考虑性能的情况下,JSON.parse(JSON.stringify(value))是最简最万能的拷贝。

直接操作 Vue data 中不存在的属性导致的 v-model 绑定异常问题

直接操作 Vue data 中不存在的属性导致的 v-model 绑定异常问题

初学Vue遇到的问题,尝试了几个小时才搞明白,大佬应该一眼就能看出什么问题吧……

需要注意,不要直接在JS中操作一个Vue data对象中不存在的属性,如果同时有通过v-model绑定到该对象的不存在的属性时,会出现诡异的行为表现,console中不会报出任何 warnerror

需求是,实现三个复选框,第一个复选框初始为选中状态,一开始写出来是这样的——

HTML
1
2
3
4
5
<div id="app" style="margin: 10px;">
<van-checkbox v-for="box in checkboxes" :key="box.id" v-model="box.selected">
复选框 {{ box.title }}
</van-checkbox>
</div>
JS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
new Vue({
el: '#app',
data () {
return {
checkboxes: [
{ id: 1, title: 'a' },
{ id: 2, title: 'b' },
{ id: 3, title: 'c' }
]
}
},
created () {
this.checkboxes[0].selected = true
}
})

试下效果:

See the Pen vue-v-model-not-work by iMaeGoo (@iMaeGoo) on CodePen.

复选框a的表现显然是异常的,点击不能成功地切换选中状态,而在点击之后再点击其他复选框,才会“有延迟地”切换状态。

阅读更多
CSS 类似 iOS 的毛玻璃动态模糊效果

CSS 类似 iOS 的毛玻璃动态模糊效果

提到网页毛玻璃效果,总结下来有以下2种:

  1. 模糊元素本身
  2. 模糊元素后面的内容

早在之前,1就已经可以通过 CSS3 filter 属性实现,而2一直没有一个好的解决方案。对1的运用,也可以达到2的效果,通过模糊图片的一部分,就可以实现类似 bilibili 导航栏的模糊背景效果 ↓

这样实现的前提是,我们的背景是一个静态的,单一的图片,那么如果我们需要模糊的背景比较复杂呢?仔细观察QQ右栏的标题栏,和下方的应用 Dock,都是 iOS 常见的毛玻璃叠加层效果 ↓

显然模糊元素本身并不能解决所有场景的问题。

阅读更多
XSS, CSRF, CRLF, SQL注入学习笔记

XSS, CSRF, CRLF, SQL注入学习笔记

XSS, CSRF, CRLF, SQL注入都是历史悠久的四种攻击方式,因为参数化查询已经成了普遍用法,我们已经离SQL注入很远了,但是,XSS,CSRF,CRLF却没有远离我们。

本文以初学者角度探讨四种Web攻击以及预防方式,是个人基于对多种Web漏洞的学习总结,不承诺内容规范。

阅读更多

AngularJS 给 directive scope 绑定的 function 传参

如果我们想要给directive的scope中绑定的方法传递参数,需要传递对象,而不是直接传值。

举个栗子,这里的clickOutside是从用的地方传入的一个方法,debug时我们会发现绑进来的clickOutside并不是我们传的clickOutSideAction

1
2
3
4
5
6
7
8
9
10
11
12
13
app.directive('clickOutSide', ['$document', function($document) {
return {
restrict: 'A',
scope: {
clickOutside: '&'
},
link: function (scope, el) {
$document.on('click', function (e) {
scope.clickOutside();
});
}
}
}]);
1
<div data-click-out-side click-Outside="$ctrl.clickOutSideAction()"></div>

如果需要在这里给clickOutSideAction传参数,应该这样改:

1
2
3
4
5
6
7
8
9
10
app.directive('clickOutSide', ['$document', function($document) {
return {
...
link: function (scope, el) {
...
scope.clickOutside({event: e});
...
}
}
}]);
1
<div data-click-out-side click-Outside="$ctrl.clickOutSideAction(event)"></div>

好处是在实际使用directive的地方,不需要考虑参数列表顺序,只需要保证参数名称正确。

AngularJS input 输入框自适应内容宽度

在Gist上找到的一个directive,用来让input输入框的宽度自适应内容宽度。
https://gist.github.com/mbenford/8016984

原理是生成一个相同样式的,隐藏的span,通过span的宽度动态改变input的宽度。
同时兼顾了input有placeholder的情况。

如果是在比较大的系统中,可以用throttle节流阀包装一下resize方法,避免性能问题。

如果是textarea,对应的directive在这里:
https://github.com/monospaced/angular-elastic

阅读更多

CSS鼠标悬浮改变相邻元素样式

效果:

Hover me! X

源码:

1
2
3
4
<div class="chip">
<span class="name">Hover me!</span>
<span class="close-bth">X</span>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.chip {
display: flex;
width: fit-content;
font-size: 20px;
text-align: center;
background-color: #ccc;
}

.chip .name { width: 120px; }
.chip .close-bth { width: 30px; }

.chip .name:hover,
.chip .name:hover + .close-bth,
.chip .close-bth:hover {
color: white;
background-color: #888;
}

CodePen link:
https://codepen.io/iMaeGoo/pen/jRqYRJ

hmmmm…这种实现也没什么难的,其实是想试试在博文中插入HTML啦。

AngularJS Material制作气泡弹出效果
编写Chrome插件将googleapis替换为国内可访问的CDN

编写Chrome插件将googleapis替换为国内可访问的CDN

由于公司不能安装梯子,所以不能访问谷歌商店,平时频繁地要访问国外的AngularJS网站,比如AgGrid,AngularJS Material,AngularJS官网等,很多用了Google的CDN源,页面就无法正常加载。

一开始的思路是改host文件,但是我们没有Google CDN的证书,会造成证书错误。

参考并优化了:https://github.com/justjavac/ReplaceGoogleCDN ,动手写了一个Chrome插件,对所有特定请求重定向,解决痛点!

阅读更多
Make simple <md-chip> work without <md-chips> in AngularJS Material?

Make simple <md-chip> work without <md-chips> in AngularJS Material?

I’m using AngularJS Material v1.1.1.
I’m finding a way to use simple <md-chip> without <md-chips>.

Here is an easy way in Vue Material: https://codesandbox.io/s/lyoqv4l0z?module=App.vue

1
<md-chip class="md-primary" md-deletable>Deletable</md-chip>

But I can not find the similiar way in AngularJS Material document.
https://material.angularjs.org/latest/api/directive/mdChip

阅读更多

ChartJS鼠标移到图例上显示手形

在Chart options中添加:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 给图例加手势
legend: {
onHover: function(e) {
e.target.style.cursor = 'pointer';
}
},

// 给图加手势
hover: {
onHover: function(e) {
var point = this.getElementAtEvent(e);
if (point.length) {
e.target.style.cursor = 'pointer';
} else {
e.target.style.cursor = 'default';
}
}
}
微信二维码