我正在与一个我试图整合的界面展开激烈的战斗。我在CSS& XHTML,但我的jQuery / JavaScript技能并不太令人印象深刻。我正在寻找的不是一个严格的答案,而是一些关于如何进行这些任务的暗示。
我想要实现的是在主内容区域中有一些框的布局,当用户按下侧边栏中的链接或框本身的标题时,可以展开和折叠。
dashboard http://www.timkjaerlange.com/foobar/example-dashboard-v01.gif
此外,我希望浏览器通过设置cookie来记住最后扩展的框。如果这还不够,我还希望能够为每个框添加一个“有限”类,从而禁用它,并且它是相应的sidebar-list-item。
此外,我希望该框具有基于其状态的类(展开,折叠,限制)。
这是我的标记:
<!-- S I D E B A R - L E F T -->
<div id="sidebar-left">
<ul class="sidebar-menu-1">
<li><strong>List headline</strong>
</li>
<li><a href="#">Open module 1</a>
</li>
<li><a href="#">Open module 2</a>
</li>
<li><a href="#">Open module 3</a>
</li>
</ul>
</div><!--/sidebar-left-->
<!-- M A I N - C O N T E N T -->
<div id="main-content">
<!-- dashboard-module -->
<div class="dashboard-module">
<div class="dashboard-module-content limited">
<h2>Headline 1</h2>
<p class="teaser">Teaser-text 1</p>
<div class="expand-collapse">
[some content]
´ </div>
</div>
</div><!--/dashboard-module-->
<!-- dashboard-module -->
<div class="dashboard-module">
<div class="dashboard-module-content limited">
<h2>Headline 2</h2>
<p class="teaser">Teaser-text 2</p>
<div class="expand-collapse">
[some content]
´ </div>
</div>
</div><!--/dashboard-module-->
<!-- dashboard-module -->
<div class="dashboard-module">
<div class="dashboard-module-content limited">
<h2>Headline 3</h2>
<p class="teaser">Teaser-text 3</p>
<div class="expand-collapse">
[some content]
´ </div>
</div>
</div><!--/dashboard-module-->
</div><!--/main-content-->
这是我的jQuery:
// If the dashboard-module is "limited" do this:
$('div[class*=limited]').each( function(index) {
var countFix = $('div.dashboard-module-content').index(this);
var countFixPlusTwo = countFix + 2;
$( 'ul.sidebar-menu-1 li:nth-child(' + countFixPlusTwo + ')' ).unbind('click').removeClass('selected').addClass('sidebar-menu-locked');
$(this).parent('.dashboard-module').find('h2').unbind('click');
$(this).find('.expand-collapse').remove();
$(this).find('.dashboard-module p:hidden').show();
$(this).addClass('limited-btn');
});
// Check for cookies and do stuff accordingly:
var cookieTest = $.cookie("cookie");
if(cookieTest == null){
$('.js-hidden').hide();
$('ul.sidebar-menu-1 li:not(.sidebar-menu-locked):eq(1)').addClass('selected');
$('.dashboard-module-content:not(.limited):eq(0)' ).toggleClass('hide-btn');
$('.dashboard-module-content:not(.limited):not(:eq(0))' ).removeClass('hide-btn');
$('.expand-collapse:eq(0)' ).show();
};
if(cookieTest != null){
var cookieTestPlusTwo = parseInt(cookieTest, 10) + 2;
$('.dashboard-module-content:eq(' + cookieTest + ')' ).toggleClass('hide-btn');
$('.dashboard-module-content:not(:eq(' + cookieTest + '))' ).removeClass('hide-btn');
$('ul.sidebar-menu-1 li:nth-child(' + cookieTestPlusTwo + '):not(.sidebar-menu-locked)').addClass('selected');
$('ul.sidebar-menu-1 li:not(:nth-child(' + cookieTestPlusTwo + '))').removeClass('selected');
$('.expand-collapse:eq(' + cookieTest + ')' ).show();
$('.expand-collapse:not(:eq(' + cookieTest + '))').hide();
};
// When clicking dashboard-module headers do stuff:
$('.dashboard-module h2:not(.limited h2):not(.tooltip h2)').click(function(index) {
var indexFoo = $('.dashboard-module h2:not(.tooltip h2)').index(this);
var indexPlusTwo = indexFoo + 2;
var indexCookie = indexFoo;
$.cookie("cookie", indexCookie, { expires: 7 });
$('.dashboard-module-content:eq(' + indexFoo + ')').toggleClass('hide-btn');
$('.dashboard-module-content:not(:eq(' + indexFoo + '))' ).removeClass('hide-btn');
$('ul.sidebar-menu-1 li:nth-child(' + indexPlusTwo + ')').addClass('selected');
$('ul.sidebar-menu-1 li:not(:nth-child(' + indexPlusTwo + '))').removeClass('selected');
$('.dashboard-module-content:eq(' + indexFoo + ') .expand-collapse').toggle('fast');
$('.dashboard-module-content:not(:eq(' + indexFoo + ')) .expand-collapse').hide('fast');
$('.dashboard-module-content:not(.limited)').each( function(){
if($(this).parent('.dashboard-module').find('.hide-btn').length == 0){
$(this).find('p.teaser').show();
}
else {
$(this).find('p.teaser').hide();
}
});
});
// When clicking sidebar list-items do stuff:
$('.sidebar-menu-1 li:not(.sidebar-menu-locked)').click(function(index) {
var indexFoo = ($('.sidebar-menu-1 li').index(this) - 1);
var indexPlusTwo = indexFoo + 2;
var indexCookie = indexFoo;
$.cookie("cookie", indexCookie, { expires: 7 });
$('.dashboard-module-content:eq(' + indexFoo + ')').toggleClass('hide-btn');
$('.dashboard-module-content:not(:eq(' + indexFoo + '))' ).removeClass('hide-btn');
$('ul.sidebar-menu-1 li:nth-child(' + indexPlusTwo + ')').addClass('selected');
$('ul.sidebar-menu-1 li:not(:nth-child(' + indexPlusTwo + '))').removeClass('selected');
$('.dashboard-module-content:eq(' + indexFoo + ') .expand-collapse').toggle('fast');
$('.dashboard-module-content:not(:eq(' + indexFoo + ')) .expand-collapse').hide('fast');
$('.dashboard-module-content:not(.limited)').each( function(){
if($(this).parent('.dashboard-module:not(.limited)').find('.hide-btn').length == 0){
$(this).find('p.teaser').show();
}
else {
$(this).find('p.teaser').hide();
}
});
});
至于现在它都可以在FF中运行,但在IE7 + 8中却没有。但我的问题不是关于如何使它在IE中运行,而是更多关于如何进行这种任务?我怀疑我的jQuery并不完全干,但我该如何压缩它呢?
您将如何编写和组织代码?很抱歉,如果这是一个过于宽泛和冗长的问题,但我真的对经验丰富的jQuery设计师如何应对这样的挑战感兴趣。
更新:感谢Tatu Ulmanen的帮助,我成功地将其组合在一起:http://timkjaerlange.com/foobar/jquery-test/index.html
答案 0 :(得分:4)
侧边栏链接 - &gt;内容关系,在侧边栏中使用与主要内容的div的ID相对应的rel标签,如下所示:
<ul id="sidebar">
<li><a href="#" rel="tab_1">Open tab 1</a></li>
<li><a href="#" rel="tab_2">Open tab 2</a></li>
<li><a href="#" rel="tab_3">Open tab 3</a></li>
</ul>
...
<div id="content">
<div class="module" id="tab_1"> ... </div>
<div class="module" id="tab_2"> ... </div>
<div class="module" id="tab_3"> ... </div>
</div>
然后在jQuery中,tab的更改很容易实现:
$('#sidebar a').click(function() {
$('#content div.module').hide();
$('#content div#'+$(this).attr('rel')).show();
return false;
});
如果您希望模块的标题始终可见,您可以执行以下操作:
<div id="content">
<div class="module" id="tab_1">
<h2>Module header</h2>
<p class="module_tools">
<a href="#" class="module_hide">Hide</a>
<a href="#" class="module_show">Show</a>
</p>
<div class="module_contents">
...
在jQuery中:
$('#sidebar a').click(function() {
var $visible_module = $('#content div#'+$(this).attr('rel'));
$('#content div.module div.module_contents').hide();
$('#content div.module div.module_contents a.module_hide').hide();
$('#content div.module div.module_contents a.module_show').show();
$visible_module.find('div.module_contents').show();
$visible_module.find('a.module_hide').show();
$visible_module.find('a.module_show').hide();
return false;
});
然后,为了实现模块中的show按钮,我会“欺骗”并按下侧栏中的相应按钮。
$('#content .module_show').click(function() {
$('#sidebar a[rel='+$(this).closest('div.module').attr('id')).click();
return false;
});
隐藏按钮易于实现:
$('#content .module_hide').click(function() {
$(this).closest('div.module').find('div.module_contents').hide();
return false;
});
最后一件事是实现'锁定'功能。为此,我只是在侧边栏的链接中添加一个类,告诉当前选项卡处于非活动状态,然后根据它修改模块:
<ul id="sidebar">
<li><a href="#" rel="tab_1">Open tab 1</a></li>
<li><a href="#" rel="tab_2" class="inactive">Open tab 2</a></li>
在jQuery中:
$('#sidebar a.inactive').each(function() {
var $target_module = $('#content div#'+$(this).attr('rel'));
// Remove the links alltogether
$target_module.find('.module_hide, .module_show').remove();
return false;
});
还必须修改侧边栏链接的点击事件:
$('#sidebar a').click(function() {
if($(this).hasClass('inactive')) return false;
...
涵盖了不包括cookie保存的所有基础。希望这能为您提供有关如何简化代码的一些建议。请注意,我没有测试任何这个,所以我不能保证它的工作原理。如果您不理解某些内容,请随时询问。
确保使用CSS样式设置应用程序的初始状态,例如隐藏模块中的所有“隐藏”链接和.module_contents,因为它们可能默认关闭。
答案 1 :(得分:1)
我建议从http://plugins.jquery.com/开始。
查看那里的插件示例。播放演示,文档并查看源代码。
答案 2 :(得分:0)
我认为Tatu发布了一个很棒的答案。但是我使用了一些脚本来更紧密地使用HTML。我发布了working demo for you here ...额外的“}})”在右边缘只出于某种原因出现在bin中(我不知道如何摆脱它)。
CSS
#sidebar-left {
float:left;
width: 200px;
height: 700px;
background: #444;
padding: 20px;
}
#main-content {
float:left;
width: 600px;
height: 700px;
background: #555;
padding: 20px;
}
.sidebar-menu-1 .selected a { color: #080; }
.sidebar-menu-1 .sidebar-menu-locked a { color: #d00; text-decoration: line-through; }
.dashboard-module h2 { cursor: pointer; }
.dashboard-module { border: #777 1px solid; padding: 5px 15px; margin-bottom: 5px; }
.dashboard-module-content {}
.limited h2 { text-decoration: line-through; }
.expand-collapse { display: none; }
.show_btn { background: #08c url(http://i46.tinypic.com/2vd3246.gif) 98% 4px no-repeat; }
.hide_btn { background: #080 url(http://i47.tinypic.com/iqadz5.gif) 98% 4px no-repeat; }
.limited_btn { background: #d00 url(http://i47.tinypic.com/209ghzp.gif) 98% 4px no-repeat; }
HTML(仅略微修改)
<!-- S I D E B A R - L E F T -->
<div id="sidebar-left">
<ul class="sidebar-menu-1">
<li><strong>List headline</strong></li>
<li><a href="#m1">Open module 1</a></li>
<li><a href="#m2">Open module 2</a></li>
<li><a href="#m3">Open module 3</a></li>
<li><a href="#m4">Open module 4</a></li>
</ul>
</div><!--/sidebar-left-->
<!-- M A I N - C O N T E N T -->
<div id="main-content">
<!-- dashboard-module -->
<div id="m1" class="dashboard-module">
<div class="dashboard-module-content">
<h2>Headline 1</h2>
<p class="teaser">Teaser-text 1</p>
<div class="expand-collapse">
[some content]
</div>
</div>
</div><!--/dashboard-module-->
<!-- dashboard-module -->
<div id="m2" class="dashboard-module">
<div class="dashboard-module-content">
<h2>Headline 2</h2>
<p class="teaser">Teaser-text 2</p>
<div class="expand-collapse">
[some content]
</div>
</div>
</div><!--/dashboard-module-->
<!-- dashboard-module -->
<div id="m3" class="dashboard-module">
<div class="dashboard-module-content">
<h2>Headline 3</h2>
<p class="teaser">Teaser-text 3</p>
<div class="expand-collapse">
[some content]
</div>
</div>
</div><!--/dashboard-module-->
<!-- dashboard-module -->
<div id="m4" class="dashboard-module">
<div class="dashboard-module-content limited">
<h2>Headline 4</h2>
<p class="teaser">Teaser-text 4</p>
<div class="expand-collapse">
[some content]
</div>
</div>
</div><!--/dashboard-module-->
</div><!--/main-content-->
脚本
$(document).ready(function(){
$('.dashboard-module').each(function(){
var mod = $(this);
mod.find('h2').addClass('show_btn');
// If the dashboard-module is "limited" do this:
if (mod.find('.dashboard-module-content').hasClass('limited')){
$('.sidebar-menu-1').find('a[href$=' + mod.attr('id') + ']').parent().removeClass('selected').addClass('sidebar-menu-locked');
mod.find('.expand-collapse').remove();
mod.find('p:hidden').show();
mod.find('h2').removeClass('show_btn hide_btn').addClass('limited_btn');
};
// Add click to Dashboard Modules
mod.find('h2').click(function(){
toggleContent(mod);
})
})
// Add click to Side Menu
$('.sidebar-menu-1 a').click(function(){
// The dashboard-module ID is contained in the sidebar-menu link href attribute
toggleContent( $( $(this).attr('href')) );
return false;
})
function toggleContent(mod){
// don't open limited content
if (mod.find('.dashboard-module-content').hasClass('limited')) return false;
// close open content
if (!mod.find('h2').hasClass('hide_btn')){
$('.hide_btn').removeClass('hide_btn').addClass('show_btn').parent().find('.expand-collapse').hide();
$('.sidebar-menu-1 .selected').removeClass('selected');
}
var btn = (mod.find('.expand-collapse').toggle().is(':hidden')) ? 'show_btn' : 'hide_btn';
mod.find('h2').removeClass('show_btn hide_btn').addClass(btn);
$('.sidebar-menu-1').find('a[href$=' + mod.attr('id') + ']').parent().toggleClass('selected');
}
})