摘要:可以是数字或者是字符串如果是数字则表示属性名前加上空格符号的数量,如果是字符串,则直接在属性名前加上该字符串。
最后更新于2019年1月13日
前端常用代码片段(一) 点这里
前端常用代码片段(二) 点这里
前端常用代码片段(三) 点这里
前端常用代码片段(四) 点这里
前端常用代码片段(五) 点这里
前端常用代码片段(六) 点这里
function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min + 1) + min) } export function shuffle(arr) { let _arr = arr.slice() for (let i = 0; i < _arr.length; i++) { let j = getRandomInt(0, i) let t = _arr[i] _arr[i] = _arr[j] _arr[j] = t } return _arr }
扩展:
1.取[10,100) 的随机整数方法Math.floor(Math.random()*90+10);2.取[10,100] 的随机整数方法
function randomBy(under, over){ switch(arguments.length){ case 1: return parseInt(Math.random()*under+1); case 2: return parseInt(Math.random()*(over-under+1) + under); default: return 0; } } randomBy(10, 100);
//随机返回一个范围的数字 randomNumber(n1, n2) { //randomNumber(5,10) //返回5-10的随机整数,包括5,10 if (arguments.length === 2) { return Math.round(n1 + Math.random() * (n2 - n1)); } //randomNumber(10) //返回0-10的随机整数,包括0,10 else if (arguments.length === 1) { return Math.round(Math.random() * n1) } //randomNumber() //返回0-255的随机整数,包括0,255 else { return Math.round(Math.random() * 255) } }3.利用sort()
我们先产生个数组
var arr=[]; for(var i=0;i<10;i++){ arr.push(i) } console.log(arr) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
我们以前的正常排序是这样的:
arr.sort(function(a,b){ return b-a });
接下来我们来打乱它:
arr.sort(()=>{ return Math.random() - 0.5 }) // [1, 0, 2, 3, 4, 6, 8, 5, 7, 9]
第二种打乱方法:
arr.sort((a,b)=>{ return a > Math.random()*10; }) // [1, 2, 0, 6, 4, 3, 8, 9, 7, 5]
解析:
先说正常的排序:2.函数节流(throttle)和 函数去抖(debounce)
a,b表示数组中的任意两个元素,若return > 0 ,b前a后;若reutrn < 0 则a前b后;当a=b时,则存在浏览器兼容 ;
a-b输出从小到大排序,b-a输出从大到小排序。
然后再说我们打乱的方法:
创建数组不用说,接下来就是用js的sort方法 来实现,Math.random()实现一个随机0-1之间的小数 然后再减去0.5,这时就会根据return比较后得到的值排序,所以说就会生成不是正常从大到小或者从小到大的排序。
函数节流 和 函数去抖 都是为了项目优化而出现的,官方是没有具体定义的,他们的出现主要是为了解决一些短时间内连续执行的事件带来性能上的不佳和内存的消耗巨大等问题;像这类事件一般像 scroll keyup mousemove resize等等,短时间内不断的触发,在性能上消耗是非常大的,尤其是一些改变DOM结构的操作;
节流[throttle]与防抖[debounce]非常相似,都是让上述这类事件里定义的代码 从不断的执行 更改成为 规定的时间内执行多少次;
函数节流(throttle) 应用场景函数节流(throttle),例如实现一个拖拽功能,需要一路监听 mousemove 事件,在回调中获取元素当前位置,然后重置 dom 的位置(样式改变)。如果我们不加以控制,每移动一定像素而触发的回调数量是会非常惊人的,回调中又伴随着 DOM 操作,继而引发浏览器的重排与重绘,性能差的浏览器可能就会直接假死,这样的用户体验是非常糟糕的。我们需要做的是降低触发回调的频率,比如让它 500ms 触发一次,或者 1000ms,这个阈值不能太大,太大了拖拽就会失真,也不能太小,太小了低版本浏览器可能就会假死,这样的解决方案就是函数节流。函数节流的核心是,让一个函数不要执行得太频繁,减少一些过快的调用来节流。
函数节流有哪些应用场景?哪些时候我们需要间隔一定时间触发回调来控制函数调用频率?
DOM 元素的拖拽功能实现(mousemove)
射击游戏的 mousedown/keydown 事件(单位时间只能发射一颗子弹)
计算鼠标移动的距离(mousemove)
Canvas 模拟画板功能(mousemove)
搜索联想(keyup)
监听滚动事件判断是否到页面底部自动加载更多:给 scroll 加了 debounce 后,只有用户停止滚动后,才会判断是否到了页面底部;如果是 throttle 的话,只要页面滚动就会间隔一段时间判断一次
节流通俗来解释就比如我们水龙头放水,阀门一打开,水哗哗的往下流,这个秉着勤俭节约的优良传统美德,我们要把水龙头关小点,最好是如我们心意按照一定规律在某个时间间隔内一滴一滴的往下滴,这,,,好吧这就是我们节流的概念;换成函数来说,使用setTimeout方法,给定两个时间,后面的时间减去前面的时间,到达我们给定的时间就去触发一次这个事件,这么说太笼统的,我们看下面的函数,这里我们以【scroll】为例;
/** 样式我就顺便写了 **/ ------------------------ /** 先给定DOM结构;**/------------------------ /**主要看js,为了简单我用JQ去写了**/
或
export function throttle(delay, action){ let last = return function(){ let curr = +new Date() if (curr - last > delay){ action.apply(this, arguments) last = curr } } }函数去抖(debounce) 应用场景
写代码之前,我们先清楚一下防抖的概念,不知道大家有没有做过电脑端两边悬浮广告窗口的这么一个东西,当我们拖动滚动条的时候,两边的广告窗口会因为滚动条的拖动,而不断的尝试着去居于中间,然后你就会看到这两个窗口,不停的抖啊抖;
一般这种就叫抖动了,我们要做的就是防止这种抖动,称为防抖[debounce ];
那这里防抖思想就是当我们拖动完成之后,两边的窗口位置再重新去计算,这样,就会显得很平滑,看着很舒服了,最主要的操作DOM结构的次数就大大减少了;
优化了页面性能,降低了内存消耗,不然你像IE这种比较老点版本的浏览器,说不定就直接给你蹦了
用书面一点的说法就是,在某个事件没有结束之前,函数不会执行,当结束之后,我们给定延时时间,然他在给定的延时时间之后再去执行这个函数,这就是防抖函数;
来看代码:
//将上面案例的throttle函数替换为debounce函数; function debounce(method,time){ var timer = null ; return function(){ var context = this; //在函数执行的时候先清除timer定时器; clearTimeout(timer); timer = setTimeout(function(){ method.call(context); },time); } }
思路就是在函数执行之前,我们先清除定时器,如果函数一直执行,就会不断的去清除定时器中的方法,知道我们操作结束之后,函数才会执行;
或
export function debounce(func, delay) { let timer return function(...args) { if (timer) { clearTimeout(timer) } timer = setTimeout(() => { func.apply(this, args) }, delay) } }
用途
当我们做keyup像后台请求检验的时候,可以使用防抖函数,不然我们每按一次键盘就请求一次,请求太频繁,这样当我们结束按键盘的时候再去请求,请求少很多了,性能自然不用说;
resize 窗口大小调整的时候,我们可以采用防抖技术也可以使用节流;
mousemove 鼠标移动事件我们既可以采用防抖也可以使用节流;
scroll 滚动条触发的事件,当然既可以采用防抖也可以采用节流;
连续高频发的事件都可以采用这两种方式去解决,优化页面性能;
具体的采用哪一种更较为合适,主要还是看你的业务需求
区分
节流说白了就是每ms执行一次函数,防抖就是 最后一次触发后ms后执行一次回调函数。
节流就是拧紧水龙头,让水滴一滴一滴流,而去抖则是按压一个弹簧,不松手则弹簧不会触发函数节流和去抖都是限制基于DOM事件执行的javascript数量的方法,都是为了提高JS性能,但是两者是有区别的。
推荐阅读
函数节流和去抖之间的区别
本小节引用
avaScript 函数节流...
JavaScript 高级系列...
这个是网上一个网友提的问题,自己未曾遇到也为实验,先保存在这
源代码:
原因:
图片的比例不是1:1(图片纵横比不为1)
解决方法:(待验证)
或
border-radius:100%4.如何优雅的实现金钱格式化:1234567890 --> 1,234,567,890
用正则魔法实现:
var test1 = "1234567890" var format = test1.replace(/B(?=(d{3})+(?!d))/g, ",") console.log(format) // 1,234,567,890
非正则的优雅实现:
function formatCash(str) { return str.split("").reverse().reduce((prev, next, index) => { return ((index % 3) ? next : (next + ",")) + prev }) } console.log(formatCash("1234567890")) // 1,234,567,8905.如何最佳的让两个整数交换数值
常规办法:
var a=1,b=2; a += b; b = a - b; a -= b;
缺点也很明显,整型数据溢出,对于32位字符最大表示数字是2147483647,如果是2147483645和2147483646交换就失败了。
黑科技办法:
a ^= b; b ^= a; a ^= b;
es6:
[b,a] = [a,b]6.实现标准JSON的深拷贝
var a = { a: 1, b: { c: 1, d: 2 } } var b=JSON.parse(JSON.stringify(a))
不考虑IE的情况下,标准JSON格式的对象蛮实用,不过对于undefined和function的会忽略掉。
7.在str前添加一个➕号,+str会强制转Number不用Number、parseInt和parseFloat和方法把"88"字符串转换成数字
var str="88"; console.log(+str) // 88 //或者 console.log(str - 0) // 88 //但是如果是混合类型的字符串,则会转为NaN var b="1606e"; console.log(+b) // NaN8.数组去重
方法1:最短的代码实现es6
[...new Set([1, "1", 2, 1, 1, 3])]
function uniqueArray(arr){ return Array.from(new Set(arr)); }
方法2:使用filter + indexOf
如下代码所示:
removeRepeatArray(arr) { return arr.filter(function (item, index, self) { return self.indexOf(item) === index; }); }
方法3:使用splice
如下代码所示:
function uniqueArray(arr){ for(var i = 0; i < arr.length - 1; i++){ for(var j = i + 1; j < arr.length; j++){ if(arr[j] === arr[i]){ arr.splice(j--, 1); } } } return arr; }
方法4:只用Array
如下代码所示:
function uniqueArray(arr){ var retArray = []; for(var i = 0; i < arr.length; i++){ if(retArray.indexOf(arr[i]) < 0){ retArray.push(arr[i]); } } return retArray; }
方法5:Object.keys(对象)
let a = ["1", "2", "3", 1,NaN,NaN,undefined,undefined,null,null, "a", "b", "b"]; const unique = arr => { var obj = {} arr.forEach(value => { obj[value] = 0;//这步新添加一个属性,并赋值,如果不赋值的话,属性会添加不上去 }) return Object.keys(obj);//`Object.keys(对象)`返回这个对象可枚举属性组成的数组,这个数组就是去重后的数组 } console.log(unique(a));//["1", "2", "3", "NaN", "undefined", "null", "a", "b"]
注意:
这个方法会将 number,NaN,undefined,null,变为字符串形式,因为对象的属性名就是一个字符串
Array(6).fill(8)10.取出一个数组中的最大值和最小值
var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411]; var maxInNumbers = Math.max.apply(Math, numbers); // 或 Math.max(...arr) var minInNumbers = Math.min.apply(Math, numbers); // 或 Math.min(...arr)11.将argruments对象转换成数组
var argArray = Array.prototype.slice.call(arguments);
或者ES6:
var argArray = Array.from(arguments)12.短路表达式
条件判断
var a = b && 1 // 相当于 if (b) { a = 1 } else { a = b }
var a = b || 1 // 相当于 if (b) { a = b } else { a = 1 }13.RGB to Hex
function toHEX(rgb){ return ((1<<24) + (rgb.r<<16) + (rgb.g<<8) + rgb.b).toString(16).substr(1); }14.JSON.stringify()妙用
1 语法
JSON.stringify(value[, replacer[, space]])
一般用法:
var user = {name: "andy", isDead: false, age: 11, addr: "shanghai"}; JSON.stringify(user); "{"name":"andy","isDead":false,"age":11,"addr":"shanghai"}"
2 扩展用法
2.1 replacer
replacer可以是函数或者是数组。
功能1: 改变属性值
将isDead属性的值翻译成0或1,0对应false,1对应true
var user = {name: "andy", isDead: false, age: 11, addr: "shanghai"}; JSON.stringify(user, function(key, value){ if(key === "isDead"){ return value === true ? 1 : 0; } return value; }); //"{"name":"andy","isDead":0,"age":11,"addr":"shanghai"}"
功能2:删除某个属性
将isDead属性删除,如果replacer的返回值是undefined,那么该属性会被删除。
var user = {name: "andy", isDead: false, age: 11, addr: "shanghai"}; JSON.stringify(user, function(key, value){ if(key === "isDead"){ return undefined; } return value; }); //"{"name":"andy","age":11,"addr":"shanghai"}"
功能3: 通过数组过滤某些属性
只需要name属性和addr属性,其他不要。
var user = {name: "andy", isDead: false, age: 11, addr: "shanghai"}; JSON.stringify(user, ["name", "addr"]); //"{"name":"andy","addr":"shanghai"}"
2.2 space
space可以是数字或者是字符串, 如果是数字则表示属性名前加上空格符号的数量,如果是字符串,则直接在属性名前加上该字符串。
功能1: 给输出属性前加上n个空格
var user = {name: "andy", isDead: false, age: 11, addr: "shanghai"}; JSON.stringify(user, null, 4);
"{ "name": "andy", "isDead": false, "age": 11, "addr": "shanghai" }"
功能2: tab格式化输出
var user = {name: "andy", isDead: false, age: 11, addr: "shanghai"}; JSON.stringify(user, null, " ");
"{ "name": "andy", "isDead": false, "age": 11, "addr": "shanghai" }"
功能3: 搞笑
JSON.stringify(user, null, "good");
"{ good"name": "andy", good"isDead": false, good"age": 11, good"addr": "shanghai" }"
2.3 深拷贝
var user = {name: "andy", isDead: false, age: 11, addr: "shanghai"}; var temp = JSON.stringify(user); var user2 = JSON.parse(temp);
3 其他
JSON.parse() 其实也是支持第二个参数的。功能类似于JSON.stringify的第二个参数的功能。
console.log("$",$.fn.jquery) //$ 3.2.116.img异步加载图片
在开发中,我们经常有异步加载图片的请求,然后在图片加载成功后做一些操作,一般我们通过onload方法来实现.网上有两种写法,大家可以先看一下(注:logo.jpg是张本地图片):
例子1:
var img = new Image(); img.src = "logo.jpg"; img.onload = function () { alert("image is loaded"); }; document.body.appendChild(img);
例子2:
var img = new Image(); img.onload = function () { alert("image is loaded"); }; img.src = "logo.jpg"; document.body.appendChild(img);
发现什么了没有?上面两个例子最大的差别就在于onload和src赋值的先后顺序.那么onload和src赋值的先后顺序会在实际中产生什么差别呢?
产生这个问题的原因很简单,就是因为logo.jpg是本地图片,导致浏览器加载起来非常快,几乎在给img赋值src的时候,图片就已经加载完成,同时触发了onload事件,代码中为onload赋值的语句就相当于在onload事件发生后,这时候已经晚了.
将src写到了onload的前面,会导致onload来不及赋值就被执行了,所以正确的写法应该是第2个例子.既在给图片分配地址前,先绑定好它的onload事件,这样就不用担心错过时机的问题了.
正确的例子:
var img = new Image(); // 如果文档装入完成后加载用window load //window.addEventListener("load" , function(){ // document.body.appendChild(img); //} , false); // 如果图片加载完毕用 img load img.addEventListener("load", function(){ document.body.appendChild(img); } , false); img.src = "test.png";17.几个常用的console用法
1.console.log(): 进行标准输出流的输出(stdout)
console.group("mounted 挂载结束状态===============》"); console.log("%c%s", "color:green","data : " + this.$data)
2.console.error(): 进行标准错误流的输出用法与console.log()一样.
3.console.dir(): 查看一个对象的内容,并把对象信息输出到控制台.
// a.js var person = { age: 38, name: "kobe", job: function(){ return "player" } }; console.log(person); // node a.js { age: 38, name: "kobe", job: [Function: job] }
4.console.time()与console.timeEnd() : 可以用来统计一段代码的执行时间
// a.js console.time("loop"); for(var i =0;i < 10000;i++){ ; } console.timeEnd("loop"); // node a.js loop: 0.283ms
好玩的console.log()
console.log("%c3"," text-shadow: 0 1px 0 #ccc,0 2px 0 #c9c9c9,0 3px 0 #bbb,0 4px 0 #b9b9b9,0 5px 0 #aaa,0 6px 1px rgba(0,0,0,.1),0 0 5px rgba(0,0,0,.1),0 1px 3px rgba(0,0,0,.3),0 3px 5px rgba(0,0,0,.2),0 5px 10px rgba(0,0,0,.25),0 10px 10px rgba(0,0,0,.2),0 20px 20px rgba(0,0,0,.15);font-size:6em;line-height:60px;") console.log("%c2"," text-shadow: 0 1px 0 #ccc,0 2px 0 #c9c9c9,0 3px 0 #bbb,0 4px 0 #b9b9b9,0 5px 0 #aaa,0 6px 1px rgba(0,0,0,.1),0 0 5px rgba(0,0,0,.1),0 1px 3px rgba(0,0,0,.3),0 3px 5px rgba(0,0,0,.2),0 5px 10px rgba(0,0,0,.25),0 10px 10px rgba(0,0,0,.2),0 20px 20px rgba(0,0,0,.15);font-size:4em;line-height:60px;") console.log("%c1"," text-shadow: 0 1px 0 #ccc,0 2px 0 #c9c9c9,0 3px 0 #bbb,0 4px 0 #b9b9b9,0 5px 0 #aaa,0 6px 1px rgba(0,0,0,.1),0 0 5px rgba(0,0,0,.1),0 1px 3px rgba(0,0,0,.3),0 3px 5px rgba(0,0,0,.2),0 5px 10px rgba(0,0,0,.25),0 10px 10px rgba(0,0,0,.2),0 20px 20px rgba(0,0,0,.15);font-size:2em;line-height:60px;") console.log("%c南京热还是东京热.", "color: #fff; background: #f40; font-size: 24px;border-radius:0 15px 15px 0;padding:10px;"); console.log("%c ","background-image:-webkit-gradient( linear, left top, right top, color-stop(0, #f22), color-stop(0.15, #f2f), color-stop(0.3, #22f), color-stop(0.45, #2ff), color-stop(0.6, #2f2),color-stop(0.75, #2f2), color-stop(0.9, #ff2), color-stop(1, #f22) );color:transparent;-webkit-background-clip: text;font-size:5em;width:1px;height:40px;padding:2px;") console.log("%c 热 热 热", "color:red;font-size:30px;font-weight:bolder;padding:50px 420px;line-height:10px;background:url("http://img.zcool.cn/community/0127c0577e00620000012e7e12da0e.gif") repeat-x;background-size:contain;");18. !!强制转布尔值boolean
根据当前需要判断的值是真值还是假值来判断,真值返回true,假肢返回false,那么这样的话,除了假值,剩下的也都是真值了。
假值有:0 、 “” 、 null 、 undefined 、 false 、NaN
除了这 6 个外,其它均为“真” ,包括对象、数组、正则、函数等。
注意: "0"、"null"、"false"、{}、[]也都是真值 。
那么下面我们来看看!!是如何转布尔值的。
例如:
首先我们声明3个变量,x为null,y为空字符串,str为字符串,下面看看他们添加了"!!"后会有什么结果。
var x=null; var y=""; var str="abcd"; console.log(!!x) // false; console.log(!!y) // false; console.log(!!str) // true; 如上所说,假值返回false,真值返回true。19. 不可靠的undefined 可靠的void 0
在JavaScript中,假设我们想判断一个是否是 undefined,那么我们通常会这样写:
if(a === undefined){ dosomething..... }
因为在javascript中,undefined是不可靠的
例如:
当undefined被放在在function函数内,我们把它当成一个局部变量,它是可以赋上值的,下面我们来试试。
function foo2(){ var undefined=1; console.log(undefined) } foo2(); // 1;
但是当在函数内定义一个全局变量,并不能给赋上值
var undefined; function foo2(){ undefined=1; console.log(undefined) } foo2() // undefined
那么我们试试用void 0或者 void (0)来代替:
先声明一个变量a,赋值为undefined,接下来我们用void 0来判断一下。
var a=undefined; //用void 0来判断一下 if(a===void 0){ console.log("true") } // true //再用void (0)来判断一下 if(a===void (0)){ console.log("true") } // true //最后我们打印一下这两个的返回值 console.log(void 0,void (0)) // undefined undefined
我们现在可以通过void 0 运算来获得 undefined;那在以后需要判断值为undefined的时候,可以直接用void 0或者void (0),而且这两个值的直接返回值就是undefined,所以说非常可靠哦!
20.用typeof来判断对象的潜在陷阱问:使用 typeof bar === "object" 来确定 bar 是否是对象的潜在陷阱是什么?如何避免这个陷阱?
尽管 typeof bar === "object" 是检查 bar 是否对象的可靠方法,令人惊讶的是在JavaScript中 null 也被认为是对象!
因此,令大多数开发人员惊讶的是,下面的代码将输出 true 控制台:
var bar = null; console.log(typeof bar === "object"); // logs true!
只要清楚这一点,同时检查 bar 是否为 null,就可以很容易地避免问题:
console.log( (bar !== null) && (typeof bar === "object") ); // logs false
要答全问题,还有其他两件事情值得注意:
首先,上述解决方案将返回 false,当 bar 是一个函数的时候。在大多数情况下,这是期望行为,但当你也想对函数返回 true 的话,你可以修改上面的解决方案为:
console.log( (bar !== null) && ((typeof bar === "object") || (typeof bar === "function")) );
第二,上述解决方案将返回 true,当 bar 是一个数组(例如,当 var bar = [];)的时候。
在大多数情况下,这是期望行为,因为数组是真正的对象,但当你也想对数组返回 false 时,你可以修改上面的解决方案为:
console.log( (bar !== null)&& (typeof bar === "object") && (toString.call(bar) !== "[object Array]") );
或者,如果你使用jQuery的话:
console.log( (bar !== null)&& (typeof bar === "object") && (! $.isArray(bar)) );
或者 数组和函数返回false,但对于对象则为true:
console.log((bar !== null) && (bar.constructor === Object));
参考:
1.这些JavaScript编程黑科技...
2.图片的异步加载与onload函数
3.原生js的常用方法整理
4.ec-do-2.0.0.js
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/88518.html
摘要:本文总结的代码片段六持续更新前端常用代码片段一点这里前端常用代码片段二点这里前端常用代码片段三点这里前端常用代码片段四点这里前端常用代码片段五点这里前端常用代码片段六点这里多彩的传入和变量本节参考文章多彩的版本号比较和和本节参考文章 本文总结的代码片段(六)--持续更新 前端常用代码片段(一) 点这里前端常用代码片段(二) 点这里前端常用代码片段(三) 点这里前端常用代码片段(四) 点...
摘要:两个数组内的元素相加第二种考虑兼容一个数组插入到另一个数组通过方法将一个数组插入到另外一个数组数字排序的函数在默认情况下使用字母数字字符串码点排序。它们具有不同的引用,无法用相比较。 最后更新于2019年1月13日 前端常用代码片段(一) 点这里前端常用代码片段(二) 点这里前端常用代码片段(三) 点这里前端常用代码片段(四) 点这里前端常用代码片段(五) 点这里前端常用代码片段(六)...
摘要:尽量避免使用表达式又称动态属性。使用计算数组中的重复项如果你想计算数组中的每个值有多少重复值,也可以快速帮到你。 前端常用代码片段(一) 点这里前端常用代码片段(二) 点这里前端常用代码片段(三) 点这里前端常用代码片段(四) 点这里前端常用代码片段(五) 点这里前端常用代码片段(六) 点这里 1.简述一下你对HTML语义化的理解?并写出一段语义化的HTML? 语义化是指根据内容的结...
最后更新于2019年1月13日 前端常用代码片段(一) 点这里前端常用代码片段(二) 点这里前端常用代码片段(三) 点这里前端常用代码片段(四) 点这里前端常用代码片段(五) 点这里前端常用代码片段(六) 点这里 大部分需要引入 jquery-1.9.1.min.js(兼容ie8) 1.回车触发事件的代码 $(function(){ $(#username).focus(...
摘要:当运行时,如果不为,则将超时函数推送到事件队列,并且函数退出,从而使调用堆栈清零。因此,该方法从头到尾不经过直接递归调用即可处理,因此调用堆栈保持清晰,无论迭代次数如何。 前端常用代码片段(一) 点这里前端常用代码片段(二) 点这里前端常用代码片段(三) 点这里前端常用代码片段(四) 点这里 1.tap事件点透问题? 问题点击穿透问题:点击蒙层(mask)上的关闭按钮,蒙层消失后发现触...
阅读 3315·2021-11-12 10:36
阅读 2467·2021-11-02 14:43
阅读 2146·2019-08-30 14:23
阅读 3462·2019-08-30 13:08
阅读 919·2019-08-28 18:09
阅读 3128·2019-08-26 12:22
阅读 3140·2019-08-23 18:24
阅读 2016·2019-08-23 18:17