[js] 积累

之前有类似的文章,为了过渡到markdown编辑器,不再往里加了,新起一篇

771172-20170608004009825-109748280.jpg

DOMContentLoaded

The DOMContentLoaded event is fired when the initial HTML document has been completely loaded and parsed,
without waiting for stylesheets, images, and subframes to finish loading.
A very different event load should be used only to detect a fully-loaded page.
It is an incredibly popular mistake to use load where DOMContentLoaded would be much more appropriate, so be cautious.


document.addEventListener("DOMContentLoaded", function(event) {
    console.log("DOM fully loaded and parsed");
});

// this synchronous script is going to delay parsing of the DOM. 
//So the DOMContentLoaded event is going to launch later.
for(var i=0; i<1000000000; i++){} 

数字处理

实现负数变成0的效果

Math.max(0,-3) //0

生成min-max间的随机整数

    function randomInt(min, max) {
        return Math.floor(Math.random() * (max - min + 1) + min);
    }

生成min-max间的随机整数数组

    function randomIntArray(min, max, length) {
        let temp = [];
        for (let i = 0; i < length; ++i) {
            temp.push(Math.floor(Math.random() * (max - min + 1) + min));
        }
        return temp;
    }

求幂,求根

求幂
Math.pow(2,3) //8

求根
Math.pow(8,1/3) //2

字符串处理

  • 快速创建相同字符

new Array(4).join('a') 这里为创建了 aaa

对象处理

  • 获取对象长度
(Object.keys(obj)).length

条件语句

  • 快速判定/执行
    let a =3;
    function howl(){
        console.info('haha')
    }
    console.log(a>2&&3)//3
    console.log(a>4&&5)//false
    console.log(a>2&&'xx')//xx
    console.log(a>4&&'xx')//false
    a>2&&howl()//'haha'
    a>4&&howl()//不运行
  • 多用while代替直接的for循环
    let n=10;
    for(let i=0;i<n;++i){
        console.info(i)
    }

    let i =0;
    while(i <n){
        console.log(i)
        ++i;
    }
  • 合理使用break
let n=10;
for (let i = 0; i < n; i++) {
    console.log(i)
    if(i==3){
        break;
    }
}

for (let i = 0; i < 4; i++) {
    console.log(i)
}

browser

一次click会触发一次mousemove
margin部分是无法触发click的

无阻塞加载JS文件

如果link或者script都是动态生成的话,他们都是异步加载,异步执行, js可能在link之前或者之后执行

var scriptElem = document.createElement("script");
scriptElem.src = "http://anydomain.com/A.js";
document.getElementByTagName("head")[0].appendChild(scriptElem);

var link = document.createElement('link');
link.href = "p-green.css";
link.rel = "stylesheet";
document.head.appendChild(link);

var script = document.createElement('script');
script.src = "p-green.js";
document.head.appendChild(script);

网页渲染过程

  1. 输入网址。
  2. 浏览器查找域名的IP地址。
  3. 浏览器给web服务器发送一个HTTP请求
  4. 网站服务的永久重定向响应
  5. 浏览器跟踪重定向地址 现在,浏览器知道了要访问的正确地址,所以它会发送另一个获取请求。
  6. 服务器“处理”请求,服务器接收到获取请求,然后处理并返回一个响应。
  7. 服务器发回一个HTML响应
  8. 浏览器开始显示HTML
  9. 浏览器发送请求,以获取嵌入在HTML中的对象。在浏览器显示HTML时,它会注意到需要获取其他地址内容的标签。这时,浏览器会发送一个获取请求来重新获得这些文件。这些文件就包括CSS/JS/图片等资源,这些资源的地址都要经历一个和HTML读取类似的过程。所以浏览器会在DNS中查找这些域名,发送请求,重定向等等…

解析html以构建dom树 -> 构建render树 -> 布局render树 -> 绘制render树

  1. 浏览器会将HTML解析成一个DOM树,DOM 树的构建过程是一个深度遍历过程:当前节点的所有子节点都构建好后才会去构建当前节点的下一个兄弟节点。
  2. 将CSS解析成 CSS Rule Tree 。
  3. 根据DOM树和CSSOM来构造 Rendering Tree。注意:Rendering Tree 渲染树并不等同于 DOM 树,因为一些像 Header 或 display:none 的东西就没必要放在渲染树中了。
  4. 有了Render Tree,浏览器已经能知道网页中有哪些节点、各个节点的CSS定义以及他们的从属关系。下一步操作称之为Layout,顾名思义就是计算出每个节点在屏幕中的位置。
  5. 再下一步就是绘制,即遍历render树,并使用UI后端层绘制每个节点。

Reflow 、Repaint

Reflow(回流):浏览器要花时间去渲染,当它发现了某个部分发生了变化影响了布局,那就需要倒回去重新渲染。
Repaint(重绘):如果只是改变了某个元素的背景颜色,文字颜色等,不影响元素周围或内部布局的属性,将只会引起浏览器的repaint,重画某一部分。

Reflow要比Repaint更花费时间,也就更影响性能。所以在写代码的时候,要尽量避免过多Reflow。

reflow的原因:

  • 页面初始化的时候;
  • 操作DOM时;
  • 某些元素的尺寸变了;
  • 如果 CSS 的属性发生变化了。

减少 reflow/repaint

  • 不要一条一条地修改 DOM 的样式。与其这样,还不如预先定义好 css 的 class,然后修改 DOM 的 className。
  • 不要把 DOM 结点的属性值放在一个循环里当成循环里的变量。
  • 为动画的 HTML 元件使用 fixed 或 absolute 的 position,那么修改他们的 CSS 是不会 reflow 的。
  • table 布局可能会因为很小的一个小改动会造成整个 table 的重新布局。

兼容性问题

new Date('2017-1-22') 这种格式的时间处理在ios有问题。
参考这个
解决方案

new Date('2017-1-22'.replace(/-/g, '/'))

为什么undefined == null

underfined值是派生自null值的。

基本数据类型和引用数据类型的区别

  • 基本数据类型因为值的大小固定,所以直接保存在栈内存中。而引用数据类型因为值的大小不固定,所以保存在堆内存中,而堆内存是无法直接进行访问的,进而在栈内存当中又保存了指向堆内存中位置的指针。
  • 复制时,基本数据类型是将原始值的副本赋值给新值,从而两个值之间并不会有任何影响,而引用数据类型则是将栈内存中保存的指向堆内存的指针赋值给新值,从而会互相影响。

JS 中没有按地址(引用)传递,只有按值传递

这里严格的说,在和JAVA类似的语言中,已经没有了指针。在C里面,指针就是一个具有固定长度的类型(在大多数的C编译器里是2个字节),但在JAVA类似的语言里,引用也有自己的属性和方法,只是你不能直接去访问和控制它,所以它从某种意义上也是一种对象,这种机制也很大程度的避免了内存泄露,术语称之为内存结构化访问机制。

判断数据类型

           function isArray(value) {
                return Object.prototype.toString.call(value) == '[object Array]';
            }

            function isFunction(value) {
                return Object.prototype.toString.call(value) == '[object Function]';
            }

            function isRegExp(value) {
                return Object.prototype.toString.call(value) == '[object RegExp]';
            }
            console.log(isRegExp(/abc/));

随机色

    function randomColor() {
        return `#${(~~(Math.random() * (1 << 24))).toString(16)}`
    }


    //从指定颜色中随机选色
    function randomColor(colors = ['red', 'yellow', 'blue']) {
        return colors[Math.floor(Math.random() * colors.length)];
    }

对url里的中文及特殊符号进行处理

encodeURIComponent 、decodeURIComponent

encodeURIComponent('中文啊')//"%E4%B8%AD%E6%96%87%E5%95%8A"
decodeURIComponent('%E4%B8%AD%E6%96%87%E5%95%8A')//中文啊

//为了更严格的遵循 RFC 3986(它保留 !, ', (, ), 和 *),即使这些字符并没有正式划定 URI 的用途,下面这种方式是比较安全的:
function fixedEncodeURIComponent (str) {
  return encodeURIComponent(str).replace(/[!'()]/g, escape).replace(/\*/g, "%2A");
}

有时候会报decoude时URI malformed错误,可能是参数被不同的编码方式进行了encode,比如说后端的方法或者说已经不建议使用的escape方法

document.activeElement

返回当前页面中获得焦点的元素,也就是说,如果此时用户按下了键盘上某个键,会在该元素上触发键盘事件.该属性是只读的.

很多情况下,该属性会返回一个<input>或者<textarea>元素,于此同时,如果用户在文本输入框中选中了一些文本,还可以使用该元素的selectionStart和selectionEnd属性获得准确的选中文本内容.

该属性的值还可能是一个<select>元素(下拉菜单)或者type属性为button,checkbox或radio的<input>元素.

无限轮播的思路

  1. 直接显示隐藏(最简单)
  2. 显示隐藏+动画进出场(实现左右进场)
  3. 头尾多一视口数量(也就是视口展示多少就多多少),到最尾或最前时,显示展示多余的部分,然后直接显示到正常位置(实现无限左右滑动)
  4. 在3的理解基础上,到最前/末尾开始拼接DOM元素,这种方式不推荐

像一般的轮播图插件的实现,都是移动了整个条的方式来移动卡片,但这种情况下,如果又遇到每个卡片有独立的动画(比如说缩放),
那么效果就不会那么理想,这大概也就是那种移动每个卡片的轮播插件写法存在的理由了.

获取伪元素的样式

        let a = document.getElementById('x');
        let b = window.getComputedStyle(a);
        console.log(b.height);
        console.log(b.width);
        let c = window.getComputedStyle(a, ':before');
        let d = c.getPropertyValue('font-size');

target 与 currentTarget 区别

属性/方法类型读/写说明
targetElement只读事件的目标。始终指向事件发生的元素。可以用来实现事件代理。
currentTargetElement只读其事件处理程序当前正在处理事件的那个元素。指向事件所绑定的元素。

Window.getComputedStyle()

let style = window.getComputedStyle(element, [pseudoElt]);

element 用于获取计算样式的Element
pseudoElt 可选 指定一个要匹配的伪元素的字符串。必须对普通元素省略(或null)。

给出应用活动样式表后的元素的所有CSS属性的值,并解析这些值可能包含的任何基本计算。
有点像浏览器的Elements.

数字判断

[]>0 //false
{}>0 // error
undefined>0 //false
null>0 //false
NaN>0 //false
''>0 //false
'str'>0 //false
'0'>0 //false
'-1'>0 //false
'123'>0 //true


[]>-1 //true
{}>-1 // error
undefined>-1 //false
null>-1 //true
NaN>-1 //false
''>-1 //true
'str'>-1 //false
'0'>-1 //true
'-1'>-1 //false
'123'>-1 //true

[]>=0 //true
{}>=0 // error
undefined>=0 //false
null>=0 //true
NaN>=0 //false
''>=0 //true
'str'>=0 //false
'0'>=0 //true
'-1'>=0 //false
'123'>=0 //true

isFinite([]) //true
isFinite({}) // false
isFinite(undefined) //false
isFinite(null) //true
isFinite(NaN) //false
isFinite('')//true
isFinite('str') //false
isFinite('0') //true
isFinite('-1') //true
isFinite('123')//true

[]|0 //0
{}|0 //error
undefined|0 //0
NaN|0 //0
''|0 //0
null|0 //0
'str'|0 //0
'123'|0 //123
'-123'|0 //-123
123|0 //123
-123|0 //-123
12.2|0 //12
12.6|0 //12

/^\d+$/.test([]) //false
/^\d+$/.test({}) // false
/^\d+$/.test(undefined) //false
/^\d+$/.test(null) //false
/^\d+$/.test(NaN) //false
/^\d+$/.test('')//false
/^\d+$/.test('str') //false
/^\d+$/.test(0) //true
/^\d+$/.test(-1) //false
/^\d+$/.test(123)//true

用指数表示大额数字

1e0 === 1;
1e1 === 10;
1e2 === 100;
1e3 === 1000;
1e4 === 10000;
1e5 === 100000;

一些零碎(可能不一定有用)

   function bbbb() {
        console.log(a);// function a
        var a = 'aaa'; //用let 则报错,说明这种写法是有问题的

        function a() {
        }

        console.log(a);// 'aaa'
    }
    bbbb();
    var n = 123;
    n.a = 11;
    console.log(n + n.a);//NaN
    var s = 'string';
    s.str = 'haha';
    console.log(s + s.str);//stringundefined



    function Foo() {
        getName = function () {
            console.log(1);
        };
        return this;
    }
    Foo.getName = function () {
        console.log(2);
    };
    Foo.prototype.getName = function () {
        console.log(3);
    };
    var getName = function () {
        console.log(4);
    };
    function getName() {
        console.log(5);
    }

    Foo.getName();//2
    getName();//4
    Foo().getName();//1
    getName();//1
    new Foo.getName();//2
    new Foo().getName();//3
    new new Foo().getName();//3
    

转载于:https://www.cnblogs.com/qingmingsang/articles/6215797.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值