使用 <select> 下拉菜单创建导航不像以前那么常见,但它仍然存在。它因其不可访问性/干扰性而受到不少批评。事实上,您在网上找到的许多用于创建此类菜单的脚本都是这样。太糟糕了。让我们创建一个既可以在有 JavaScript 的情况下工作,也可以在没有 JavaScript 的情况下工作的菜单!
干扰方式
<form>
<select onchange="window.open(this.options[this.selectedIndex].value)">
<option value="">Go to page...</option>
<option value="https://css-tricks.org.cn/">CSS-Tricks</option>
<option value="http://digwp.com/">Digging Into WordPress</option>
<option value="http://quotesondesign.com/">Quotes on Design</option>
</select>
</form>
内联 JavaScript……它有效,但仅在启用 JavaScript 时才有效。如果没有,您将拥有一个完全不起作用的下拉菜单。
不干扰方式
<form id="page-changer" action="" method="post">
<select name="nav">
<option value="">Go to page...</option>
<option value="https://css-tricks.org.cn/">CSS-Tricks</option>
<option value="http://digwp.com/">Digging Into WordPress</option>
<option value="http://quotesondesign.com/">Quotes on Design</option>
</select>
<input type="submit" value="Go" id="submit" />
</form>
非常相似,但没有内联 JavaScript。相反,我们给表单和 ID,稍后我们将使用它们作为目标。表单现在 POST 到自身,并且我们添加了一个提交按钮,因此表单是可用的。现在选择具有名称值,因此当按下提交按钮时,它将 POST 一个值。
在我们页面的最顶部,我们将检查该表单的 POST 值。如果存在,我们将把页面重定向到该值。
<?php
if (isset($_POST['nav'])) {
header("Location: $_POST[nav]");
}
?>
根本不需要 JavaScript,页面重定向完全通过服务器端 PHP 处理。**注意:**这只是简化的 PHP。您可能应该在将提交的值传递给 header 函数之前对其进行清理(尤其是在运行 PHP 4.4.2 或 5.1.2 之前的版本时),以防止“header 注入”攻击。
我们可以通过几行 jQuery 使其行为与干扰方法相同。
- 隐藏提交按钮。
- 当选择更改时……
- 重定向到选项的值
$(function() {
$("#submit").hide();
$("#page-changer select").change(function() {
window.location = $("#page-changer select option:selected").val();
})
});
更新
读者 David Vandenbroek 写道
我发现使用
<select onChange="window.open(this.options[this.selectedIndex].value)">
在 iOS Safari 将“阻止弹出窗口”设置设置为关闭时,会在 iPhone/iPad 上打开一个弹出警告对话框,如果允许,则会打开一个新窗口。当该设置设置为打开时,什么也不会发生。
为了避免这两种不良行为,我使用了
<select onChange="window.location.replace(this.options[this.selectedIndex].value)">
代替。
我太激动了,我已经搜索了一个小时,终于找到了这个!我对自己说:“我知道 CSS-TRICKS 会有,让我看看。”无需搜索。非常感谢您提供如此全面的网站。
还需要注意的是,不干扰的方式也不会强制打开新窗口。
或者这是另一个原因 :D
在 header 函数之前进行某种验证是否明智?或者我错过了什么?
这将是一种方法
很有趣。大多数时候我接到的项目是客户要求一些东西。我做的第一件事就是查看 css-tricks,并且每次我都感到惊讶,是的,有新的帖子,而且这正是我正在寻找的。就像这个人读懂了我的心思!
我可能不会发现这很有用,但它非常好 :P
还有一件事,曾经有一篇关于无 CSS 无图像解决方案的文章,但它似乎消失了。它在哪里?谢谢 :P
我喜欢新的设计 CSS 技巧!
干得好,Chris!..
Kiss (K)
很想看看如何设置这些样式
不错……不到一周前,我曾想过这样的功能会很好地添加到我在工作中的自定义起始页,只是没有花时间去查找它是如何实现的。您的时机再好不过了。
谢谢。
这很酷。在禁用 Javascript 时可以很好地回退。我同意 Kristoffer 的观点,在 url 进入 header() 之前应该对其进行验证/检查。
您还应该在 header() 之后放置一个 exit; 以防止 header() 调用下方代码的执行。
请参阅 PHP 手册页面以获取信息:http://nl.php.net/manual/en/function.header.php
我似乎从来不喜欢下拉导航菜单,但是鉴于适当的环境,我可能会考虑实现这样的东西。不错的帖子!
Chris,我必须承认,我真的不明白如何让不干扰的方式工作。一个新的播客可以提供帮助 :)
使用组合框进行页面选择是非常糟糕的用户界面设计。始终为此目的使用锚点,并考虑 PDA/移动用户。
缺点是这种导航根本无法访问。我所做的是像这样的 HTML
以及一个将 html 转换为选择框的 javascript。
这是因为我们的设计师喜欢使用选择框作为导航元素,在我看来这完全是错误的,因为它滥用了表单元素。
我更喜欢只使用 ul 并使用 suckerfish 或简洁的 javascript 效果将其样式设置为某种菜单。
如果您只有 3 个选项可供选择,这很好。
但是,我计划使用它来销售使用 Brown Paper Tickets 的音乐会/活动的票。而且,我们每月有 20 个活动。这在一个列表中变得有点笨拙。
这是一个很好的解决方案。
我的意思是,您可以通过 Javascript 将列表重写为选择框(这使没有 javascript 的用户和搜索引擎能够使用)或使用 css 将列表样式设置为选择框(通过将其设置为 position:absolute,高度设置为一行,并通过悬停使其展开(可选地通过 scriptaculous))。
因此,您可以兼得两全其美。
我同意 Dmitry 的观点。我很难理解使用表单元素提供导航的意义——在我看来,它没有语义并且可用性差。为什么不使用样式化的列表,如果您真的必须,可以使用一些 JS。
我通常不喜欢这些解决方案,但它非常适合小型网站的子菜单移动导航!
所以现在我必须用 PHP 重写所有页面,这样我才能拥有一个半不可访问的导航,搜索引擎会忽略它?
有什么优势?
是的。您必须立即重写所有内容。
嗯,不。如果您已经有了这样的下拉菜单,那么这是一种使它不那么干扰的方式。并且 PHP 不是必需的,您可以使用任何可以接受表单数据并进行重定向的服务器端技术。
James,如果表单内的链接会被搜索引擎忽略,那么数百万个网站就不会被索引。爬取 Dreamweaver 生成的页面比统治阿富汗更难。它几乎不包含我们所说的 HTML。这是一堆点击事件。我想说
如果有链接,Google 就会获取它。
很好的方法,谢谢分享 :)
您的博客太酷了!我正在寻找推广我博客的方法。这特别有用。请访问我的博客。
http://www.ishtihari.blogspot.com
Chris 干得漂亮。谢谢
这是对 POST 的误用;应该使用 GET 代替。
是啊..这哥们儿真的能读懂我们的心思…谢谢哥们儿…
由 Hendrik Walter 发送
这是一种将侵入式方法与 PHP 代码结合起来使其以相同方式工作的方法,只是不使用 jQuery
谢谢 Chris!
抱歉,Chris,我个人认为这是我在 CSS Tricks 上读过的最糟糕的文章。
您似乎正在通过示例认可一种非常糟糕的做法。
至少删除 onchange 行为并将该“go”按钮从 noscript 中取出。
这至少可以使大多数人可以使用它。
最好使用
location.assign(this.options[this.selectedIndex].value)
代替
window.location.replace(this.options[this.selectedIndex].value)
因为 location replace 不在浏览器历史记录中,并且它不允许后退按钮