chaims / study

to do study
0 stars 0 forks source link

JS常用总结 #28

Open chaims opened 7 years ago

chaims commented 7 years ago

目录

  1. 常用优化技巧
  2. 浏览器全屏
  3. 键盘事件
  4. 函数防抖动和函数节流
chaims commented 7 years ago

操作优化

  1. 三元操作符

    const answer = x > 10 ? 'is greater' : 'is lesser';

  2. 短路求值简写方式

    想确定null,undefined或空值时,使用短路求值方法 const variable2 = variable1 || 'new';

  3. 循环简写方法

    for (let i = 0; i < allImgs.length; i++) for (let index in allImgs) [2, 5, 9].forEach(logArrayElements);

  4. 对象属性简写

    const obj = { x:x, y:y }; 简写为 const obj = { x,y }

  5. 箭头函数

    function sayHello(name) { console.log('Hello', name); } setTimeout(function() { console.log('Loaded') }, 2000); list.forEach(function(item) { console.log(item); });

    转换为:

    sayHello = name => console.log('Hello', name);

    setTimeout(() => console.log('Loaded'), 2000);

    list.forEach(item => console.log(item));

  6. 隐式返回值 经常使用return语句来返回函数最终结果,一个单独语句的箭头函数能隐式返回其值(函数必须省略{}为了省略return关键字

    function calcCircumference(diameter) { return Math.PI * diameter } var func = function func() { return { foo: 1 }; };

    简写:

    calcCircumference = diameter => (Math.PI * diameter;) var func = () => ({ foo: 1 });

  7. 默认参数值

    function volume(l, w, h) {
         if (w === undefined)w = 3;
         if (h === undefined)h = 4;
         return l * w * h;
    }
    
    简写:
    
    volume = (l, w = 3, h = 4 ) => (l * w * h);
    volume(2) //output: 24
  8. 解构赋值简写方法

    const observable = require('mobx/observable');
    const action = require('mobx/action');
    const runInAction = require('mobx/runInAction');
    简写为:
    import { observable, action, runInAction } from 'mobx';
    
    const store = this.props.store;
    const form = this.props.form;
    const loading = this.props.loading;
    const errors = this.props.errors;
    const entity = this.props.contact;
    简写为:
    const { store, form, loading, errors, entity:contact } = this.props;
  9. 扩展运算符简写

    const odd = [1, 3, 5]; const nums = [2 ,4 , 6].concat(odd); 简写为: const nums = [2 ,4 , 6, ...odd]; const nums = [2 ,4 , ...odd,6,];

    const arr = [1, 2, 3, 4]; const arr2 = arr.slice() 简写为: const arr2 = [...arr];

    const { a, b, ...z } = { a: 1, b: 2, c: 3, d: 4 }; console.log(a) // 1 console.log(b) // 2 console.log(z) // { c: 3, d: 4 }

  10. 强制参数简写

    function foo(bar) {
         if(bar === undefined) {
            throw new Error('Missing parameter!');
         }
         return bar;
    }
    简写:
    mandatory = () => {
         throw new Error('Missing parameter!');
    }
    foo = (bar = mandatory()) => {
         return bar;
    }
  11. 双重非位运算代替Math.floor

    Math.floor(4.9) === 4
    ~~4.9 === 4
  12. Array 查询 find()

    const pets = [
        { type: 'Dog', name: 'Max'},
        { type: 'Cat', name: 'Karl'},
        { type: 'Dog', name: 'Tommy'}
    ]
    pet = pets.find( pet => pet.type === 'Dog' && pet.name === 'Karl' )
  13. 简单copy&&深度copy 用slice 或 contcat方法实现数组的简单复制

    注意:有对象和函数或者数组的数组,简单值不一起改变,但是引用类型则原来对象和复制对象一起改变

    JSON.parse(JSON.stringify(arr1))
    $.extend(true,target,obj)
    var deepCopy = function(o) {
    if (o instanceof Array) {
        var n = [];
        for (var i = 0; i < o.length; ++i) {
            n[i] = deepCopy(o[i]);
        }
        return n;
    
    } else if (o instanceof Object) {
        var n = {}
        for (var i in o) {
            n[i] = deepCopy(o[i]);
        }
        return n;
    } else {
        return o;
    }
    }
  14. Function构造函数 Function构造函数接受的参数中,第一个是要传入的参数名,第二个是函数内的代码(用字符串来表示)。

    var f = new Function('a', 'alert(a)');
    f('jawil'); 
  15. 正则表达式 (转金钱)

    var test1 = '1234567890'
    var format = test1.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
    console.log(format) // 1,234,567,890
  16. [].forEach.call($$("*"),function(a){
    a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)
    })

    17.组件

    "★★★★★☆☆☆☆☆".slice(5 - rate, 10 - rate);
chaims commented 7 years ago

浏览器全屏

var doc = document.documentElement;
if (docElm.requestFullscreen) {  
    docElm.requestFullscreen();  
}
else if (docElm.mozRequestFullScreen) {  
    docElm.mozRequestFullScreen();  
}
else if (docElm.webkitRequestFullScreen) {  
    docElm.webkitRequestFullScreen();  
}
else if (elem.msRequestFullscreen) {
  elem.msRequestFullscreen();
}

退出全屏

if (document.exitFullscreen) {  
    document.exitFullscreen();  
}  
else if (document.mozCancelFullScreen) {  
    document.mozCancelFullScreen();  
}  
else if (document.webkitCancelFullScreen) {  
    document.webkitCancelFullScreen();  
}
else if (document.m**itFullscreen) {
      document.m**itFullscreen();
}

事件监听

document.addEventListener("fullscreenchange", function () {  
    fullscreenState.innerHTML = (document.fullscreen)? "" : "not ";
  }, false);  
document.addEventListener("mozfullscreenchange", function () {  
    fullscreenState.innerHTML = (document.mozFullScreen)? "" : "not ";
  }, false);  
document.addEventListener("webkitfullscreenchange", function () {  
    fullscreenState.innerHTML = (document.webkitIsFullScreen)? "" : "not ";
  }, false);
document.addEventListener("msfullscreenchange", function () {
    fullscreenState.innerHTML = (document.msFullscreenElement)? "" : "not ";
  }, false);

全屏样式设置在浏览器全屏的使用我们还可以进行样式设置

html:-moz-full-screen {  
    background: red;  
}  
html:-webkit-full-screen {  
    background: red;  
}  
html:fullscreen {  
    background: red;  
}
chaims commented 6 years ago

键盘事件

英文输入法:事件触发顺序:keydown - > keypress - > keyup 中文输入法:

firfox:输入触发keydown,回车确认输入触发keyup
chrome:输入触发keydown、keyup,回车确认输入只触发keydown
IE/Safari/opera:输入触发keydown、keyup,回车确认输入触发keydown,keyup

keypress事件不能对系统功能键(例如:后退、删除等,其中对中文输入法不能有效响应)进行正常的响应, keydown和keyup均可以对系统功能键进行有效的拦截,但事件截获的位置不同。

键盘中的键分为字符(可打印)键和功能键(不可打印),系统功能键包括如下: Esc、Tab、Caps Lock、Shift、Ctrl、Alt、Enter、Backspace、Print Screen、Scroll Lock、Pause Break、Insert、Delete、Home、End、Page Up、Page Down, F1 through F12,Num Lock、The Arrow Keys。

keypress响应系统功能键总结: Firefox:支持 Esc、Enter、Backspace、Pause Break、Insert、Delete、Home、End、Page Up、Page Down、F1 through F12、The Arrow Keys Chrome:支持Enter Oprea:支持Enter Safari:支持Enter IE:支持Esc、Enter

firefox:上下左右键会触发kepress. chrome/IE/safari/oprea:上下左右键不会触发kepress.

keyCode(键码), which, charCode(字符编码)

keydown: 获得keyCode, charCode=0
keypress: 字符(英文区分大小写+数字  / * , .  ...等非功能键),keyCode=0 ,获取charCode值, 反之获取keyCode, charCode=0
keyup: 获得keyCode, charCode=0

jquery 中 event.which = original.charCode != null ? original.charCode : original.keyCode; 总结:回车、上下左右、等功能键keydown、keypress、keyup都获取keyCode,并且值相等。

开启大写情况,keydown、keypress(字母,主键盘数字、回车)、keyup,which值相等,小写kepress获取的which不同于keypress、keyup。

keypress事件的keyCode对字母的大小写敏感,而keydown、keyup事件不敏感 keypress事件的which值无法区分主键盘上的数字键和附键盘数字键的,而keydown、keyup的which值对主附键盘的数字键敏感。 【 IE(ie9以下)只有一个属性KeyCode属性,当为keydown和keyup 事件是,keycode属性表示你具体按下的键(也称为virtual keycode),当捕捉的是keypress事件时keyCode属性指的是你键入的字符(character code)

标准浏览器中情况有些不同,event对象包含一个keyCode属性和一个charCode属性,keydown和keyup事件的时候,keyCode表示的就是你具体按的键,charCode为0;当捕捉的是keypress事件时,keyCode为0,charCode指的是你按下的字符,鉴于IE和FF中的区别,如果你比较懒的话,建议只使用keydow和keyup事件 】

chaims commented 6 years ago

节流和防抖动

场景

频繁执行的事件,如:

只需要在特定的时候去执行绑定了这些事件的函数

函数防抖动(debounce)

当我们调用一个动作的时候,会设置在n毫秒后才执行,而在这n毫秒内,如果这个动作再次被调用的话则将重新再计算n毫秒,采取执行。

function debounce(func, wait){
  var timeID = null;
  return function(){
    clearTimeout(timeID);
    timeID = setTimeOut(func, wait);
  }
}
function hanlder(){
  console.log('Hanlde the scroll event.');
}
window.addEventListener('scroll', debounce(hanlder, 400));

防抖技术即是可以把多个顺序地调用合并成一次,也就是在一定时间内,规定事件被触发的次数。

函数的节流(Throttle)

只允许一个函数在 X 毫秒内执行一次

var throttle = function(delay, action){ 
    var last = 0; 
    return function () { 
        var curr = +new Date();
        if (curr - last > delay) { 
            action.apply(this, arguments);
            last = curr; 
        }
    } 
}

只允许一个函数在 X 毫秒内执行一次,只有当上一次函数执行后过了你规定的时间间隔,才能进行下一次该函数的调用。

rAF(requestAnimationFrame)

在页面重绘之前,通知浏览器调用一个指定的函数,这个方法接受一个函数为参,该函数会在重绘前调用。实现以 16.7ms (1000/60) 的频率来触发,代表它的可调节性十分差。

var ticking = false; // rAF 触发锁
function onScroll(){
  if(!ticking) {
    requestAnimationFrame(realFunc);
    ticking = true;
  }
}

function realFunc(){
    // do something...
    console.log("Success");
    ticking = false;
}
// 滚动事件监听
window.addEventListener('scroll', onScroll, false);

16.7ms 触发一次 handler,降低了可控性,但是提升了性能和精确度。