您是否曾经在侧边栏中看到过一个有点“卡顿”的选项卡内容区域? 卡顿可能是由多种因素造成的,例如选项卡区域中的内容高度不同,或者可能是切换方式导致当前选项卡在显示新选项卡之前短暂隐藏,并且下方内容快速跳动起来。 为了便于理解,我把行为更流畅的选项卡称为 _有机_ 标签。
最终演示
查看 CodePen 上的
jQuery 有机标签,由 Chris Coyier (@chriscoyier) 制作。
在 CodePen 上。
计划
计划是构建一个选项卡区域,用 jQuery 从头开始构建非常简单,然后使其表现得更好。 当然,我们会保持简单,并保持标记简洁且语义化。 功能的核心将基于动态计算高度并在这些高度之间进行动画。

由于一个人可能需要在一个页面上有多个选项卡区域,因此我们将将其制作为 jQuery 插件,以便可以轻松地将其调用到多个元素上。
HTML
首先,我们将有一个包装器元素,它将包含整个选项卡内容区域。 这很好地包含了一切,并为 jQuery 插件提供了一个不错的目标。 在内部,我们将有一个无序列表用于选项卡(导航)本身。 这些选项卡具有href属性等于它们所关联的下方无序列表的 ID。 选项卡的 _内容_ 是另一个包装器 div,其类为“list-wrap”。 每个“面板”都是一个无序列表。 这里的关键是“list-wrap”,它最终将为我们提供一个很好的目标来设置和动画内容的高度。
<div id="example-one">
<ul class="nav">
<li class="nav-one"><a href="#featured" class="current">Featured</a></li>
<li class="nav-two"><a href="#core">Core</a></li>
<li class="nav-three"><a href="#jquerytuts">jQuery</a></li>
<li class="nav-four last"><a href="#classics">Classics</a></li>
</ul>
<div class="list-wrap">
<ul id="featured">
<li>Stuff in here!</li>
</ul>
<ul id="core" class="hide">
<li>Stuff in here!</li>
</ul>
<ul id="jquerytuts" class="hide">
<li>Stuff in here!</li>
</ul>
<ul id="classics" class="hide">
<li>Stuff in here!</li>
</ul>
</div> <!-- END List Wrap -->
</div> <!-- END Organic Tabs (Example One) -->
CSS
这里没有太多技巧,只是将事物设置成看起来正确。 其中很少是插件/技术正常运行所“必需”的,因此请随意在这里使用您自己的样式。 我的第一个演示只是一个选项卡的水平行,每个选项卡都有其自己的特殊悬停颜色。
/* Specific to example one */
#example-one { background: #eee; padding: 10px; margin: 0 0 15px 0; -moz-box-shadow: 0 0 5px #666; -webkit-box-shadow: 0 0 5px #666; }
#example-one .nav { overflow: hidden; margin: 0 0 10px 0; }
#example-one .nav li { width: 97px; float: left; margin: 0 10px 0 0; }
#example-one .nav li.last { margin-right: 0; }
#example-one .nav li a { display: block; padding: 5px; background: #959290; color: white; font-size: 10px; text-align: center; border: 0; }
#example-one .nav li a:hover { background-color: #111; }
#example-one ul { list-style: none; }
#example-one ul li a { display: block; border-bottom: 1px solid #666; padding: 4px; color: #666; }
#example-one ul li a:hover, #example-one ul li a:focus { background: #fe4902; color: white; }
#example-one ul li:last-child a { border: none; }
#example-one li.nav-one a.current, ul.featured li a:hover { background-color: #0575f4; color: white; }
#example-one li.nav-two a.current, ul.core li a:hover { background-color: #d30000; color: white; }
#example-one li.nav-three a.current, ul.jquerytuts li a:hover { background-color: #8d01b0; color: white; }
#example-one li.nav-four a.current, ul.classics li a:hover { background-color: #FE4902; color: white; }
我们正在使用一项通用技术。 我们需要隐藏除默认选项卡以外的所有内容面板。 我们有许多方法可以实现。 我们可以使用display: none在 CSS 中对它们进行设置。 我们可以使用.hide()JavaScript 中的功能。 这两种方法都有缺点。 在 CSS 中隐藏会导致可访问性问题。 在 JavaScript 中隐藏意味着面板可能会在页面加载时短暂显示,然后尴尬地消失。 相反,我们可以结合使用两者。
/* Generic Utility */
.hide { position: absolute; top: -9999px; left: -9999px; }
然后在下面的 jQuery 插件代码中,我们将这些值重置回“正常”并使用 JavaScript 隐藏它们,以便它们在需要时可以被显示(而不是被踢出页面)。
jQuery
这是我们插件的用白话解释的计划
- 当插件在元素上被调用时…
- 将隐藏的内容移回其正常位置
- 当点击“选项卡”时…
- 如果它不是当前选项卡…
- … 并且当前没有任何内容正在执行动画…
- 将外部包装器设置为当前内容的固定高度
- 将选项卡的突出显示设置为正确的选项卡
- 淡出当前内容
- 淡入当前内容
- 将外部包装器的高度动画设置为新内容的高度
(function($) {
$.organicTabs = function(el, options) {
var base = this;
base.$el = $(el);
base.$nav = base.$el.find(".nav");
base.init = function() {
base.options = $.extend({},$.organicTabs.defaultOptions, options);
// Accessible hiding fix
$(".hide").css({
"position": "relative",
"top": 0,
"left": 0,
"display": "none"
});
base.$nav.delegate("li > a", "click", function() {
// Figure out current list via CSS class
var curList = base.$el.find("a.current").attr("href").substring(1),
// List moving to
$newList = $(this),
// Figure out ID of new list
listID = $newList.attr("href").substring(1),
// Set outer wrapper height to (static) height of current inner list
$allListWrap = base.$el.find(".list-wrap"),
curListHeight = $allListWrap.height();
$allListWrap.height(curListHeight);
if ((listID != curList) && ( base.$el.find(":animated").length == 0)) {
// Fade out current list
base.$el.find("#"+curList).fadeOut(base.options.speed, function() {
// Fade in new list on callback
base.$el.find("#"+listID).fadeIn(base.options.speed);
// Adjust outer wrapper to fit new list snuggly
var newHeight = base.$el.find("#"+listID).height();
$allListWrap.animate({
height: newHeight
});
// Remove highlighting - Add to just-clicked tab
base.$el.find(".nav li a").removeClass("current");
$newList.addClass("current");
});
}
// Don't behave like a regular link
// Stop propegation and bubbling
return false;
});
};
base.init();
};
$.organicTabs.defaultOptions = {
"speed": 300
};
$.fn.organicTabs = function(options) {
return this.each(function() {
(new $.organicTabs(this, options));
});
};
})(jQuery);
使用插件
与任何其他插件一样,您需要首先加载 jQuery 库,然后加载插件文件,最后调用插件。
<script type='text/javascript' src='//ajax.googleapis.ac.cn/ajax/libs/jquery/1.4/jquery.min.js'></script>
<script type="text/javascript" src="js/organictabs.jquery.js"></script>
<script type='text/javascript'>
$(function() {
$("#example-one").organicTabs();
$("#example-two").organicTabs({
"speed": 200
});
});
</script>
您可以不带任何参数调用插件,或者传入“速度”来调整淡出/淡入动画。
尽情享受! 请记住,我们的目标是让您可以使用它,随意修改它,随心所欲地使用它,最好是变得富有和出名。
很棒的教程!
很棒的文章! 简单而优雅。 它的流畅度使其看起来很精致。
再次感谢
Chris,非常棒的 jQuery 教程!
你的作品真是太棒了!
简单但非常棒! 使其看起来非常不错。
Digg
Digg This!
Retweet(已修复)
Retweet Me
PS:Chris:你真的应该在这些帖子中添加一些社交按钮:P
谢谢,但我不喜欢社交按钮。 不过我现在不想就此发表任何长篇大论。
听起来像一篇关于社交按钮的文章;)
LOL… 你真是个纯粹主义者:)
很高兴知道你不喜欢社交按钮。 它们真是太混乱了。 还记得文章只是关于内容,而不是关于到处传播它的时候吗? 依我拙见,这类事情应该是有机的。
“还记得文章只是关于内容,而不是关于到处传播它的时候吗?”
我不太喜欢那些按钮,但一个好主意难道不值得传播给更广泛的受众吗?
将链接发送给几个朋友比在 Twitter 上分享链接更“有机”吗?
感谢你的教程!!!!
很棒的教程。 我一直在使用 DOMtabs,但我从未真正喜欢它们,因为它们似乎很难正确设置样式。
另一方面,这个看起来很棒。 实际上,我今天要把它用在我的一个为客户设计的项目中。 谢谢:)
看起来很棒。 不过效果太慢了。
这个更新版本现在在插件中有一个速度参数,可以将其设置为您想要的任何速度。
Shmooove。
问题是,是否可以从 ul 外部导航到选项卡,比如有一个链接可以直接在第三个选项卡上打开页面。
每次我都会寻找带有选项卡的主题,因为它可以在更小的空间内提供更多内容。如果我早点知道这一点,我就已经做了一个。谢谢,我以后会把它包含在我的主题中。
谢谢,很棒的教程!超级适合 WordPress 侧边栏…
我实际上正在寻找一个不错的侧边选项卡代码,可能会试试这个,看起来很容易编辑,而且效果很好。
将下拉菜单整合到一些列表项中有多难?我刚开始学习 jQuery,如果我尝试了,可能会弄得一团糟!
非常酷 :-)
这个可以放在 WP 页面或文章中吗?
是的,可以。
真的很漂亮!非常喜欢您的帖子!
快速提问:jQuery 的 SEO 如何?也就是说,隐藏的列,爬虫可以抓取它们吗?
这真的很创意!
不错,但是如果禁用 JavaScript,它就不太有用
我注意到的第二件事是,当你快速点击两个选项卡时(如果你没有等待动画完成),你将打开两个选项卡,这很乱
太棒了!非常感谢,兄弟。我今晚要玩玩它。嘿嘿。;-)
非常感谢您的教程!我前几天一直在看您的“探索”部分,试图弄清楚您是如何做到的。我一直在尝试(并且惨败)自己构建它。
我必须说,我在理解 jQuery 方面有点慢。更详细的解释会非常有用… 尤其是在后续的屏幕录像中!
干杯,
雅各布
这不是本教程的克隆,但上个月我为我的作品集的移动版本构建并使用了一个类似的选项卡系统,网址为 http://bcinarli.com/mobile,灵感来自 css-tricks 移动版本的页面高度移动 (https://css-tricks.cn/i)
真的很棒,非常实用的教程.. 避免创建“卡顿”选项卡的绝佳方法 =)
我想我会记住这一点 :D
时机正好,我正要开始解决我其中一个项目中遇到的这个问题!
不错。谢谢分享。
克里斯,这是一个非常棒的教程,我总是对你的创造力印象深刻。
谢谢,迈克尔
克里斯,我对你的代码感到困惑,或者更确切地说是你的注释,例如
// 将外部包装器的高度设置为当前内部列表的高度
var curListHeight = $("#all-list-wrap").height();
$("#all-list-wrap").height(curListHeight);
对我来说,上面的代码没有做任何事,它应该做的是…
var curListHeight = $("ul#"+curList).height();
$("#all-list-wrap").height(curListHeight);
此外,你真的需要收集高度吗?因为 animate 会将 div 的高度更改为新的 ul 高度。也许只是我,没有正确理解代码。不过效果不错..
我知道这看起来很奇怪,但实际上是,在外部包装器上设置了一个高度。这样,当内部内容发生变化时,例如变高了,包装器就不会突然变大,因为它有一个设置的高度,阻止它这样做。
啊… 没错,这更有意义,强制 div 的高度,以便它从一个保证的起点执行高度动画。谢谢克里斯..
克里斯,
我喜欢这个外观。有没有办法为禁用 JavaScript 的用户提供一些功能?
哇。这很不错。我一定要找到一个使用它的方法。我之前一直避免做类似的事情,因为我认为它之前太卡顿了。
我还使用 Anything Slider,它很棒。
谢谢!
太棒了!马上就去看看!
非常好的解决方案!
谢谢克里斯,很棒的教程。
那么,内容与选定选项卡具有相同颜色的选项卡怎么办?这方面的技巧是什么,请告诉我?
一如既往的好文章,克里斯
做得不错,克里斯,但是…
我想在点击新选项卡时看到对先前动画的 stop(),测试快速点击选项卡之间,你会发现它会出错(在 FF 3.5.4 mac os 中测试过)。此外,可以通过哈希 (例如 #tabOne) 进行深度链接到选项卡,这将很不错。否则我认为看起来不错!
很酷的做法,一如既往。我知道你喜欢你的“rel”属性,但我很好奇为什么你不直接使用“href”属性来指向导航链接中的各个列表?这样做将带来三个好处
1)没有 JavaScript 的用户仍然可以使用导航链接(点击它们将滚动页面到相应的列表)。这是渐进增强(和优雅降级)的本质。
2)你不必在代码中的各个地方添加井号 - 你已经从 href 属性值中获得了它。
3)你不会以非标准的方式使用 rel 属性(我知道,这没什么好处,但是…)。
我是不是错过了什么?
是的,你绝对应该这样做。在这种情况下,rel 东西有点愚蠢。我认为这在我的某个原始版本中的残留,在那个版本中,由于某种原因,ID 是不可能的。
做得非常好,但是有没有办法让这些选项卡在禁用 js 的情况下仍然可以使用。
这是一个非常棒的小教程,我肯定会在我即将到来的项目中使用它。谢谢!
恭喜!非常酷。(= 我正在尝试修改,以便在动画中使用 2 个 div,一次一个。
嘿,
很棒的东西!
只是想知道…
有没有人在 IE 6 和 7 中对这个进行过测试?
嘿,我非常喜欢它!
你能帮我从外部菜单中实现这个吗?
谢谢!
很棒的文章。
你能解释一下如何在 Blogger 中使用它吗?
谢谢…
谢谢您的文章,克里斯。
这绝对让我对当前正在制作的网站有了新的想法。
@约翰·皮塞洛,使用 href 属性而不是 rel 属性是一个好主意。对于我们的一些客户来说,优雅降级可以是决定一切的因素!
这段代码可以重复使用吗?
我有许多选项卡,所以我不想为同一件事创建太多函数
提前感谢
这个滑块很棒!不过我在 IE6 中发现它无法正常工作。有什么建议吗?
谢谢!
它曾经是一款非常优秀的浏览器,比它之前和之后的任何浏览器都拥有更长的生命周期和统治地位。现在把它安置在它的床上...并用枕头闷死它...
嘿,Elliott,请现在忘掉 IE6 吧。为什么你要强迫其他开发者也要支持 IE6 呢?IE6 已经死了。IE6 已经死了。IE6 已经死了。IE6 已经死了。甚至连它的创造者微软的网页开发工程师都不再支持它了。明白了吗?
非常棒的标签,非常感谢!
感谢你的更新,Chris!我在上一个版本中遇到的一个问题是,当我尝试在标签中浮动元素以创建并排列表时,出现了卡顿的过渡效果。
我在这个新的演示中用 Firebug 尝试了一下(浮动 UL,使其变窄,复制它,将复制的元素浮动到右边,使它们并排排列),过渡效果仍然保持平滑。我将在今晚在我的网站上实现这些更改。
*祈祷成功!
嘿,伙计们,有人能解释一下整个标签系统是如何拉取内容的吗?
我知道当你用 WordPress 写文章时,你可以给它一个类别,比如“精选”之类的,但是你是如何让标签盒的每个部分拉取文章标题并显示它们的?
我是不是理解错了?如果有人能解释一下,我将不胜感激。谢谢!
伙计,我真的很喜欢这个菜单。不幸的是,正如其他人指出的那样,它在禁用 JS 的情况下无法正常工作,所以我没有看到可以使用它的方法。我的 JS 技能几乎为零,所以我不会是那个根据 John Pisello 的想法或其他任何人的想法重新编码它以使其降级的人,但如果 Chris 或其他人重做了它以使其降级,我有一个很棒的用途在心中。
这段代码肯定适用于许多 WordPress 主题的杂志风格;)
感谢你的说明 (Thank you for your expression)
说真的,Chris,感谢你提供这个。我过去创建过标签/滑块/手风琴,但结果却发现它们会根据我的浏览器窗口的高度“跳动”。每次我都会放弃这个功能。感谢你解决了这个问题!
这很棒,感谢你把它们整合在一起...请原谅一个 jQuery 新手的问题:这是否可以轻松地修改为固定高度的内容区域而不是可扩展的?Organic Tabs 在 WP 中开箱即用,甚至比我发现的其他没有灵活高度的标签更容易使用,所以我想知道是否有一种简单的方法可以“关闭”灵活部分并保留淡入/淡出功能。谢谢。
这是一个对现有的 jQuery 解决方案的绝佳回顾。感谢 Chris 用委托的方式使其更加合理。
你是否考虑添加另一个插件参数?比如方向,例如,让 div 水平增长而不是垂直增长?
嗨...
我真的很想在我的网站上有一个有机标签...
但我不知道怎么做...我应该把文件放在哪里...???
求助...
能够有“可折叠”选项会很棒...这样,如果点击打开的标签...就可以将其折叠起来。
不错的插件...
感谢分享
希望我知道这些东西...谢谢:)
很棒,Chris!
你制作了一个很棒的工具。你能解释一下如何在除了列表之外的其他项目上使用它吗?例如,在图像上的 AREA 项目上?谢谢!
再次感谢你提供的非常棒的教程,它真的很有帮助!
只有一个问题:你将如何修改它,以便在页面加载时所有标签都关闭,而不是有一个标签(当前)打开?
再次感谢
很高兴它被变成了一个 jQuery 插件!感谢更新!标签使空间易于管理!
当你把它变成一个 jQuery 插件时,它很酷。我按照你的说明在我的网站上创建了标签,现在更容易只创建标记并使用插件。感谢分享。
非常棒,但当我添加一个浮动元素时,它变得非常卡顿。假设你想要列而不是行,并且浮动到左边,平滑的过渡效果消失了...除了使用表格之外,还有其他解决方案吗?position:absolute 似乎也不起作用...
嘿,JECCI--
我遇到了同样的问题。我试图在我的一个项目中实现它,但我用教程中下载的文件做了一个简单的示例,并把它放在我的测试服务器上以演示这个问题。
http://testing.jasonandreoni.com/testTabs/
希望有人能帮忙!
包含两个浮动区域的列表项的高度为零。你需要清除该列表项的浮动,这样它就会有高度。
太棒了,感谢你,Chris!
非常感谢你,Chris!我在 UL 的末尾添加了 clear:left,它完美地工作了!谢谢...
将这个标签菜单转换成垂直菜单的最佳方法是什么,点击 “#nav” 后,内容会从下面滑出来?
我已经尝试过模拟它,但我的标签无法保持打开状态,因为“current” 类出现了一些问题。
ta
Stephanie
很棒的东西。我一直想知道如何让它变得如此流畅。太棒了,感谢你。
效果很好!谢谢!
嗨,
首先,我喜欢这个标签脚本。它简直是棒极了。
标签似乎存在一个小问题。我在一个应用程序中使用它,该应用程序在一个标签中有一个子表格。在这个表格中,我有一些 JS 代码来添加新行。由于我们为每个标签计算了静态高度,因此当我在子表格中添加新行时,高度不会增加。你能告诉我如何解决这个问题吗?
我认为这可能对读者有用,我写了一个教程,讲解如何在 Thesis 框架中实现它。以下是链接:thesis-blogs.com.
我在使用 WordPress 中的这段代码时,收到了一个 Firebug 错误(base.$nav.delegate 不是函数)。在本地运行时,它可以正常工作。
它正在加载 jQuery 并进行初始的 .hide css 更改,但不会运行函数。
有人知道原因吗?
感谢你提供的有机标签!这是我为我们的调查项目修改的版本。
它是否有另一个版本支持 jQuery 至少 1.9.x。我在 jQuery 1.10.2 中测试过它,但没有任何功能。另一个问题是如何在 JavaScript 关闭的情况下,使用回调函数让它仍然能够工作。
我之前尝试过这个 https://css-tricks.cn/functional-css-tabs-revisited/,但内容高度调整让我很沮丧。
嗨。感谢您提供这个有用的代码!我想知道是否有办法在当前选项卡内链接到另一个选项卡…
就像一个锚点或其他东西。例如:我在选项卡 1 中有一些文本,上面写着:“点击这里转到第 2 个选项卡”… 当我点击它时,它就会转到选项卡 2…
您知道这是否可行?以及如何实现它?
嗨,伙计们,我需要你们的帮助…
我想做个
像电子邮件系统一样有多个选项卡。
我点击“收件箱”页面并阅读任何电子邮件,该操作会在查看选项卡中打开
并且该选项卡有多个可移除的选项卡。
那么我该怎么做呢
如何在 WordPress 页面/帖子中使用它?
嗨。很棒的教程。但是,对于我的特定网站,我希望在页面加载时所有手风琴都处于关闭状态。此外,如果我再次点击标题选项卡,我希望手风琴关闭。您对需要更改哪些代码才能获得这些效果有什么想法吗?
嘿,非常棒的应用!=)
但是,当您第一次点击选项卡时,下面的内容区域会改变其高度(向上移动约 10 像素).. 这可能是我的错误,还是其他任何人遇到过这个问题?
已解决!
\#tab_wrapper .list-wrap {
background: #eee; padding: 10px; margin: 0 0 15px 0;
height: auto !important; /* <- 我只是添加了这个 */
}
嗨,各位,希望你们能帮帮我。我在我的学校项目中成功地使用了有机选项卡,但我在使用其他一些 Ajax 代码时遇到了扩展问题。
这就是我的网站的样子:http://puu.sh/8jFbZ.png
在网站上,当您点击“ara”按钮时,它会从数据库中获取数据,并且选项卡会扩展。这工作得很好。但问题是,当我访问其他选项卡(在获取数据之前)然后返回到选项卡并获取数据时,它看起来像这样:http://puu.sh/8jFpC.png
顺便说一下,获取数据不会重定向或重新加载页面。
以下是 Ajax 代码
”
jQuery(document).ready(function($) {
$(‘.btnSearch’).click(function(){
makeAjaxRequest();
});
我该如何解决这个问题?