日志分类:JS

Javascript 中的 call 和 apply

时间:2012年02月01日作者:愚人码头查看次数:1,944 views评论次数:2

JavaScript 中通过call或者apply用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。简单的说就是改变函数执行的上下文,这是最基本的用法。两个方法基本区别在于传参不同。

  • call(obj,arg1,arg2,arg3);call第一个参数传对象,可以是null。参数以逗号分开进行传值,参数可以是任何类型。
  • apply(obj,[arg1,arg2,arg3]);apply第一个参数传对象,参数可以是数组或者arguments 对象。

这两个方法通常被用来类的继承和回调函数:

作用一、类的继承:

先来看这个例子:


function Person(name,age){

this.name = name;

this.age=age;

this.alertName = function(){

alert(this.name);

}

this.alertAge = function(){

alert(this.age);

}

}

function webDever(name,age,sex){

Person.call(this,name,age);

this.sex=sex;

this.alertSex = function(){

alert(this.sex);

}

}

var test= new webDever("愚人码头",28,"男");

test.alertName();//愚人码头

test.alertAge();//28

test.alertSex();//男

这样 webDever类就继承Person类,Person.call(this,name,age) 的 意思就是使用 Person构造函数(也是函数)在this对象下执行,那么 webDever就有了Person的所有属性和方法,test对象就能够直接调用Person的方法以及属性了; 09年的理解解非常粗浅,呵呵。http://www.css88.com/archives/1692

作用二、回调函数:

call 和 apply在回调行数中也非常有用,很多时候我们在开发过程中需要对改变回调函数的执行上下文,最常用的比如ajax或者定时什么的,一般情况下,Ajax都是全局的,也就是window对象下的,来看这个例子:


function Album(id, title, owner_id) {

this.id = id;

this.name = title;

this.owner_id = owner_id;

};

Album.prototype.get_owner = function (callback) {

var self = this;

$.get('/owners/' + this.owner_id, function (data) {

callback && callback.call(self, data.name);

});

};

var album = new Album(1, '生活', 2);

album.get_owner(function (owner) {

alert('The album' + this.name + ' belongs to ' + owner);

});

这里


album.get_owner(function (owner) {

alert('The album' + this.name + ' belongs to ' + owner);

});

中的 this.name就能直接取到album对象中的name属性了。

标签:,分类:JS

javascript插入样式

时间:2012年01月30日作者:愚人码头查看次数:1,856 views评论次数:7

最近做一个项目,需要javascript动态插入样式,结果以前的方法失效了!查了2个小时的原因竟然是自己手贱,这个最后再说!

javascript插入样式在前端开发中应用比较广泛,特别是在修改前端表现和页面换肤的时候。最近做的这个任务是用户在别人的站点上点击一个按钮,就会在别的站点页面下插入一个脚本,执行,这其中包含了样式的插入。

一般情况下javascript动态插入样式有两种,一种页面中引入外部样式,在<head>中使用<link>标签引入一个外部样式文件,另一种是在页面中使用<style>标签插入页面样式(这里说的不是style属性)。

一、页面中引入外部样式:

在<head>中使用<link>标签引入一个外部样式文件,这个比较简单,各个主流浏览器也不存在兼容性问题:


function includeLinkStyle(url) {
var link = document.createElement("link");
link.rel = "stylesheet";
link.type = "text/css";
link.href = url;
document.getElementsByTagName("head")[0].appendChild(link);
}

includeLinkStyle("http://css.sodao.com/home/css/reset.css?v=20101227");

但是在我目前做的这个项目中本身应用的样式非常少,直接用引入一个外部样式文件似乎不合适,所以我选择了第二种方案,在页面中使用<style>标签插入页面样式。

二、使用<style>标签插入页面样式:

这种方式在各个主流浏览器存在兼容性问题,像firefox等标准浏览器无法直接获取设置styleSheet的cssText值,标准浏览器下只能使用document.styleSheets[0].cssRules[0].cssText单个获取样式;同时使用:document.styleSheets[0].cssRules[0].cssText=newcssText;页面不会自动更新样式,必须使用:document.styleSheets[0].cssRules[0].style.cssText=newcssText;这点似乎没坑爹的IE来的人性化和简便。YUI中使用了一个很好的办法:style.appendChild(document.createTextNode(styles));采用createTextNode将样式字符串添加到<style>标签内;


function includeStyleElement(styles,styleId) {

if (document.getElementById(styleId)) {
return
}
var style = document.createElement("style");
style.id = styleId;
//这里最好给ie设置下面的属性
/*if (isIE()) {
style.type = "text/css";
style.media = "screen"
}*/
(document.getElementsByTagName("head")[0] || document.body).appendChild(style);
if (style.styleSheet) { //for ie
style.styleSheet.cssText = styles;
} else {//for w3c
style.appendChild(document.createTextNode(styles));
}
}
var styles = "#div{background-color: #FF3300; color:#FFFFFF }";
includeStyleElement(styles,"newstyle");

这样页面中的元素就能直接应用样式了,不管你的这些元素是不是通过脚本追加的。

关于手贱:

看这段代码:


var divObj = document.createElement("div");
divObj .id = "__div";
divObj .innerHTML="测试js插入DOM和样式";
document.body.appendChild(divObj );

var styles = "#__div{background-color: #FF3300; color:#FFFFFF }";
includeStyleElement(styles,"newstyle");

前面说了这个项目是用户在别人的站点上点击一个按钮,就会在别的站点页面下插入一个脚本,执行,这其中包含了样式的插入,我为了尽可能的保证我创建的元素ID唯一性,手贱在元素ID前加了“__”,表示私有防止冲突。结果悲剧了,IE6,IE7 class和id的命名不能以下划线开头(“_”),竟然把这个给忘了!花了两个小时才找到原因。悲剧啊!得出一个结论!做前端千万不能手贱!

标签:,分类:JS

Javascript绝句欣赏

时间:2012年01月19日作者:愚人码头查看次数:2,496 views评论次数:4

转载自:http://site.douban.com/widget/notes/22456/note/142716442/

1. 取整同时转成数值型:

’10.567890′|0
结果: 10
’10.567890′^0
结果: 10
-2.23456789|0
结果: -2
~~-2.23456789
结果: -2

2. 日期转数值:
var d = +new Date(); //1295698416792

3. 类数组对象转数组:
var arr = [].slice.call(arguments)

4. 漂亮的随机码:
Math.random().toString(16).substring(2); //14位
Math.random().toString(36).substring(2); //11位

5. 合并数组:
var a = [1,2,3];
var b = [4,5,6];
Array.prototype.push.apply(a, b);
uneval(a); //[1,2,3,4,5,6]

6. 用0补全位数:
function prefixInteger(num, length) {
return (num / Math.pow(10, length)).toFixed(length).substr(2);
}

7. 交换值:
a= [b, b=a][0];

8. 将一个数组插入另一个数组的指定位置:
var a = [1,2,3,7,8,9];
var b = [4,5,6];
var insertIndex = 3;
a.splice.apply(a, Array.concat(insertIndex, 0, b));
// a: 1,2,3,4,5,6,7,8,9

9. 删除数组元素:
var a = [1,2,3,4,5];
a.splice(3,1);

10. 快速取数组最大和最小值
Math.max.apply(Math, [1,2,3]) //3
Math.min.apply(Math, [1,2,3]) //1
(出自http://ejohn.org/blog/fast-javascript-maxmin/)

11. 条件判断:
var a = b && 1;
相当于
if (b) {
a = 1
}

var a = b || 1;
相当于
if (b) {
a = b;
} else {
a = 1;
}

12. 判断IE:
var ie = /*@cc_on !@*/false;

还有吗?欢迎回应

分类:JS

Underscore.string.js Version (2.0.0) 中文文档

时间:2012年01月07日作者:愚人码头查看次数:1,866 views评论次数:3

Javascript缺乏完整的字符串操作。Underscore.string.js试图填补这一空白。

正如名称指出的Underscore.string.js为 Underscore.js 的扩展,但你可以独立使用_s-全局变量。但配合 Underscore.js 使用。
Underscore.string.js Version (2.0.0) 中文文档:http://www.css88.com/doc/underscore.string/

github项目地址:http://epeli.github.com/underscore.string/ | https://github.com/epeli/underscore.string

设置样式方法setStyle

时间:2011年12月26日作者:愚人码头查看次数:1,715 views评论次数:0

上周在微博上看到这样一条微博:

这个setStyle方法确实避免了mydiv.style.xxx这种写法大量重复的代码,确实代码简洁了不少,也很直观,但是这里还有一个问题,如果设置的样式一多,重复操作DOM无法避免,销毁原样式并重建都会增加浏览器的开销。我们可以先生成一个样式字符串,再一次性设置样式,这样可以尽量避免页面reflow。例如:

[cc lang="javascript" width="630" tab_size="4"  ]

//类型判断
var TypeC=window.TypeC||{};
(function(TC){
var toString = Object.prototype.toString;
TC.isString = function(o) {
return toString.call(o) === ‘[object String]‘;
};
TC.isObject = function(o) {
return toString.call(o) === ‘[object Object]‘;
};
})(TypeC);

function setStyle(el, style) {//style变量:{“display”:”block”,”font-size”:”28px”,”color”:”red”}
var sty=”";
if (TypeC.isString(style)){
sty=style;
}else if (TypeC.isObject(style)) {
var s;
for (s in style) {
sty += s+”:”+style[s]+”;”;
}
}
el.style.cssText +=”;”+sty;
}

[/cc]

如果参数style传进来的是字符串,那么直接用cssText设置样式,如果是个对象,先将对象拼装成字符串,再用cssText设置样式;

这里使用了obj.style.cssText=“”;这种写法,

很蛋疼的是这里使用了这样一句:el.style.cssText +=”;”+sty;

原因是:obj.style.cssText=“”;这种写法会把原有的cssText清掉,比如原来的style中有’display:none;’,那么执行完上面的JS后,display就被删掉了。
为了解决这个问题,可以采用cssText累加的方法:

Element.style.cssText += ’width:100px;height:100px;top:100px;left:100px;’

但是,cssText(假如不为空)在IE中最后一个分号会被删掉,比较BT….
因此,上面cssText累加的方法在IE中是无效的。

最后,可以在前面添加一个分号来解决这个问题:

Element.style.cssText += ’;width:100px;height:100px;top:100px;left:100px;’

具体可以查看:用cssText批量修改样式[更新]

标签:,分类:JS

javascript中神奇的(+)加操作符

时间:2011年12月17日作者:愚人码头查看次数:2,563 views评论次数:9

javascript是一门神奇的语言,这没神奇的语言中有一个神奇的加操作符。

常用的加操作符我们可以用来做:

  1. 加法运算,例如:alert(1+2); ==>3
  2. 字符串连接,例如:alert(“a”+”b”);==>”ab”

高级一点的还有“+=”,也是做以上两种操作的。

昨天在javascript丛林群里问了问题:怎么把“2000-09-11 19:22”这个日期格式字符串转换成毫秒数?

斩梦人天天马上回答我: +new Date(’2000-09-11 19:22′),试了一下不行,正确的应该是+new Date(’2000/09/11 19:22′)。

答案似乎已经不重要了,你看这前面有个加操作符,说实话这种写法以前真没见过。神奇的javascript中的加操作符,还有非常神奇的作用,转换数据类型,一般是字符串和数值的转换,例如,javascript丛林网友jason给的例子:

// 16进制转换:
+”0xFF”;              // -> 255

// 获取当前的时间戳,相当于`new Date().getTime()`:
+new Date();

// 比 parseFloat()/parseInt()更加安全的解析字符串
parseInt(“1,000″);    // -> 1, not 1000
+”1,000″;             // -> NaN, much better for testing user input
parseInt(“010″);      // -> 8, because of the octal literal prefix
+”010″;               // -> 10, `Number()` doesn’t parse octal literals
//一些简单的缩写比如: if (someVar === null) {someVar = 0};
+null;                // -> 0;

// 布尔型转换为整型
+true;                // -> 1;
+false;               // -> 0;

//其他:
+”1e10″;              // -> 10000000000
+”1e-4″;              // -> 0.0001
+”-12″;               // -> -12:

当然还有数字加空字符串的操作就可以将数字转化为字符串,例如: alert( typeof (1+”")); // ->string;

另外附送一个将字符串转化为数字的减操作符,例如: alert( typeof (“123″-0));//->number;

当然对于加操作符可能还有未知一些使用特性,欢迎留言补充!谢谢斩梦人天天,谢谢jason,谢谢javascript丛林的其他网友。

 

 

 

标签:分类:JS

Underscore.js Version (1.2.3) 中文文档

时间:2011年12月13日作者:愚人码头查看次数:5,738 views评论次数:3

Underscore 一个非常实用的JavaScript库,提供许多编程功能的支持,就像你期望 Prototype.js (或者 Ruby), 有这些功能且不扩展任何JavaScript的原生对象。有函数式编程的风格,还支持链式调用。主要涉及对Collection、Object、Array、Function的操作,还有一些实用方法。可以说是写JavaScript程序的必用类库。

Underscore.js Version (1.2.3) 中文文档:http://www.css88.com/doc/underscore/

注:Collections和Functions翻译来自http://wangjianjun.github.com/underscore/underscore.html

Underscore.js Version (1.2.3) 源码解析:http://www.css88.com/doc/underscore/docs/underscore.html
Underscore.js 测试:
http://www.css88.com/doc/underscore/test/test.html
http://www.css88.com/doc/underscore/test/temp_tests.html

seaJs的模块定义、模块加载及模块依赖关系

时间:2011年12月11日作者:愚人码头查看次数:2,256 views评论次数:3

SeaJS 是由玉伯开发的一个遵循 CommonJS 规范的模块加载框架,可用来轻松愉悦地加载任意 JavaScript 模块和css模块样式。SeaJS非常小巧,小巧在于压缩和gzip后体积只有4K,而且接口和方法也非常少,SeaJS 就两个核心:模块定义和 模块的加载及依赖关系。SeaJS非常强大,SeaJS可以加载任意 JavaScript 模块和css模块样式,SeaJS会保证你在使用一个模块时,已经将所依赖的其他模块载入到脚本运行环境中。玉伯的说法,SeaJS可以让你享受写代码的乐趣,不用去管那些加载的问题。你是否厌倦了如此多的js和css引用,我数了一下我们公司网站的个人主页首页上有39个css和js引用,带来的影响可想而知:

1.不利于维护,前端后端都一样,

2.http请求过多,当然这个可以通过合并解决,但是如果没有后端直接合并,人工成本非常大,就算后端合并,维护的时候,这么长的一个字符串,眼睛肯定看花

用SeaJS就能非常好的解决这些问题。

模块的定义define

定义一个模块比较简单,例如定义一个sayHello模块,建一个sayHello.js文档:


define(function(require,exports,module){
exports.sayHello = function(eleID,text) {
document.getElementById(eleID).innerHTML=text;
};
});

这里先看一下exports参数,exports参数是用来向外提供模块的 API.也就是通过这个exports其他的模块就能访问sayHello方法。
继续阅读:seaJs的模块定义、模块加载及模块依赖关系»

标签:,分类:JS

[jQuery插件]Pause 暂停

时间:2011年12月07日作者:愚人码头查看次数:1,819 views评论次数:1

jQuery 本身的动画只有停止的功能,一但停止(stop)后就无法自动接着做未做完的动画内容。 因此Pause插件扩充了animate() 的功能,让它可以支持暂停(pause)及恢复(resume)动画。
这个插件覆盖jQuery的默认的animate()方法,任何加载了这个插件的动画都将支持Pause暂停。两个新的不带任何参数的方法被添加到每一个jQuery对象:pause()和resume()。
例如:
$box.hover(function() {
$box.pause();
}, function() {
$box.resume();
});

demo演示地址:http://tobia.github.com/Pause/

项目地址:https://github.com/tobia/Pause

标签:分类:jQuery

简单的字符串模板

时间:2011年12月03日作者:愚人码头查看次数:1,845 views评论次数:9

每次在写脚本的时候拼装字符串是个头痛的事情,主要是双引号,单引号,还有一堆变量,一不小心就搞错了,而且可读性非常差。这里推荐一个小工具:http://www.html-js.com/my-js/version0.0.1/tool/html2string.html 这个工具可以将复杂的字符串转换成js的字符串。至少解决的了手动拼装的的问题,但是变量的话还是非常难受。比如一个列表:

  • 《愚人码头》 – 熊天平
  • 《富士山下》 - 陈奕迅
  • 《假如》 – 信乐团
通常如果是异步的请求,后端一般返回回来的是一个json:

[
{"song":"愚人码头","songurl":"http://www.css88.com/mp3/1.html","songer":"熊天平","songerurl":"http://www.css88.com/songer/1.html"},
{"song":"富士山下","songurl":"http://www.css88.com/mp3/2.html","songer":"陈奕迅","songerurl":"http://www.css88.com/songer/2.html"},
{"song":"假如","songurl":"http://www.css88.com/mp3/3.html","songer":"信乐团","songerurl":"http://www.css88.com/songer/3.html"}
]

通常情况下会这样拼装:


var listData=[
{"song":"愚人码头","songurl":"http://www.css88.com/mp3/1.html","songer":"熊天平","songerurl":"http://www.css88.com/songer/1.html"},
{"song":"富士山下","songurl":"http://www.css88.com/mp3/2.html","songer":"陈奕迅","songerurl":"http://www.css88.com/songer/2.html"},
{"song":"假如","songurl":"http://www.css88.com/mp3/3.html","songer":"信乐团","songerurl":"http://www.css88.com/songer/3.html"}
];
    var listHtml="<ul>"
    for(var i=0,lengths = listData.length;i < lengths;i++){
        listHtml+='<li class="item">《'+listData[i].song+'》 - <span>'+listData[i].songer+'</span>'
    }
    listHtml+="</ul>"
    console.log(listHtml);

继续阅读:简单的字符串模板»

标签:分类:JS
Page 2 of 2812345678910Last »