不显眼的下拉菜单页面切换器

Avatar of Chris Coyier
Chris Coyier 发布

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200美元免费额度!

使用 <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 使其行为与干扰方法相同。

  1. 隐藏提交按钮。
  2. 当选择更改时……
  3. 重定向到选项的值
$(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)"> 

代替。