正则小进阶

分组,断言详解
对于有正则基础的同学,
配合上面的参考文献,
()分组配合\数字的引用 (?=n)、(?!n)这种前向断言 (?<=n)、(?<!n)这种后向断言。嗯,正则基本够用了。ps:js里没有后向断言!!!s里没有后向断言!!!s里没有后向断言!!!气的昏古七
完。(额,好像断言的名字跟参考文献里作者提的不同,算了 我就喜欢这么叫它,只是为了好记哈哈)

js的面向对象编程

这里只贴出参考文献,按顺序看就好。
so easy!
详解JS类概念的实现
然后看看阮一峰老人家的三篇系列:
Javascript 面向对象编程(一):封装
最后看着玩的一篇,如果前面的理解过了,那么你可以发现这篇一些问题。(看不出问题去看评论= =):
Javascript定义类(class)的三种方法

我总结下,关于继承在JS实现的技术上只有两点要提:
1.为了继承父级私有属性,apply很重要。
2.为了不让父级的私有属性污染子集的原型,new构造函数很重要。
最后提醒,constructor记得指回正确的构造函数。

如果你还是真的真的真的不能理解为什么要这样做?
那就试着理解下这句话

“子类继承父类后:
一,子类的私有属性要继承父类的私有属性。私有的意思就是自己身上的,不用在原型链里找的
二,而父类的公共属性就通过原型链给子类用就好。”

完。

同源策略及规避方法

实现要贴的是来自大神阮一峰的参考文献:浏览器同源政策及其规避方法
然后是window.name的作用示例: window.name 跨域实现原理及实例
HTML5安全:CORS(跨域资源共享)简介。。。ie67不要想了。。。
看完以上文章觉得真是精彩,但有些知识点个人认为值得注意注意。
1. window.name容量为2mb,出现的目的是起初是为了解决cookie小的问题(80kb)
2. window.name在通讯前还是需要跳转到同源名下的网址,但window.name中的信息不变,进而实现通讯(结合上面第二个参考文献看,会发现和不能跨越的ajax配合,爽歪歪!!!)
3. ajax不能跨域?用cors可以,而且ie8支持(对于现在来说我认为一般ie8支持就算可以随便用了!),值得注意的是服务器需要设置Access-Control-Allow-Origin,如果是别人家的服务器。。。那么你就想想别的路子吧。(cors使用请参考开头提供的第三个文献)
4. 更方便简洁的方法是postMessage,h5的api,兼容性就呵呵啦。要注意的是该api的语法:
otherWindow.postMessage(message,targetOrigin, [transfer]);
其中特别特别特别注意otherWindow

MDN原文解释:otherWindow:其他窗口的一个引用,比如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames。MDN原文解释:otherWindow:其他窗口的一个引用,比如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames。

这里第一次见到会有点措手不及,比如我给你个东西,主语应该是‘我’,这里是‘你’的感觉。。。

完。

我保证,超级超级简单的弄明白this指向

首先盗张图,来源:图解javascript this指向什么?

完。
好吧,其实我想介绍的是setTimeout和this之间的故事,也可以加深this的理解:)

obj={
    a:1,
    fn:function(){console.log(this.a)}//执行obj.fn()时打印1,此时this为obj。
}

obj={
    a:1,
    fn:function(){setTimeout(console.log(this.a),1000)}//执行obj.fn()时还是打印1,此时this为obj。
}
obj={
    a:1,
    fn:function(){setTimeout(function(){console.log(this.a)},1000)}//执行obj.fn()时还是打印undefined,此时this为window。
}

END

js滚动事件和兼容

都说IE8是做兼容的分水岭,没想FF也有与别人不一样的时候,给FF,IE两位小祖宗递茶。

判断IE678的小技巧

!-[1,] 如果返回true就是IE678。因为IE678会认为[1,][1,undefined],其他浏览器会所谓是[1]。so接下来你懂的。

事件绑定

addEventListener,传三个参数,第一个为事件名称(不带‘on’),第二个为事件函数,第三个为是否捕获,默认false。不兼容IE678,所以要用attachEvent,传两个参数,第一个事件名称(带“on”!),第二个事件函数(注意于前面相比没有第三个参数哦)。相对应的事件解绑removerEventListenerdetachEvent

禁止冒泡

e.cancelBubble = true查了一波资料,发现这本来是IE专属的功能,但其他浏览器也实现了,但不是标准,未来可以除掉???所以用stopPropagation()方法这个标准的来代替吧。

阻止默认事件

e.preventDefault(),不兼容IE678,IE678要用e.returnValue = false

鼠标滚动事件

在这个事件兼容中我看到了FF的任性。。。mousewheel事件在非FF中有用,FF要用DOMMouseScroll代替。而且,与之相对应的判断鼠标滚轮滚上还是滚下的属性也不同。mousewheel的是e.wheelDelta,向下滚为-120的倍数,向上120的倍数。DOMMouseScrolle.detail,向下滚为3,向上为-3。

好了,根据上面这些知识来封装个函数兼容IE678和FF,代码?自己搞!

完。

DOM

回顾下昨天自己的收获,蛮杂的,但细细回想,起DOM这个标题无可厚非。

JS三大组成部分是什么?

DOM、BOM、ECMA。

对于兼容性问题,都说IE8是个分水岭,下文有点点提到。

DOM中值得注意的是,

静态方法(所谓静态就是如果代码执行后如果有新节点添加进来,这静态方法是不知道的):

querySelector、querySelectAll、getElementById,

前两者IE7及以下不能用

(后者可以用ID名直接代替,这个用法最初是 IE 里面的,后来 firefox chrome 好像也支持了。不建议使用,这个不是标准里面的,将来不一定支持。而且ID变量名也可以轻易被改变)

接下来说动态方法

getElementsByClassNamegetElementsByTagNamegetElementsByName,值得注意的是第一个方法在IE8及以下不兼容

有个兼容方法,这里我就推荐篇别人写的给大家 http://blog.csdn.net/u014753892/article/details/52776973

这里啰嗦几句,也算是对推荐文章里的代码精华做个回顾。居然有的浏览器没有getElementsByClassName,那就来个大家都有的className嘛,哦好回顾完了。

因为js没学好,学牢固,就去看了《锋利的jQuery》,现在好多方法混乱了T T。所以给自己复习下DOM的增删查改。

children推荐使用)、childNodes(常与nodeType,nodeValue、nodeName配合使用,兼容性问题:IE8之辈)、firstChild(firstElementChild)、last。。。除了第一个,其他通通为了兼容就不要随便用!

appendChild、insertBefore(传参两个,一个都不能省!)、createElement、removeChild(只是从页面中删除,想添加回来也是分分钟的事)、parentNode(可用offsetParent取得老一辈,记得加定位)、cloneNode(参数为true时克隆完整节点,但对于js里绑定的事件函数克隆不过来,想解决此问题只能把函数写到节点属性里,如onclick=“xx”)、replaceChild(添新,删老)。

嗯,这么多方法,以后学jQuery要边学边回忆原生js怎么写的,这样jQuery熟不熟无所谓,js确很熟了很好啊哈哈。

再说点昨天的收获,群里有人在问如何写个代码让新浪自动取消关注,一想有意思,我那段没上微博的时间好像也被自动关注了很多营销号。所以动动手,嗯,还是有收获了。一开始浏览器里打入$符号,咦,有用!牛逼了,还以为是内嵌jQuery,后来就悲剧了,提示没这方法那方法的,查了一下,原来这货不是jQuery。收获一:浏览器里的$相当于querySelector,而$$相当于querySelectAll。收获二:把js当jq用,我真是傻,傻傻的在click括号里写回调函数,半天没反应。后来灵机一动,自己写个回调,参数就是函数就好了哈哈,然后一顿模拟用户操作,搞定,按一下取消一个。(每次成功后浏览器会清除掉我自定义的回调,毕竟页面刷新了应该。)附上代码:

$$(".opt .layer_menu_list li a")[2].go=function(fn){if(!($$(".btn_34px")[1])){this.click()};fn()};$$(".opt .layer_menu_list li a")[2].go(function(){$$(".btn_34px")[0].click()})

另外一个小知识点,setTimeout返回一个number。

最近在看iscroll,看完看看vue吧= =招聘老说要,本来还想捣鼓下小程序的,这下好了,贪多嚼不烂。

完。

杂谈transform3D,鼠标拖动,手机端拖动

今天又复习了一下css3的transform3D部分,说个印象深的就是rotateX正值是从右往左看的顺时针方向,rotateY正值时是从下往上看时的顺时针方向。虽然注意这个好像没啥意思,有人会觉得测试一下就知。我也觉得,但刻意留意下,会提高点点效率,积少成多,熟能生巧嘛。然后看了小龙老师的3D盒子源码。然后自己也模仿了个。附上网址(审查可以看源码,都写在网页里了):http://www.huangjunyong,club

有趣的地方在于鼠标能拖动来转换视角。用坐标对应旋转角度,利用3对变量(X,Y),第一对存着角度状态(坐标),第二对存着鼠标点击时的坐标,第三对存着鼠标移动时产生的坐标,进而做出鼠标拖动旋转的效果。因为源码移动端没效果,移动端没有onmousedown这些方法,所以我加了ontouchstart等来替换(百度的,学习了!),要注意的是,要取得X坐标,如onmousedown的话有

document.onmousedown=function(e){

var e = e || event;//event在IE下就有,而在FF事件执行时才有产生

var x = e.pageX;

}

如果是ontouchstart的话,有

 

document.ontouchstart=function(e){

e=e||event;
var touch = e.touches[0];
var x = touch.pageX;

}

大家可以发现除了方法对应着换了外,还有个e.touches[0]的东西。touches对象嘛,想一下为什么鼠标没有呢?因为鼠标只有一个嘛,你只有一根手指?

源码中值得注意的还有元素节点中有个ondragstart='return false'

ondragstart在IE9以后才支持,不加的话图片会被拖到新窗口,别的元素要可以拖动的话得加draggable="true"

完。

从懒加载到回流

突然有个疑问,懒加载?比如作用于图片,就是监听滚动事件,当滚动条拉下到一定距离图片才加载出来,可以为用户省流量,减少服务器压力(此处可能说错。)

而问题来了,图片怎么感觉是网页一开始加载就随着加载的呢,那怎么叫他停?想到这我看了篇关于浏览器渲染原理的文章,翻译写的非常好!可以先看看再回来(最下面)。

这里提到了reflow,应该就是我们所说的回流了。回流会加大浏览器的负担,在上面那篇文章里有所提到,解决办法就是1、尽量把元素放在内存处理;2、用类名操作(一次性操作多个嘛,按我的理解,毕竟reflow一般会异步执行或者累积执行);3、对绝对定位的元素来进行操作;4、尽量操作低层次的节点(下是低);

说完回流,说说懒加载。懒加载图片先用个统一的普通图片代替,真正的图片用比如data-src=“xxx.jpg”写在img标签里,等滚到图片附近时再把真正的引用替换给src。这里我想到原生js单是要得到浏览器可视窗口大小,为了兼容就有3个api要写!天哪,写完发现jQuery真亲切,帮你封装好了(window.innerHeight || document.documentElement.ClientHeight || document.body.ClientHeight,而jq就一个$(window).height())。

滚动监听需要注意性能优化,这里来个节流函数,话不多说,抄了端代码过来:

// 简单的节流函数
//fun 要执行的函数
//delay 延迟
//time  在time时间内必须执行一次
function throttle(fun, delay, time) {
    var timeout,
        startTime = new Date();
    return function() {
        var context = this,
            args = arguments,
            curTime = new Date();
        clearTimeout(timeout);
        // 如果达到了规定的触发时间间隔,触发 handler
        if (curTime - startTime >= time) {
            fun.apply(context, args);
            startTime = curTime;
            // 没达到触发间隔,重新设定定时器
        } else {
            timeout = setTimeout(fun, delay);
        }
    };
};
// 实际想绑定在 scroll 事件上的 handler
function lazyload(event) {}
// 采用了节流函数
window.addEventListener('scroll',throttle(lazyload,500,1000));

这throttle函数有个值得说下的地方,就是为什么要返回一个函数呢?想弄明白你就要知道如果不这样做,直接把函数里的变量写到throttle会怎样?本来不想告诉你们,自己去试一试的。算了,我这人忍不住要说,嗯。。。算了,说一半吧,在于arguments的不同。当然,还有一个作用...不然每次滚动startTime都刷新还玩个X。补充一句window.addEventListener('scroll',throttle(lazyload,500,1000));throttle(lazyload,500,1000)已经变成他返回的函数啦。。。

完。

参考:

http://coolshell.cn/articles/9666.html 《浏览器的渲染原理简介》

http://www.cnblogs.com/flyromance/p/5042187.html《滚动加载图片(懒加载)实现原理》

https://zhuanlan.zhihu.com/p/24057749 《前端如何实现图片懒加载(lazyload) 提高用户体验》