frontend notes 06/12/2020
最近更新于:

JavaScript 速记

日常记录一些 js/css 相对实用的小笔记,本笔记保持长期更新,如有错误或更好的方案留言反馈

使用 toString() 取随机字符串(toString 最大值为 32)

    var rs=(num)=>{let rs=Math.random().toString(num);return rs.substring(2,rs.length)}
rs(2);  //1011111100100110111101101110010000011101101001100001
rs(16);  //40a52a10becc

使用 link() 创建指定参数链接

    "example string".link("http://www.w3school.com.cn");  //<a href="http://www.w3school.com.cn">example string</a>"

使用 !+"v1" 判断 IE8 以下的浏览器

    !+"\v1";  //true(IE8及以下)
!+"\v1";  //false(谷歌浏览器和IE9及以上)

使用原生js选择 不包含特定 class 的元素(How to Select Element That Does Not have Specific Class)

    <ul id="tasks">
  <li class="completed selected">One Task</li>
  <li>Two Task</li>
</ul>
// select li which doesn't have a 'class' attribute...
console.log(document.querySelector("li:not([class])"))

// select li which doesn't have a '.completed' and a '.selected' class...
console.log(document.querySelector("li:not(.completed):not(.selected)"))

通过创建 input 并使用 document.execCommand("copy") 复制文本框内容(注意这里不能隐藏文本框否则获取不到值)

    var text="some sample text",  //文本内容
    copyIpt=document.createElement("input");  //创建文本框
//copyIpt.style.display="none";copyIpt.type="hidden";
document.body.appendChild(copyIpt);  //添加文本框
copyIpt.value=text;  //复制到文本框
copyIpt.select();  //选中所有文本
document.execCommand("copy")  //复制所选内容

js内容选中即复制

    document.onclick = function() {
    if (window.getSelection) {
        text = window.getSelection();
    } else if (document.selection) {
        text = document.selection.createRange();
    }
    // 放到粘贴板里,操作浏览器自身的API
    // console.log(text.toString());
    document.execCommand('Copy'); // 执行浏览器的复制命令
}

(更新精准/模糊匹配)js 正则匹配指定开头结尾内字符串(这里匹配 img 标签)

    var str = "img: <img src='#' />",
    filter = str.match(/\<img.*?\>/g);  //<img src='#' />
    var str = "img: <img src='#' />",
    inclouds = str.match(/\<([\s\S]*?)\>/)[0],  //<img src='#' />
    notincloud = str.match(/\<([\s\S]*?)\>/)[1];  //img src='#' /

js 删除符合指定条件的数组对象中的某个对象

    var arr = [{name:"a",age:1},{name:"b",age:2},{name:"c",age:3}];
console.log(arr)  //a:1 b:2 c:3
for(let i=0;i<arr.length;i++){
    arr[i].name=="b" ? arr.splice(i,1) : false;
}
console.log(arr)  //a:1 c:3

js 函数参数执行 js 方法

    var arr = ["a","b","c"],
    forArr = forFunc=(arr,exe)=>{
        if(arr!=null && arr!=undefined)
        for(let i=0;i<arr.length;i++){
            exe!=undefined ? exe(i) : false;
        }
    };
forFunc(arr,function(i){
    console.log(arr[i])  //a,b,c
})

js 批量定义变量

    var arr = ["a","b","c"],
for (let i=0; i<arr.length;i++) {
    eval('var' +arr[i]+ '= document.getElementById("' +arr[i]+ '");');
}
console.log(a);  //确保 id 为 a 的元素不等于 null 或 undefined 

js Object.keys 用法举例

    var arr = ["a","b","c"],
    obj = {"a":"aaa","b":"bbb","c":"ccc"},
    str = "String";
Object.keys(arr);  //["0","1","2"]
Object.keys(obj);  //["a","b","c"]
Object.keys(str);  //["0","1","2","3","4","5"]

JavaScript 异步方案 async/await

    const f = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(123);
    }, 2000);
  });
};

const testAsync = async () => {
  const t = await f();
  console.log(t);
};

testAsync();
//首先定义了一个函数 f,这个函数返回一个 Promise,并且会延时 2 秒,resolve 并且传入值 123。
//testAsync 函数在定义时使用了关键字 async,然后函数体中配合使用了 await,最后执行 testAsync。
//整个程序会在 2 秒后输出 123,也就是说 testAsync 中常量 t 取得了 f 中 resolve 的值,并且通过 await 阻塞了后面代码的执行,直到 f 这个异步函数执行完。

js 移除 string 中的空格

    var str = "s triing",
    str = str.replace(/\s+/g,"");  //去除所有空格
    去除两头空格:   
    str = str.replace(/^\s+|\s+$/g,"");  //去除左空格
    str = str.replace( /^\s*/, '');  //去除右空格
    

js 移除指定数组中的某一项

    var arr = ["a","b","c"];
    let index = arr.indexOf("b");
    arr.splice(index,1);
    console.log(arr)  //["a","c"]

js 防抖(连续点击)

    function debounce(fn, wait) {    
    var timeout = null;    
    return function() {
        if(timeout !== null)   clearTimeout(timeout);        
        timeout = setTimeout(fn, wait);    
    }
}
// 处理函数
function handle() {
    console.log("handled 1000ms")
}
// 执行事件
window.addEventListener('click', debounce(handle, 1000));
    var check;
window.onclick=()=>{
    check ? clearTimeout(check) : check;
    check = setTimeout(function(){
        console.log('checked');
    }, 1000);
}

js 自执行函数

    (function a(){
    console.log('auto_run_fn')  //auto_run_fn(无需调用直接执行)
})()

js 自执行函数 this 指向

    (function(){
    console.log(this);  //this 指向 window
    var that = this;  //that 指向 window
    return (function(){
        return this
    })()
})();

JavaScript 闭包计数器

    function closure(){
        var counter = 0;
        plus = function(){
            counter++
        };
        subs = function(){
            counter--
        };
        //闭包函数
        return function(){
            console.log(counter)
        }
    };
var res = closure(),  //调用闭包函数
    counter_plus = function(){
        plus();
        res()
    },
    counter_subs = function(){
        subs();
        res()
    };
counter_plus();  //counter = 1
counter_subs();  //counter = 0

JavaScript 防抖(闭包)

    function debounce(delay){
        var timer = null;
        return function(){
            timer ? clearTimeout(timer) : timer;
            timer = setTimeout(function(){
                console.log("连续点击时,仅执行一次(最后一次)点击事件")
            },delay)
        }
    };
var res = debounce(1000);
window.addEventListener('click',res)  //连续点击时,仅执行一次(最后一次)点击事件

JavaScript 节流(闭包)

    function throttle(delay){
        var timer = null,
            handle = function(){
                console.log("连续点击时,每隔 1000ms 执行一次 handle()");
            };
        return function(){
            if(timer==null){  //!timer
                timer = setTimeout(function(){
                    //handle.apply(this,null);  //apply 传递 argument 上下文 this 环境
                    handle();
                    timer = null  //消除定时器表示激活
                },delay)
            }
        }
    };
var res = throttle(1000);
window.onclick=function(){
    res()  //连续点击时,每隔 1000ms 执行一次 handle()
}

JavaScript call() apply()

    console.log(this);  //window
//call()、apply()、bind() 都是用来重定义 this 这个对象的!
var name="name",
    age=0;
var obj={
        name: "NAME",
        objAge: this.age,
        fn: function(arg){
            console.log(this);
            console.log("arg: "+arg);
        }
    },
    newObj={
        name: "Named",
        age: 1
    };
obj.fn();  //{NAME,0}
obj.fn.call(newObj,'string');  //{Named,1},"string"
obj.fn.apply(newObj,['array']);  //{Named,1},[array]
obj.fn.bind(newObj,'string')();  //{Named,1},"string"
obj.fn.bind(newObj,['array'])();  //{Named,1},[array]

JS正则限制只能输入数字、或带小数点的数字,并且小数后面限制多少位

    const length = 2
    const reg = new RegExp(`^\\d+(\\.\\d{1,${length}})?$`)

JS 利用 offsetParent 判断元素是否可见

    var p = document.querySelectorAll("p");
    p.offsetParent!=null ? console.log("可见") : console.log("不可见");

JS 利用 split() join() 实现 replaceAll() 的两种方式

    var str = "[dog]man[cat]",
    replace = ["[","]"],
    all = ["【","】"],
    obj = {
        "[":"【",
        "]":"】"
    },
    replaceAll = function(str,replace,all){
        for(let i=0;i<replace.length;i++){
            str = str.split(replace[i]).join(all[i])
        };
        return str
    },
    replaceObj = function(str,obj){
        for(key in obj){
            str = str.split(key).join(obj[key])
        };
        return str
    };
    replaceAll(str,replace,all);  //"【dog】man【cat】"
    replaceObj(str,obj);  //"【dog】man【cat】"

Js 过滤字符串数字和非数字

    var str="a1b2c3";
console.log(str.replace(/[0-9]/ig,""));  //abc
console.log(str.replace(/[^0-9]/ig,""));  //123

Js 获取指定父元素

function eachParent(curPar,tarPar){
    while(curPar.TagName.toLowerCase()!=tarPar){
        curPar = curPar.parentNode
    };
    return curPar
}

Js 在 head 执行时当所有 dom 加载完成后再执行

var headfn = function(){
    console.log("hellow world")
},
isloaded = function(){
    window.addEventListener("DOMContentLoaded", headfn, false);
}

Js 滚动到当前滚动条底部

var focusScroll = function(focusarea){
    focusarea.focus();
    focusarea.scrollTop = focusarea.scrollHeight
};
focusScroll(textarea)  //textarea 聚焦元素

Js textarea/input 值操作

var textarea = documen.getElementById("textarea")
    selection = window.getSelection ? window.getSelection() : document.selection.createRange().text,
    indexOfSelectBefore = textarea.selectionStart,
    indexOfSelectAfter = textarea.selectionEnd;
    textarea.setSelectionRange(0, 0);  //定位光标到指定位置(不选中)
    console.log(selection.toString());  //当前已选中文本
    console.log(indexOfSelectBefore);  //当前已选中文本前索引
    console.log(indexOfSelectAfter);  //当前已选中文本后索引

Js 使用 dispatchEvent 触发自定义事件

var event = new Event('click');
window.addEventListener('click',function(e){
    console.log(1)
});
window.dispatchEvent(event)  //log 1 without click the window

Js 获取最近一个月(上个月的今天至今为止)的 leancloud 标准日期格式

console.log(new Date());  //Tue Apr 27 2021 11:05:51 GMT+0800 (中国标准时间)
dateFormat = function(d){
    const addZero = (n,m) => {
              return n<m ? '0'+n : n;
          },
          year = d.getFullYear(),
          month = p ? addZero(d.getMonth()+1,10) : addZero(d.getMonth(),10),
          day = addZero(d.getDate(),10),
          hour = d.getHours(),
          minute = addZero(d.getMinutes(),10);
    return year+ '-' +month+ '-' +day+' '+hour+':'+minute+':'+second;
};
dateFormat(new Date(),true);  //2021-04-27 11:05:51
dateFormat(new Date(),false);  //2021-03-27 11:05:51

Js 获取当前元素到窗口顶部/侧面距离

var el = document.getElementById("el");
console.log(el.getBoundingClientRect().top)  //distance between el and window-top

获取 JS 数组中的相同元素的名称和数量

var ary =["anime","comic","game","movie","tv","anime"];  
var res = [];  
ary.sort();  
for(var i = 0;i<ary.length;){ 
    var count = 0;
    for(var j=i;j<ary.length;j++){  
        if(ary[i] == ary[j]){  
            count++;
        }
    };
    res.push([ary[i],count]);  
    i+=count;  
}  
//res 二维数维中保存了 值和值的重复数
for(var  i = 0 ;i<res.length;i++){  
    console.log("值:"+res[i][0]+" 重复次数:"+res[i][1]+");  
}

// 不用reduce时: 
    var arr = ["apple","orange","apple","orange","pear","orange"]; 
    function getWordCnt(){ 
      var obj = {}; 
      for(var i= 0, l = arr.length; i<l; i++){ 
        var item = arr[i]; 
        obj[item] = (obj[item] +1 ) || 1; 
      } 
      return obj; 
    }
    console.log(getWordCnt());//{apple: 2, orange: 3, pear: 1}
// 用reduce时: 
    var arr = ["apple","orange","apple","orange","pear","orange"]; 
    function getWordCnt(){ 
      return arr.reduce(function(prev,next){ 
        prev[next] = (prev[next] + 1) || 1; 
        return prev; 
      },{}); 
    } 
    console.log(getWordCnt());//{apple: 2, orange: 3, pear: 1}

Js 简单委托事件

<div id="atag">
    <a>111</a>
    <a>222</a>
</div>
const atag = document.querySelector("#atag");
atag.onclick=(e)=>{
    var e = e || window.event,
        t = e.target || e.srcElement,
        p = "a";  //事件标签
    // 创建 while 循环,直到 t=p,否则循环向上遍历 t 的 parentNode 是否为 p
    while(t!=atag){
        if(t.nodeName.toLowerCase()==p){
            console.log("delegated a tag");
            break;  //跳出循环
        }else{
            t = t.parentNode;
        }
    }
}

Js 在 iframe 中查找父页面变量或函数

var variable = "parentvar";
<iframe>
    console.log(parent.variable)  //parentvar
</iframe>

Js 利用访问 iframe 父页面变量

var parVar = "this var from parent";  //注意!不能使用 const 否则 iframe 不可读父页面变量
//iframe 页面内调用
console.log(parent.parVar)  //"this var from parent"

Js 利用 postMessage 方法在 iframe 中与父页面跨域通信

<iframe id="postMessage"></iframe>
//子页面传数据至父页面同理
const person = {
          name: "name",
          age: 1
      };
window.onload = function(){
    document.getElementById("postMessage").contentWindow.postMessage(JSON.stringify(person),"/")  //postMessage 第二参数可限制访问来源
};
//iframe 页面内调用
window.addEventListener("message",function(e){
    let res = JSON.parse(e.data);  //return parsed JSON Object
    alert(`getMessage ${res} from ${e.origin}`);  //getMessage [Object Object] from /
    console.log(res)  //{name: "name",age: 1}
});

正则匹配指定标签内所有内容

<tag>[\w\W]*?</tag>

短路运算符 && || (除了NaN、null、""、undefined、0、function这几个为false外,其他皆为true)

false ? false : true
console.log(false&&true)  //false (find true one by one)
console.log(false||true)  //true (find true between both)

JS 鼠标拖拽时被中断

event.preventDefault()  //阻止默认事件 
element.setCapture()  //捕获事件
element.releaseCapture()  //释放事件 

js 时间戳转为日期格式

function getLocalTime(nS) {     
    return new Date(parseInt(nS) * 1000).toLocaleString().replace(/:\d{1,2}$/,' ');     
}     
console.log(getLocalTime(1293072805));  //2010/12/23 上午10:53 

JS阻止事件冒泡

e=e || window.event,
//阻止事件冒泡
//不仅仅要stopPropagation,还要preventDefault
pauseEvent = function(e){
    if(e.stopPropagation) e.stopPropagation();
    if(e.preventDefault) e.preventDefault();
    e.cancelBubble=true;
    e.returnValue=false;
    return false;
}

js 获取指定 css 值(transform),不指定即返回所有匹配值

_getComputedStyle = function(element,property,which) {
    const st = window.getComputedStyle(element, null),
          tr = st.getPropertyValue('-webkit-'+property) ||
               st.getPropertyValue('-moz-'+property) ||
               st.getPropertyValue('-ms-'+property) ||
               st.getPropertyValue('-o-'+property) ||
               st.getPropertyValue(property) || 'FAIL';
    if (tr === 'FAIL') {
        return '';
    };
    if(which){
        let target = tr.split(",")[which];
        if(target){
            return Number(target)
        }else{
            return 0
        }
    }else{
        return tr
    }
}

safari 父元素 overflow 子元素 transform 导致父元素 border-radius 失效

.father{
    border-radius: 10px;
    overflow: hidden;
    transform: rotate(0deg);  //仅需在设置 border-radius 的元素上添加 rotate(0deg) 即可修复
}
.child{
    transform: translate(10px,10px)
}

CSS 速记

使用 prefers-color-scheme 进行浏览器亮/暗色默认行为切换

    @media (prefers-color-scheme: light) {
    body{
        color:white;
        background:black;
    }
}
@media (prefers-color-scheme: dark) {
    body{
        color:blank;
        background:white;
    }
}

笔记参考链接: HOE:JavaScript 之神妙之处