javascript实现tab标签组件2

接着javascript实现tab标签组件1,来继续完善tab标签组件,在之前的几个示例中都是通过点击事件来触发标签切换,下面实现定制激活事件的功能。

<div class="tab J_tab">
<ul class="tab-menuWrapper">
<li class="J_tab-menu tab-currentMenu1">menu1</li>
<li class="J_tab-menu">menu2</li>
<li class="J_tab-menu">menu3</li>
</ul>
<div class="tab-contnetWrapper">
<div class="J_tab-content">
<div>content1</div>
<ul>
<li>1</li>
<li>2</li>
</ul>
</div>
<div class="J_tab-content" style="display:none;">
<p>content2</p>
<div>abc</div>
</div>
<div class="J_tab-content" style="display:none;">
content3
</div>
</div>
</div>
<div class="tab J_tab">
<ul class="tab-menuWrapper">
<li class="J_tab-menu tab-currentMenu2">menu1</li>
<li class="J_tab-menu">menu2</li>
<li class="J_tab-menu">menu3</li>
</ul>
<div class="tab-contnetWrapper">
<div class="J_tab-content">
<div>content1</div>
<ul>
<li>1</li>
<li>2</li>
</ul>
</div>
<div class="J_tab-content" style="display:none;">
<p>content2</p>
<div>abc</div>
</div>
<div class="J_tab-content" style="display:none;">
content3
</div>
</div>
</div>
<div class="tab J_tab">
<ul class="tab-menuWrapper">
<li class="J_tab-menu tab-currentMenu3">menu1</li>
<li class="J_tab-menu">menu2</li>
<li class="J_tab-menu">menu3</li>
</ul>
<div class="tab-contnetWrapper">
<div class="J_tab-content">
<div>content1</div>
<ul>
<li>1</li>
<li>2</li>
</ul>
</div>
<div class="J_tab-content" style="display:none;">
<p>content2</p>
<div>abc</div>
</div>
<div class="J_tab-content" style="display:none;">
content3
</div>
</div>
</div>

Javascript:

<script type="text/javascript">
var GLOBAL = {};
GLOBAL.namespace
= function(str){
var arr = str.split('.'),o = GLOBAL;
for(i = (arr[0] == GLOBAL)?1:0;i<arr.length;i++){
o[arr[i]]
= o[arr[i]]||{};
o
= o[arr[i]];
}
}
GLOBAL.namespace(
"Dom");
GLOBAL.Dom.getElementsByClassName
= function(str,root,tag){
if(root){
root
= (typeof root == "string")?document.getElementById(root):root;
}
else{
root
= document.body;
}
tag
= tag||'*';
var els = root.getElementsByTagName(tag),arr = [];
for(var i=0,leng = els.length;i<leng;i++){
var k = els[i].className.split(' ');
for(j = 0,len = k.length;j<len;j++){
if(k[j] == str){
arr.push(els[i]);
break;
}
}
}
return arr;
}
GLOBAL.Dom.addClass
= function(node,str){
var reg = new RegExp("(^|\\s+)"+str);
if(!reg.test(node.className)){
node.className
= node.className+" "+str;
}
}
GLOBAL.Dom.removeClass
= function(node,str){
var reg = new RegExp("(^|\\s+)"+str);
if(reg.test(node.className)){
node.className
= node.className.replace(reg,"");
}
}
GLOBAL.namespace(
"Event");
GLOBAL.Event.on
= function(node,eventType,handler,scope){
//scope用来设置handler中this的指针,默认指向node节点
Node = (typeof node == "string")?document.getElementById(node):node;
scope
= scope || Node;
if(node.addEventListener){
node.addEventListener(eventType,
function(){handler.apply(scope,arguments)},false);
}
else if(node.attachEvent){
node.attachEvent(
"on"+eventType,function(){handler.apply(scope,arguments)});
}
else{
node[
'on'+eventType] = function(){handler.apply(scope,arguments)};
}
}
function setTab(root,currentClass,trigger){
//取得标签及内容的节点,并以数组的形式保存在变量中
var tabMenus = GLOBAL.Dom.getElementsByClassName('J_tab-menu',root),
tabContents
= GLOBAL.Dom.getElementsByClassName('J_tab-content',root);
//如果不传入激活类型,默认激活类型为点击
trigger = trigger||"click";
//遍历数组,让标签监听click事件
for(var i=0,leng = tabMenus.length;i<leng;i++){
tabMenus[i]._index
= i;
GLOBAL.Event.on(tabMenus[i],trigger,
function(){
for(var j=0,len = tabContents.length;j<len;j++){
tabContents[j].style.display
="none";
}
tabContents[
this._index].style.display = "block";
var currentMenu = GLOBAL.Dom.getElementsByClassName(currentClass,root)[0];
if(currentMenu){
GLOBAL.Dom.removeClass(currentMenu,currentClass);
}
GLOBAL.Dom.addClass(
this,currentClass);
},tabMenus[i]);
}
}
var tabs = GLOBAL.Dom.getElementsByClassName('J_tab');
setTab(tabs[
0],"tab-currentMenu1",null);
setTab(tabs[
1],"tab-currentMenu2","mouseover");
setTab(tabs[
2],"tab-currentMenu3",null);
</script>

在上面的代码中需要注意的是关于this问题的处理。

如何控制this关键字的指向的讨论

在javascript中this是个让人捉摸不定的东西

1.javascript中伪协议和内联事件的this指向不同

<!-- 弹出A -->
<a href="#" onclick="alert(this.tagName)">Click me</a>
<!-- 弹出Undefined -->
<a href="JavaScript:alert(this.tagName)">Click me</a>
<!-- 弹出True -->
<a href="JavaScript:alert(this==window)">Click me</a>

通过case发现内联事件的this指向当前点击的对象,而伪协议里的this则是指向window.

2.setTimeout和setInterval也会改变this的指向。

<script type="text/javascript">
var name="somebody";
var adang={
name:
"adang",
say:
function(){
alert(
"I'm "+this.name);
}
}
adang.say();
//I'm adang

setTimeout(adang.say,
1000);//I'm somebody
setInterval(adang.say,1000);//I'm somebody
</script>

3.node.onXXX也会改变this的指向

<input type="button" value="ClickMe" id="btn" name="btn"/>
<script type="text/javascript">
var btn = document.getElementById('btn');
var name="somebody";
var adang={
name:
"adang",
say:
function(){
alert(
"I'm "+this.name);
}
}
adang.say();
//I'm adang
btn.onclick=adang.say;//I'm btn
</script>

解决this指向的问题有两个方法:

1.匿名函数的方法:

<input type="button" value="ClickMe" id="btn" name="btn"/>
<script type="text/javascript">
var btn = document.getElementById('btn');
var name="somebody";
var adang={
name:
"adang",
say:
function(){
alert(
"I'm "+this.name);
}
}
adang.say();
//I'm adang
setTimeOut(function(){adang.say()},1000);//I'm adang
setInterval(function(){adang.say()},1000);//I'm adang
btn.onclick=function(){adang.say()};//I'm adang
setTimeOut(function(){alert(this==window)},1000)//true
btn.onclick = function(){alert(this==btn)}//true
</script>

2.使用call或apply的方法

<input type="button" value="ClickMe" id="btn" name="btn"/>
<script type="text/javascript">
var btn = document.getElementById('btn');
var name="somebody";
var adang={
name:
"adang",
say:
function(){
alert(
"I'm "+this.name);
}
}
adang.say.call(btn);
//I'm btn
btn.onclick=function(){adang.say.call(adang)};//I'm adang
</script>

3.在this改变指向之前,将它指向的对象保存到一个变量中也是非常常用的方法

<input type="button" value="ClickMe" id="btn" name="btn"/>
<script type="text/javascript">
var btn = document.getElementById('btn');
var name="somebody";
var adang={
name:
"adang",
say:
function(){
alert(
"I'm "+this.name);
},
init:
function(){
var This = this;
btn.onclick
=function(){
This.say();
//I'm adang
this.say();//报错
}
}
}
adang.init();
</script>
posted @ 2011-05-06 16:26  郭培  阅读(511)  评论(0编辑  收藏  举报