你们知道弄了一整天才把博客重新弄好是什么心情吗。。 给笔记本换了固态硬盘格了C盘D盘什么软件都要重装。 折腾了好久才知道原来HEXO升级为3.0了。 之前2.7用的好好的现在弄了好久真的是心好累啊心好累啊。 不过算是弄好了,自己把public文件夹手动deploy【再见】。 好了记一下主页里用到的JS吧。 最终页面:益米,让校园生活轻松自在
JS-base 不知道为什么我自己就是不喜欢用jQuery。就是喜欢自己写长长的JS代码。所以把自己之前写过的函数都收集起来真的是太有必要了:
判断是否在数组内 1
2
3
4
5
6
7
8
function is_inArray (array,target ) {
for (var i = 0 ; i < array.length; i++) {
if (array[i] == target) {
return i;
}
}
return -1 ;
}
其实我觉得写得还好。。不过来看看zepto.js的:1
2
3
$.inArray = function (elem, array, i ) {
return emptyArray.indexOf.call(array, elem, i)
}
先来了解这个call()
函数: 这是每个函数非继承而来的方法,还有一个是apply()
。这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。apple()
接受两个参数:一个是在其中运行函数的作用域,另一个是参数数组。call()
方法和apply()
方法的区别在于接受参数的方式不同,第一个参数是this值,变化的是其余参数都直接传递给函数。具体参考《JavaScript高级程序设计》P117。这里写个例子:1
2
3
4
5
6
7
8
9
10
11
window .color = "red" ;
var o = {color: "blue" };
function sayColor ( ) {
alert(this .color);
}
sayColor();
sayColor.call(this );
sayColor.call(window );
sayColor.call(o);
使用call()来扩充作用域的最大好处,就是对象不需要与方法有任何耦合关系。
1
2
3
4
5
6
7
8
9
10
window .color = "red" ;
var o = {color: "blue" };
function sayColor ( ) {
alert(this .color);
}
sayColor();
o.sayColor = sayColor;
o.sayColor();
对比这两种写法,发现前面那种好很多了。 然后是数组的index()
方法: 接受两个参数:要查找的项和(可选的)表示查找起点位置的索引。 我之前一直以为这个方法只是在字符串里面使用。。用在查找类名。。 擦原来系统已经提供了这个方法我还在自己写。 对了,回到我写的那个方法。for (var i = 0; i < array.length; i++)
最好不要这么写,因为如果数组是DOM节点的集合,每次都需要获取一遍长度,比较消耗资源,所以改写成:for(var i = 0,var max = array.length; i < max; i++)
移除元素的某个类 先不要脸的放上自己写的:1
2
3
4
5
6
function removeClassName (target,clsName ) {
var allcls = target.className;
if (allcls.indexOf(clsName)) {
target.className = allcls.replace(clsName," " );
}
}
zepto.js版:1
2
3
4
5
6
7
8
9
10
11
removeClass: function (name ) {
return this .each(function (idx ) {
if (!('className' in this )) return
if (name === undefined ) return className(this , '' )
classList = className(this )
funcArg(this , name, idx, classList).split(/\s+/g ).forEach(function (klass ) {
classList = classList.replace(classRE(klass), " " )
})
className(this , classList.trim())
})
},
看我慢慢读懂他在做些什么… 第4行有个函数className:1
2
3
4
5
6
7
8
function className (node, value ) {
var klass = node.className || '' ,
svg = klass && klass.baseVal !== undefined
if (value === undefined ) return svg ? klass.baseVal : klass
svg ? (klass.baseVal = value) : (node.className = value)
}
哇擦后面他在干什么。。应该是在respecting SVGAnimatedString
所以第四行就是如果传入的类名为空,则设置该元素的类为空(移除所有类)。 还有个funcArg(),一看就觉得是来获得函数参数的:1
2
3
function funcArg (context, arg, idx, payload ) {
return isFunction(arg) ? arg.call(context, idx, payload) : arg
}
好像不是呢哈哈哈。。。 在这里是返回了原来的name
。(name有可能是函数,这个会比较复杂) 然后对返回的字符串进行正则表达式匹配:/\s+/g
。\s
代表空格,+
代表一个或者多个。所以这样就把类名通过空格分开来存放到数组里面了。 然后又有一个新函数:1
2
3
4
function classRE (name ) {
return name in classCache ?
classCache[name] : (classCache[name] = new RegExp ('(^|\\s)' + name + '(\\s|$)' ))
}
这里的正则表达式:'(^|\\s)'
代表以空格或者什么都没有开始,'(\\s|$)'
代表以空格或什么都没有结束。连起来就是:className
可以匹配,className
也可以匹配。 所以就是设置类名。。。 回到原来的函数,就是找到那个类名,然后换回” “。 最后是删除字符串前后的空格符trim()
赋值给元素的类。和String.prototype.trim()
一样。 啊终于看了个七七八八了。。
函数节流 1
2
3
4
5
6
7
8
9
function throttle (method, context ) {
if (method.tId) {
clearTimeout(method.tId);
};
method.tId = setTimeout(function ( ) {
method.call(context);
}, 150 );
}
这个东西用在window.onsize()
或者window.onscroll()
之前就在想我擦网页滚动一下就执行函数会不会太消耗性能了,后来就发现了这个东西,不过最后没有这么用,而是:1
2
3
4
5
6
7
8
9
10
window .onscroll = function ( ) {
if (onscrollTimer) {
clearTimeout(onscrollTimer);
}
onscrollTimer = setTimeout(function ( ) {
},
100 );
}
每隔0.1s触发一次。实际运行效果很OK。
事件函数 前面有篇文章写了,这次也用到了。兼容性良好。。