我正在尝试创建一个简单的标签系统..但代码仅适用于第一次点击,然后停止响应。
我不想使用jquery ui,因为文件大小相当大。
$("#container1").hide();
if ($("#container1").is(":visible")) {
$("#link1").click(function () {
$("#container1").hide();
$("#container2").show();
});
};
if ($("#container2").is(":visible")) {
$("#link2").click(function () {
$("#container1").show();
$("#container2").hide();
});
};
这样接触像我一样的新手,谁能告诉我哪里出错?
这是一个fiddle
感谢
答案 0 :(得分:4)
这里的初始问题是,如果容器可见,您只绑定click事件。您希望绑定事件并检查回调内的状态。
$("#container1").hide();
$("#link1").click(function () {
if ($("#container1").is(":visible")) {
$("#container1").hide();
$("#container2").show();
};
});
$("#link2").click(function () {
if ($("#container2").is(":visible")) {
$("#container1").show();
$("#container2").hide();
};
});
值得一提的是,为什么会发生这种情况以及为什么你会期待不同的结果。为此,我们应该遍历每个示例的执行堆栈:
hide the container1 element
check if container1 is visible (it isn't) and if so:
add a callback to the click event of link1 element
check if container2 is visible (it is) and if so:
add a callback to the click event of link2 element
user clicks link2
callback registered to link2 click is fired
show container1
hide container2
现在您可以看到即使用户点击link1也没有效果,因为回调从未注册过。
有一种更惯用的方法来解决这个问题,即创建一个jquery插件,如下所示:
// http://jsfiddle.net/S8h5v/5/
// js:
$.fn.tabSample = function(){
$(this).each(function(idx, el){
var $this = $(this);
$this.delegate('.tabs div', 'click', function(event){
var index = $this.find(".tabs div").index(event.target);
$this.find(".contents div").removeClass('active');
var item = $this.find(".contents div:eq(" + index + ")").addClass('active');
console.log(item, index);
});
$this.find('.contents div:eq(0)').addClass('active');
});
};
// html
<div class="tab-control">
<div class="tabs">
<div>Link 1</div>
<div>Link 2</div>
</div>
<div class="contents">
<div>container 1</div>
<div>container 2</div>
</div>
</div>
// css
.tab-control .tabs div {
display: inline-block;
cursor:pointer;
padding:10px 30px;
background-color:blue;
border: solid 1px lightblue;
}
.tab-control .contents div {
display: none;
width:100%;
height:100px;
background-color:red;
}
.tab-control .contents div.active {
display: inline-block;
}
您可能尝试这种方法的原因是它增加了代码的灵活性。例如,要添加新内容项,您只需向tabs元素添加一个新div,并向内容元素添加一个新div,然后它们将自动连接以支持Tab键。您还可以通过增强.active css定义来更改“显示”和“隐藏”的方式,以便在更现代的浏览器中使用css3过渡和动画。这也允许您的代码是可移植的,因此如果您在单个页面上有多个选项卡控件,则可以创建它们而不会遇到冲突:
$(".first-tabset").tabSample();
$(".second-tabset").tabSample();
// any elements within these sets will not affect the other.
答案 1 :(得分:3)
http://jsfiddle.net/BJ8vZ/解决方案,并且激活了键盘箭头键
<style>
#tabs {border-bottom:1px solid #ccc;height:33px;margin:0 0 10px;padding-top:5px;background:#eee;}
#tabs a {float:left;margin-left:2px;border-radius:3px 3px 0 0;border:1px solid #eee;border-bottom-color:#ccc;color:#08c;height:32px;line-height:32px;padding:0 12px;text-decoration:none;}
#tabs a:hover {background:#ddd;color:#058;border-color:#ddd #ddd #ccc;}
#tabs a.active {background:#fff;color:#555;border-color:#ccc #ccc #fff;}
#tabs a.active:hover {background:#fff;color:#555;border-color:#ccc #ccc #fff;}
#tabs_data fieldset {display:none;border:0;}
#tabs_data fieldset div {font-size:13px;}
</style>
<div id="tabs">
<a href="#" onclick="tab_click(0);">tab 1</a>
<a href="#" onclick="tab_click(1);">tab 2</a>
<a href="#" onclick="tab_click(2);">tab 3</a>
</div>
<div id="tabs_data">
<fieldset> contents of tab 1</fieldset>
<fieldset> contents of tab 2</fieldset>
<fieldset> contents of tab 3</fieldset>
</div>
<script>
var tabActive=1, tabs=document.getElementById('tabs').getElementsByTagName('A'), tabs_data=document.getElementById('tabs_data').getElementsByTagName('fieldset');
function tab_click(x){
if(x > -1 && x < tabs.length && x < tabs_data.length){
tabs[tabActive].setAttribute('class','');
tabs_data[tabActive].style.display='none';
tabActive=x;
tabs[tabActive].setAttribute('class','active');
tabs_data[tabActive].style.display='block';
} return false;
}tab_click(0);
document.onkeydown=function (evnt){
if(evnt.keyCode==37 || evnt.keyCode==39)
tab_click(tabActive+evnt.keyCode-38);
}
</script>