这个想法是创建一个问答式页面,通过 JavaScript(jQuery)来增强其功能。每个问题都会显示在一个带有标签的方框中,标签悬挂在方框底部。点击标签时,标签会滑出,露出另一个包含答案的方框。

注意事项
这绝对不是一件难事,尤其是在 jQuery 的帮助下。但这个示例非常适合考虑我们即将执行操作的影响。我们的想法考虑了大多数访问网站的人,即使用支持 JavaScript 的标准浏览器的用户。但我们也需要考虑使用非标准浏览器(例如屏幕阅读器)的用户,或者在禁用 JavaScript 的情况下浏览网页的用户。
无 JavaScript
在我们功能齐全的示例中,答案被隐藏,直到点击答案标签才会显示。有很多方法可以实现这一点,但我们应该注意使用 JavaScript 进行隐藏操作,这样当 JavaScript 关闭时,答案就不会被隐藏。我们的“答案”下拉标签在禁用 JavaScript 时也会变得无关紧要,所以我们也要注意通过 JavaScript 应用它,使其只在可用时出现。
屏幕阅读器
我们已经确定将使用 JavaScript 来隐藏答案,所以不用担心答案隐藏的问题。我们现在唯一要担心的是我们的标记是否干净且语义化。换句话说,没有屏幕阅读器用户不需要看到的额外内容,以及“问题”和“答案”之间清晰的区分。
标记
然后我们从标记开始。我们将利用 定义列表,我认为它非常适合常见问题内容。
<dl class="faq">
<dt>How much wood would a wood chuck chuck if a wood chuck could chuck wood?</dt>
<dd class="answer"><div>1,000,000</div></dd>
</dl>
非常干净,但我们的语义评分有一个缺点:答案元素中的额外 div。这并非完全必要,但它有助于我们打算使用 jQuery 执行的动画的流畅性。简而言之,如果您使用类似 .slideToggle 的函数,如果该元素不使用任何填充,您的动画将更加平滑。我们通过这个额外的 div 来实现我们需要的填充。 此处有更多信息。
jQuery JavaScript
首先,我们加载库并链接到我们的外部 JavaScript 文件,以保持代码整洁。请注意,我们在这里从 Google 加载 jQuery,这是生产环境的推荐做法。更多关于 如何 和 为什么 的信息。
<script src="//www.google.com/jsapi"></script>
<script>
google.load("jquery", "1.2.6");
</script>
<script src="js/faq.js"></script>
然后我们编写实际的代码。
- 隐藏答案。
- 追加“答案”悬挂标签
- 将 slideToggle 功能应用于标签
$(function(){
$("dd.answer")
.hide();
$("dl.faq")
.append("<dd class='answer-tab-wrap'><a class='answer-tab'>Answer</a></dd>");
$(".answer-tab")
.click(function(){
$(this)
.parent()
.parent()
.find("dd.answer")
.slideToggle();
});
});
CSS
dl { clear: both; margin: 0 0 20px 0; }
dt { border: 8px solid #7ac0d0; padding: 10px; background: white;
position: relative; font-style: italic; }
dd.answer { background: white;
position: relative; width: 90%; margin: 0 auto; }
dd.answer div { padding: 10px; border-left: 8px solid #dedede;
border-right: 8px solid #dedede; border-bottom: 8px solid #dedede; }
dd.answer-tab-wrap { margin: 0 30px 0 0; }
.answer-tab { background: url(images/answer-tag.png); display: block; margin: 0 0 20px 0;
text-indent: -9999px; width: 105px; height: 50px; float: right; }
这里有一些有趣的地方。因为我们正在使答案标签浮动,所以我们将在定义列表本身清除浮动,以确保它们之间的间距正常。我们还在 .answer-tab 锚链接上使用 CSS 图片替换,以实现最高效率(图片只需加载一次)。
成功
在页面顶部,您可以看到 演示 的结果,具有功能。以下是其他场景
JavaScript 关闭
答案可见,样式仍然合理。
屏幕阅读器
以网页形式显示,禁用 CSS 和 JavaScript。
已在以下浏览器中测试并通过
Firefox 3、Safari 4、Internet Explorer 6 & 7、Opera 9
你一定是在开玩笑吧 - 我也正在写一篇完全一样的文章(“用 jQuery 美化常见问题页面”)。好吧,看来你抢先一步了。
无论如何,你的文章更好,我真的很喜欢这个实现。继续努力,Chris!
哦。抱歉,伙计,但你绝对应该还是发布它。网络上永远需要更多教程和教学内容。
没问题,老兄,你说得对,教给网络一些真正优秀的东西 - 就像你的文章 - 很好。我稍后会完成我的文章;我现在正在做一些其他的 CSS/JavaScript 东西 :) 。
想知道一些真正奇怪的事情吗?看看我在你发布文章在线之前几个小时的 Twitter 状态。
巧合吗?
太疯狂了。
来自 Monty Python,哈哈!
很棒的内容。
非侵入式 JavaScript 是每个人都应该牢记的原则。在某种程度上,它就像客户端功能的 CSS 布局(与表格相比)。更语义化,更利于 SEO/可访问性,一旦养成习惯,你就不想再回到旧方法了。
使用 JQuery 来增强用户体验而不破坏 JavaScript 禁用时的体验的绝佳示例。很棒的教程!
–Brenelz
喜欢你在本教程中使用的方法。你有一个清晰的流程,我很想实现它。我往往会从编码一个想法开始,然后一直绕圈子直到弄明白。
呃,第一个答案错了。
正确答案是“一只土拨鼠如果能扔木头,它会扔掉和它体重一样多的木头,但土拨鼠不能扔木头,因为土拨鼠是地鼠。”
该死,打错了。
-woodchuck-
嗨,克里斯,
很棒的帖子!我正准备为客户使用 jQuery 创建类似的东西。我相信你刚刚为我节省了好几个小时;我会用你的例子作为起点。谢谢,你真棒!
布莱恩
我是您在这里的订阅者,我目前在外部应用程序中查看我的订阅源(我还没有找到足够快的 Firefox 附加组件),我不得不来到这里并发表评论,至少要表达我对您投入写作和分享此类内容的时间的感谢。
您的动态常见问题页面很棒。
我已经开始对其进行自定义,它有很多可能性和潜在用途。
非常感谢。继续保持好东西。
现代屏幕阅读器(如 JAWS)可以渲染 JavaScript,那么它们是如何在没有鼠标的情况下获取答案的呢?您需要将问题设为链接,并将答案设为书签。
在启用 JavaScript 但禁用 CSS 的情况下,它看起来很像同时禁用的示例,但只是在答案下面有文本“答案”(可见)。我认为这是一种非常优雅的降级。
是否有任何解决方案可以将“答案”气泡显示为手形图标而不是箭头图标?我们的一些客户不太了解网页,他们会在网站上四处游荡,最终离开网站,因为他们不知道要开始点击...
好主意,我已经将其添加到实时示例中。只需要一个cursor: pointer;在.answer-tab在 CSS 中。
我之前看到了这一点,但什么也没说... 但它让我对 CSS 缓存提出了一些有趣的要求。如果我们进行更改,您作为一名对标题/缓存/PHP 知之甚少的前端开发人员,将如何确保用户获取最新的 CSS。
很多人犯了使用相同文件名导致样式看起来很糟糕的错误,因为他们忽略了这一点... 所以听取/了解您对此的看法将会很有趣!
我通常使用查询字符串参数来实现这一点。例如,如果我的 CSS 位于 styles.css 中,我会像这样引用它
<link rel=”stylesheet” href=”/path/to/css/styles.css?v=1.0″ />
然后,如果我推出更改,我会将**v**参数更改为 1.1 或 2.0。这将强制几乎所有我测试过的浏览器和代理缓存下载新文件。
谢谢!我可能只需要在某个地方使用它!
很棒的帖子——尤其是因为它使用了渐进增强;尽管在禁用 CSS 的情况下,答案都是可见的,直到您单击“答案”。
我知道这只需要一行代码,但在用户体验方面,将光标更改为手形会更有利,尤其是在您想要隐藏答案时。
非常好,但对于三个问题来说占用了太多空间。如果添加手风琴功能,以便您可以按主题标题区分问题,那就太好了。
克里斯,
感谢您(免费)提供的所有信息。css-tricks 是我每次打开浏览器时第一个查看的网站(是的,甚至在查看电子邮件之前)。我有一个问题。我正在开发一个小型电子商务网站,我想使用 jQuery 来丰富购物体验。我所做的是在一个 div 中打印出商品列表,并使用链接来点击将商品添加到购物车。我想使用 jQuery 将此列表分成多个页面并创建一个滑动面板之类的界面。我遇到的问题是,由于我最初使用 jQuery 来隐藏列表,因此列表会在 jQuery 隐藏它之前在屏幕上短暂闪烁。我不想使用 CSS 隐藏它,因为如果用户禁用了 JavaScript,将无法使其可见。您(或其他人)是否有任何提示给我?再次感谢您所有的知识。
您可以使用一些巨大的负上、左定位将它从页面中踢出,而不是使用 CSS 通过display: none;隐藏它,并使用position: absolute;。我认为这通常是那里使用的方法。然后只需使用 JS 删除该 CSS 即可。
我将无法删除该 css,因为 javascript 将被禁用... 我是否遗漏了什么?
我注意到,在使用您的演示时,答案块在使用 jquery 隐藏之前不可见,但在添加“答案”选项卡之前会短暂暂停。
我能说什么呢?我丈夫的名字,我可不是在开玩笑,是查克·伍德。哦,还有很棒的教程!谢谢!
这很酷。我可能会将它整合到我的一个项目中并稍作更改,如果我决定使用它,我会告诉您结果如何。
这很好,我肯定会为我未来的项目研究一下~
谢谢!
一只土拨鼠会像土拨鼠能扔的木头一样多地扔木头。
这很好,也很漂亮。但在可用性方面,问题本身应该是可点击的,以显示答案。
在设计方面(“设计”),“答案”按钮不是必需的。常见问题解答的标准和预期行为是“用户点击他们想要答案的问题”,而此实现打破了这种预期。
代码简洁干净。一两年前我做过类似的事情,当然,我没有集成 jQuery。不错的示例。
很好的教程,可以实现所需的效果,但我不会将其用于常见问题解答。当人们通常浏览常见问题解答以查找信息时,为什么要隐藏这些信息?
我还认为,创建一个名为“答案”的按钮可能会导致一些用户认为他们可以单击并自己回答问题。
很棒的文章,克里斯。我开始真正理解 JQuery,它给了我一些关于自己网站的想法。再次感谢。祝您 2009 年一切顺利。
是的,非常棒的教程。如果其他人也认为自己疯了,或者可能只是我;我最初尝试使用代码示例来弄清楚 jQuery,我花了很长时间才弄清楚“answer-tab”来自哪里!?下载演示后,我意识到这是附加带有锚标记的一部分。我现在放心了:) 谢谢克里斯。
不错的例子,克里斯。
还没有人提到过,但如果您(某人)担心额外 div 的语义问题——您不能也使用 jQuery 添加它吗?
我同意,通过 jquery 添加额外的标记对我来说似乎是完美的解决方案。
$$('dd.answer')
.wrapInner('<div></div>') // 添加 div 标签
.hide(); // 隐藏所有答案
几个月前我用 jQuery 写了一些类似的东西。我喜欢您的样式和简洁性。如果您想比较,可以看看我的...
常见问题解答插件
嗨,克里斯。演示会很有帮助。谢谢。
啊,尼尔,就在那里。我的意思是页面上的演示。我尝试使用大卫·沃尔什的 Mootools 手风琴和克里斯的演示来做同样的事情,但脚本发生了冲突。我会尝试使用您的脚本做同样的事情。
我真的很喜欢它的外观,但我有一个问题。
我是一个 jQuery 新手,但我对 answer-tab 类如何在标记中不存在且未附加的情况下被点击感到困惑。如果我完全误解了,那么我希望有人解释一下这里实际发生了什么!
(注意——我尝试使用上面的代码,结果在问题下方出现了一个静态的“答案”文本,单击时没有任何反应。如果我将 .answer-tab-wrap 更改为 .answer-tab,即附加 answer-tab 类使其实际上存在于标记中,那么事情就开始起作用了,但这看起来有点奇怪。请告诉我我哪里错了!)
我相信按照惯例,我也需要指出我是这个网站的长期粉丝,屏幕截图和帖子很棒,我总是很高兴看到新的帖子发布!感谢您的教育:)
不不不。
如果给你一个木头,他就可以chuck尽可能多的木头。
哦,你应该给MooTools,或者甚至Prototype一个机会。我从Prototype开始,一直犹豫着尝试MooTools,但我真的很高兴我做了。它非常愉快。JQuery只是获得了大量的炒作,因为John Resig推出了这个名字,而其他人在放松。
很棒的教程!由于我刚接触jquery,我想学习如何做一些类似于Firefox所做的事情。 http://www.mozilla.com/en-US/firefox/3.0.5/releasenotes/ 虽然它不完全是一个FAQ页面,但我认为它可以用于一个。
你好….
我用我的屏幕阅读器(Supernova/HAL 8.0)试了一下,它没有读出答案。它很好地读出了问题,并读出了“答案”,但我无法使用键盘点击实际的答案“按钮”。
所以..实际上,这对使用屏幕阅读器的盲人用户或必须依赖键盘访问的行动不便用户来说是不可访问的。
我应该让你知道。
谢谢,指出这一点。很抱歉在关于可访问性的文章中搞砸了这样的事情。
我相信我已经解决了这个问题。问题是这些答案标签本身是锚链接,但没有包含href属性。所以,它们无法通过键盘“选项卡”或以其他方式单独选择。
我已经修复了这个问题,所以选项卡到它并按回车键应该激活链接并显示答案。
对于确实与JavaScript一起使用的屏幕阅读器来说,情况就是这样。如果它是一个禁用JavaScript的屏幕阅读器,答案从一开始就不会被隐藏。
嗨,Chris,感谢你解决这个问题。我再次测试了它,屏幕阅读器能够正常读出页面。这类Javascript/AJAX解决方案的唯一问题是,盲人用户无法知道答案实际上是出现了。所以,假设我正在阅读页面,我点击了“答案”,答案出现在顶部。屏幕阅读器的阅读顺序是从上到下,所以为了找到答案,我会(逻辑上)按下TAB键向下移动,但是答案出现在上面......而盲人用户对此一无所知(因为答案是“静默”出现的),通常盲人用户不会在“答案”按钮的上方寻找答案。因此,最好让实际答案出现在“答案”按钮的下方,这样它对于屏幕阅读器来说就是逻辑上的阅读顺序,并且对于所有用户来说都是完全可访问的:)
Javascript/AJAX可以增强许多用户的可访问性,但对于盲人用户来说可能很棘手。你只需要确保脚本的“行为”对于屏幕阅读器来说是有意义的(因为软件相当愚蠢):)
我做了一个额外的更改,希望让事情变得稍微好一些。我在每个链接中添加了title属性,该属性应该读出“显示答案”,这应该更好地解释一下行为。
嗨,再次……抱歉成为一个令人讨厌的家伙
同样的问题。盲人用户不会知道答案在下面。“答案”这个名称非常清楚(你不需要添加“显示”)......只是用户不会知道它被放在了答案的上方(并期望它在“答案”按钮的下方),因为这是选项卡顺序。
此外,在链接标题方面......一些屏幕阅读器完全忽略它们(例如Supernova/HAL):(
好吧,更多更改=)
我做了一些布局更改和代码放置更改,希望这些更改能够解决问题。现在选项卡出现在左侧,并打开包含答案的抽屉,抽屉位于右侧。答案实际上是在“显示”链接的代码之后,所以希望这会更明显。
告诉我情况如何。
好的……
首先,感谢你的尝试:)
我再次用我的屏幕阅读器(和Internet Explorer 6.0)测试了它。布局严重混淆了(“答案按钮”散布在页面下方)。但是,从理论上讲,你的想法应该行得通,当禁用CSS时,它看起来应该是完美的,答案应该出现在下方。
当禁用CSS时......由于某种原因,屏幕阅读器会将句子和“答案”链接混淆,并且不会读出“答案”链接。屏幕阅读器会为“答案”链接读出“答案 - 混合链接”,通常在这种情况下,链接本身无法正常工作(无法点击它)。我不知道为什么。
可能值得“移动”链接,以便在禁用CSS时它出现在下一行,这样它就不会被读作一个句子?并且也查看一下IE 6.0中的布局:) 我还没有在IE 7.0中查看过。Firefox没问题,但它无法与屏幕阅读器配合使用(不用担心,它从来都不行)。
网络可访问性真是太糟糕了......!!!
好吧,下一轮准备好了=)
我明白你的意思,在关闭CSS的情况下,但那假设你关闭了CSS,而打开了JavaScript,这相当罕见,不是吗?无论如何,我认为我已经修复了它,所以它现在出现在下一行。
万岁!!!
这完美地工作......无论是对于屏幕阅读器还是行动不便的用户。
值得记住的是,当你禁用CSS时,那就是屏幕阅读器的“阅读顺序”。实际上,“屏幕阅读器”这个名称并不完全正确,因为软件也会从html代码中获取信息,而不仅仅是屏幕:)
欢迎你将来把东西发给我进行测试(我是一名网络可访问性顾问):)
干得好。
酷!
我认为这将成为本周屏幕截图的主题。