??xml version="1.0" encoding="utf-8" standalone="yes"?>
<html>
<head>
<script src="prototype.js"></script> //@7
<script type="text/javascript">
/**********************************
*
* 实现渲染一个带?上一??下一?的组?点击"上一?,当前减1,点击"下一?当前加1
*
*/
function PagesSystem(container){
this.currentPage = 10; //当前?br />
this.pageSysDiv = document.getElementById(container); //容器
this.init = function() { //组件画出来
this.createPrePage();
this.createNextPage();
};
this.changePage = function(evtObj) { //Ҏ(gu)点击后传q来的参数决定是?或是?
if(evtObj == "next") {
this.currentPage += 1;
alert("你已执行当前页?Q现在当前页是:(x)" + this.currentPage);
}else if(evtObj == "pre"){
//此处不作if(this.currentPage ==1) return;限制Z(jin)体现当传入的参数?pre"Ӟ下面的alert()一定会(x)执行
this.currentPage -= 1;
alert("你已执行当前页?Q现在当前页是:(x)" + this.currentPage);
}
};
this.createPrePage = function() {//创徏上一늻?br />
var _span = document.createElement("SPAN");
_span.style.cssText = "margin-left:16px";
var _a = document.createElement("A");
_a.href = "#";
_a.onclick = this.changePage; //@1 当点?yn)LQ?上一?Q铵钮时执行
_a.innerText = "上一?;
_span.appendChild(_a);
this.pageSysDiv.appendChild(_span);
};
this.createNextPage = function() {//创徏下一늻?br />
var _span = document.createElement("SPAN");
_span.style.cssText = "margin-left:16px";
var _a = document.createElement("A");
_a.href = "#";
_a.onclick = this.changePage; //@2 当点?yn)LQ?下一?Q铵钮时执行
_a.innerText = "下一?;
_span.appendChild(_a);
this.pageSysDiv.appendChild(_span);
};
this.init(); //执行初始?br />
}
function testUse(msg){//@3在提出问题环节用?br />
alert(msg);
}
window.onload = function() {
var ps = new PagesSystem("pageDiv");
}
</script>
</head>
<body>
<div id="pageDiv"></div>
</body>
</html>
二、分析代码,提出问题Q解决问?br />
1、无法传递参数问题?br />
你细看@1和@2?当前的代码实现是无法?pre"?next"参数传递过去,于是Q当你运行例子,点击上一|下一,都是没信息alert出来的!
q种情况Q是很常见的。那么,如何实现参Cq去?br />
@1处代码修改如下:(x)
_a.onclick = function(){ //@1 当点?yn)LQ?上一?Q铵钮时执行
testUse("pre"); //参看@3
this.changePage("pre");
}
q样创徏一个匿名函数赋予_a.onclick,也就是当_a对象的onclick事g触发后将执行此匿名函敎ͼ而匿名函数将帮忙调用testUse("pre")和this.changePage("pre")两个Ҏ(gu)Q?br />
从而达成传递参数?br />
修改代码Q运行例子后点击上一后?x)显C如下两个信息,一个是testUse中输出的信息Q证明了(jin)实现参数传递,另一个却是运行错误提C?br />
q是执行this.changePage("pre")Ҏ(gu)抛出来的。它q没像我们预期想的运行?br />
从提C到的信息是,对象不支持此属性或Ҏ(gu)Q如果浏览器报的是中文提C就可以看到“对象不支持此Ҏ(gu)或属?#8221;的提C)(j)
回头看this.changePage("pre")Ҏ(gu)Q很明显this是错误提CZ所指的对象Q在本应用中指PagesSystem对象指针的引用,在应用中实是声明了(jin)this.changePage("pre")Ҏ(gu)Q但Z么说没此Ҏ(gu)呢?Q?Q?br />
2、在问题1中,我们已成功解决传递参敎ͼ但PagesSystem对象的changePageҎ(gu)被谁偷了(jin)Q?Q?br />
再将刚才的代码修改如:
_a.onclick = function(){ //@1 当点?yn)LQ?上一?Q铵钮时执行
testUse("pre"); //参看@3
alert(this.tagName);
this.changePage("pre");
}
再运行例子,你会(x)发现输出this.tagName的gؓ(f) A, 它就是_a对象。噢Q我的天啊。怎么?x)这PQ?
哈哈..._a对象是<a href=""/></a>q个html 元素对象Q这里是“上一?#8221;铵钮对象Q原型中哪来changePageҎ(gu)啊,所以报错!Q!
你可以这L(fng)解,看如下代?
function PagesSystem(container){//此应用中的PagesSystem对象QchangePageҎ(gu)的上下文对象,也可以称为归属者?br />
//...省略其它代码
this.changePage = function(evtObj) { //Ҏ(gu)点击后传q来的参数决定是?或是?
if(evtObj == "next") {
this.currentPage += 1;
alert("你已执行当前页?Q现在当前页是:(x)" + this.currentPage);
}else if(evtObj == "pre"){
//此处不作if(this.currentPage ==1) return;限制Z(jin)体现当传入的参数?pre"Ӟ下面的alert()一定会(x)执行
this.currentPage -= 1;
alert("你已执行当前页?Q现在当前页是:(x)" + this.currentPage);
}
};
//...省略其它代码
}
q样的代码,你很Ҏ(gu)看出this是指PagesSystem, 那么我们l箋(hu)往下看
假设 A对象的原型如?
function A() {//@4
//...
this.onclick;
this.doClick = function() { //点击
this.onclick();//执行
}
//...
}
当你在PagesSystemҎ(gu)?br />
_a.onclick = function(){ //@1 当点?yn)LQ?上一?Q铵钮时执行
testUse("pre"); //参看@3
alert(this.tagName);
this.changePage("pre");
}
写上q样的代码后,你可以离p为@4的代码的模样是如下:(x)
function A() {//@4
//...
this.onclick = function(){ //@1 当点?yn)LQ?上一?Q铵钮时执行
testUse("pre"); //参看@3
alert(this.tagName); //@5
this.changePage("pre"); //@6
};
this.doClick = function() { //点击
this.onclick();//执行
}
//...
}
呵呵。。如果这L(fng)的话Q@5,@6中的this当然是指a对象Q没异义。那当然是没changePageҎ(gu)?br />
3、那么如何解册问题呢?Q?br />
很幸q,prototype.js中的bindҎ(gu)可以解册L(fng)问题Q它q解x(chng)们上面提的传参数问题?br />
看bind大侠帅样:
bind: function() {
if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
var __method = this, args = $A(arguments), object = args.shift();
return function() {
return __method.apply(object, args.concat($A(arguments)));
}
}
bindҎ(gu)中的this是bindҎ(gu)的所属者(上下文)(j)? f.bind(),f是一个声明了(jin)的方?那么bind Ҏ(gu)里的this是f
再细看,bindҎ(gu)其实做的工作是返回一个匿名函?此匿名函数帮忙执行this所指的Ҏ(gu)QbindҎ(gu)的所属者)(j)Q如果你有如下代?br />
function f(msg) {
this.functionName = "f method";
alert(msg);
alert(this.functionName);
}
button.onclick = f.bind(this, msg); //q里的this指f, 在bindҎ(gu)中用object = args.shift()获得Q这L(fng)话,当点击button后执行fҎ(gu), fҎ(gu)中的this׃?x)无故?button代替。^_^不然Q会(x)报错的啊Qbutton哪来functionNameQ呵?..
它既解决msg参数传过去,同时fl定到button环境下,bindҎ(gu)得名可能是q意义吧。至于如何实现将fl定Q靠的就是applyҎ(gu)?br />
apply谜h色彩q你们自行L开啦!
介绍?jin)bind大侠l大Ӟ我的例子麻?ch)你们自p通它啦。谢?jin)。?br />
Ƣ迎交流指正?br />
备注Q?nbsp;如需转蝲本文Q请注明出处