吸鱼下拉菜单

编辑的注释:尽管这篇文章在当时具有创新性,但它不再代表现代最佳实践。

众所周知,“DHTML”下拉菜单包含大量讨厌的JavaScript,其中包含大量浏览器特定的黑客攻击,使得任何其他整洁的语义HTML都无法访问。哦,这是一个轻量级、易访问、符合标准、兼容交叉浏览器的方法的梦想!输入吸管鱼下拉列表。

文章续下

符合标记#第2部分

首先,我们应该使用定义导航菜单的最佳方法-列表。对于这个例子,我们将处理一个简单的HTML无序列表。{换行已标记».  –预计起飞时间。}

<ul><li>太阳鱼<ul><li>黑带»太阳鱼</a></li><li>阴影低音</a></li><li>奥扎克低音</a></li><li>白色克拉皮</a></li></ul></li><li>格伦茨<ul><li>小嘴咕噜声</a></li><li>Burrito公司</a></li><li>猪鱼</a></li></ul>雷莫拉斯<ul><li>捕鲸人</a></li><li>马林斯克</a></li><li>锡兰语remora</a></li><li><a href=“”>长矛鱼</a></li><li>细长吸管鱼</a></li></ul></li></ul>

非常简单,非常简洁的HTML,因此非常容易访问。但现在我们想将其转换为动态列表-第一级列表项将组成一个水平菜单栏,第二级列表将从中下拉。

设计风格#第3部分

开始时,所有列表都需要稍微调整一下,即填充和边距设置为零,列表样式设置为无:

ul公司{填充:0;边距:0;列表样式:无;}

现在,我们需要将一级列表转换为水平菜单栏。有许多方法可以做到这一点,并进行了详细讨论在别处。我们可以内联显示列表项(显示:内联),但对于这个示例,我们要将它们向左浮动。

李{浮动:左;位置:相对;宽度:10em;}

位置已设置为相对的因为我们希望第二级嵌套列表的位置相对于第一级列表项,并且宽度已设置为将其分隔开一点。下拉菜单正在合并。

下一步是处理二级列表,这些列表本身就是下拉列表:

锂ul{显示:无;位置:绝对;顶部:1em;左:0;}

这绝对地定位了第二级列表(将它们从HTML流中拉出来,进入一个完全属于它们自己的世界),并将它们的初始状态设置为不显示。如果您替换显示:无具有显示:块,您将在Internet Explorer中看到对顶部和左侧属性的需要,因为如果没有它们,IE将把二级列表对齐到其相对父级的右上角,而不是左下角。不幸的是,此IE修复程序会在Opera等浏览器中造成混乱,因此添加以下CSS以重置除IE浏览器以外的所有浏览器的顶部和左侧属性:

li>ul{顶部:自动;左:自动;}

现在,让吸盘工作。为了在其父列表项“滚动”时显示二级列表,我们只需添加以下内容:

li:悬停ul{display:block;}

这意味着应该显示嵌套在列表项中且光标悬停在其上的任何列表。

最后,由于列表是向左浮动的,因此需要通过应用清除:左侧到它。

等一下!#第4节

我听到102.6%的人(或最新比例的人)哭了:“这句废话没用!”。正如一些人可能已经猜到的那样,我正在谈论Internet Explorer用户。您使用和开发的浏览器(如Mozilla)越多,就越能意识到Internet Explorer在web标准方面是多么可怜。这个:悬停pseudo类应该可以处理任何元素,但在InternetExplorer中它只能处理链接。那么,当下拉菜单只适用于-2.6%的浏览器时,它有什么用?说实话,没什么。我们需要运用更多的魔法。

基于DOM的救援脚本#第5节

我们已经确定IE缺乏对:悬停伪类,但通过使用文档对象模型,我们可以将mouseover和mouseout事件附加到任何元素。这对我们来说是个好消息,因为这意味着通过简单的JavaScript片段,我们可以有效地修补IE的:悬停问题。

因为IE是盲目的,我们需要找到另一种方法来识别:悬停伪类。使用JavaScript,我们知道可以操作元素的className属性,因此我们首先要做的是更改CSS:

li:悬停ul{display:block;}

变为:

li:将ul悬停,li悬停在ul上{显示:块;}

现在我们可以调用:悬停通过添加类的CSS规则结束至所需元素。我们还需要一种方法来告诉IE页面上的哪些UL元素是我们真正想要的下拉菜单。我们可以通过提供身份证件到我们的根美国元素:

    变为:

    现在我们有了识别根的方法美国元素,我们可以获取此元素并循环遍历其所有子元素,将mouseover和mouseout事件附加到所有元素嵌套在其中。这是如何完成的:

    startList=函数(){if(document.all&&document;.getElementById){navRoot=文档.getElementById(“nav”);对于(i=0;iif(node.nodeName==“LI”){node.onmouseover=函数(){this.className+=“超过”;}node.onmouseout=函数(){this.className=this.classesName.replace(“over”,“”);}}}}}window.onload=startList;

    页面加载时startList(启动列表)函数被调用。该函数通过检查是否存在文档.all对象和文档.getElementById功能。这是一种粗略的方法,但它很简短,而且很甜蜜,因为我们正在尝试制定一个紧凑的解决方案,这就行了。然后它循环通过,启用mouseover和mouseout事件,从而添加和删除结束来自的类类名元素的属性。

    给你。如果你在任何地方迷路了,看看评论,光网络示例正在运行。

    鳃、鳍、鳞片…#第6节

    到目前为止,情况有点不妙。这个想法是为了显示吸管鱼下拉菜单的基本工作方式,但CSS可以让事情看起来漂亮多了一个明显的起点是为二级列表应用背景色。

    按说明重置顶部和左侧属性后早期的,中的下拉列表漂亮的在大多数现代浏览器中,示例直接出现在菜单标签的下方,但不幸的是,并不是全部。在Safari 1.0中,它们仍然从屏幕左上角向下下拉。{检查讨论论坛解决方法。–预计起飞时间。}

    进一步的可用性和可访问性#第7节

    从第一级列表项中创建链接将允许不使用指针设备的读者使用tab-stoping。将这些链接指向比下拉列表中的链接更高级别的页面会更好。

    关于作者

    丹·韦伯

    丹·韦伯是一名网络开发人员和想要成为DJ的人。他最近的工作包括为英国政府机构实现基于标准的、可访问的网站和网络应用程序,并让人们在昏暗的伦敦酒吧里跳舞。

    帕特里克·格里菲斯

    帕特里克·格里菲斯(Patrick Griffiths)是一位总部位于伦敦的自由网络制作人,他对灵魂有着浓厚的兴趣音乐、进化和漫步他的宠物网站,HTML狗.他有时更喜欢这个名字PTG公司取决于他的心情。

    128读者评论

    1. 好的。我昨晚偶然发现了这一页,我更高兴了。我一直在寻找一种“简单”的方法来实现这个脚本的功能。

      但是,为了让NS7.1、IE6、Opera7.23满意,我正在努力。我正在重新布局我的网站,至少需要正确处理top2.htm文件,这样我就可以全面地包含它。这可能是明智的,但这是一项正在进行的工作。

      有人能告诉我为什么我的菜单以NS为中心,而不是Opera或IE吗?我认为这是一个保证金问题…

      这是一头不断成长的BSS野兽。。

      http://wanderingproductions.com/images/main.css

      这是页面:

      http://wanderingproductions.com/top2.htm

      如你所见,这张照片是居中的。其余的则不是(NS7以外)。我……很困惑。

      谢谢各位
      结核

    2. 当我在DHTML菜单上工作时,发现了这个CSS下拉菜单并爱上了它。但我想知道一些事情(关于图形界面):

      1.如何为第一个列表实现css滚动,为第二个列表实现不同的滚动。(我有一个在Mozilla Firebird中工作得很好,但在IE6和Opera 7中不工作)。

      2.是否可以使用此CSS下拉菜单制作类似网址:http://www.mediatemple.net/导航?

      提前谢谢。

    3. 诺埃米,谢谢你对Z指数的提示!我以为可以做到,只是不记得它的名字。🙂

      现在,我的下一个困惑是:这些菜单/链接/div的宽度可以超过3个吗?我注意到使用这个的例子只有三个。这是因为div/LI是左浮动、无浮动和右浮动吗?我可以先使用一个表,然后将每个div/LI放在td中,而不使用float来创建更多的菜单吗?

      …像那样吗?

    4. 我想知道是否有人尝试过像对javascript滚动一样预先缓存下拉菜单的背景图像。

      显然,IE并没有缓存图像。有趣的是,将“检查缓存页面的新版本”设置更改为“每次访问页面”之外的任何设置都可以纠正这种情况。

      Javascript滚动从来都不是必需的,在这种情况下,您可以更改图像的源代码,一旦图像被下载,它就会保留下来。

    5. 让我对这个非常有效的清洁解决方案表示祝贺。

      有了UL/LI下拉菜单,有没有一种方法可以对内容进行结构化,以便这些菜单下面文本中的无序列表可以以其默认(或类似默认)格式显示?

    6. 我尝试了两种不同的方法。也许你会比我幸运。

      首先是给菜单中使用的所有列表指定一个类(或id),考虑到站点中其他位置的列表不会以这种方式继承菜单的样式。但我没有找到一种方法来保持菜单正常工作。

      其次是创建一个定义了基本元素的标准列表类,以便站点上的其他列表可以使用该类,并且看起来与定义的一样。这一个对我不起作用,因为我的列表来自一个内容可编辑的区域,所以用户不知道如何添加样式。

      也许这些会给你一些想法。祝你好运。

    7. 一位同事在这个网站上看到了这个脚本
      之前,我把它发给了我,这样我就可以尝试将其转换为垂直导航,但它还是有错误!因为它在IE6中无法正常工作,但在我尝试过的所有其他浏览器中都能正常工作(任何人都能帮上忙吗!



      测试CSS垂直导航



    8. 你好,

      我一直在四处游玩,试图找到某种方法使第二层水平显示,我得出的结论是,至少我不能不使用Suckerfish和我的CSS知识…有什么想法吗?问题是父lis的宽度必须足够宽,以容纳所有子lis,但也必须足够窄,以成为一个选项卡。也许我可以将每个选项卡滑过去,使它们重叠,但它需要知道它是哪个选项卡。

      谢谢,

      威尔·汤普森

    9. 非常感谢这篇精彩的教程!这是一个圣杯,这是肯定的。

      我正在使用菜单系统进行设计,我遇到了一些需要注意的问题,其他人也希望使用该系统。

      如果您的菜单下拉到任何相对定位的元素上,则无论您为菜单提供了什么z索引,下拉菜单都会消失在IE/6 Win中相对定位元素的后面。

      再次感谢!这太棒了。

    10. 你可以给菜单的父元素一个更高的z索引和相对位置,它与其他定位的元素处于同一级别或更高的位置。

      [div id=“positionedelement”style=“position:relative;z-index:1”]
      [/div]

      [div id=“menu”style=“位置:相对;z索引:2”]
      [ul][li]列表1
      [ul]子菜单[/ul]
      [/li][/ul]
      [/div]

      [div id=“positionedelement”style=“position:relative;z-index:1”]
      [/div]

    11. 当您在下面的内容中使用“overflow:auto;”css样式时,Moz/Firebird/Net中的菜单似乎不起作用。如果您将鼠标悬停在这些浏览器的链接上,当您将光标移动到下面的内容上时,菜单会隐藏。在Explorer和Opera中工作正常…

      过来看:
      http://www.acc.umu.se网站/~caran/barebone.html

      我不知道这是不是代码或浏览器中的缺陷…你知道吗?

    12. 好的,在这个例子中,列表中的第一个元素有一个可点击的区域,它是整个框,而不仅仅是文本。任何下拉菜单中第一个元素下方的链接都有一个只包含文本的可单击区域,有没有办法修复它,以便下拉菜单中的所有链接都有整个框的可单击区,而不仅仅是文本?

    13. 真的很喜欢菜单,已经计划在一个网站上实现它们,并将密切关注该网站的更多下拉级别。这将使剧本更加出色。

      我会试试看我是否能帮上忙。

    14. 我的菜单在Netscape 6.2.3中闪烁。似乎这里唯一的解决方案是等待浏览器更新。有人找到这个问题的答案了吗?

      达格玛

    15. Suckerfish示例在MacOs9上的Netscape 6.2.2上似乎不起作用。还有其他人经历过吗?这只是我的机器还是那个版本的浏览器有问题?有人找到解决办法了吗?

    16. 之前的评论指出,Safari 1.0存在一个大问题,尽管Safari 1.1中的下拉功能很好(显然,苹果修复了这个错误)。从阅读所有评论来看,Safari 1.0问题似乎是菜单中最糟糕的问题。

      这里有一个解决方法。这使用JavaScript来检测Safari 1.0,并仅对该浏览器隐藏二级菜单。

      在标签上方插入以下内容:

      当然,您可以将JavaScript放在一个单独的文件中,但对它的引用需要位于CSS后面的.

      我从Chris Nott的Browser Detect脚本中复制了大部分代码行,该脚本可在http://www.dithered.com/javascript/browser_detect网站/

      注意:(1)Safari用户代理字符串中的版本号是内部版本号,而不是1.0或1.1;(2)我不知道脚本中使用的正确数字。87可能不是最好的。我所知道的是,我使用的是Safari 1.0.1(与操作系统1.2.8一起),它的版本是85.6。我不知道Safari 1.1的第一个版本是什么。(我没有在Dave Hyatt的博客上看到它。)如果有人知道答案,请发布。

      使用上述代码,Safari 1.0.1仅显示带有工作链接的顶级菜单,而下拉菜单在其他浏览器中可用。

    17. 更正:我的帖子的标题应该是“Safari 1.0工作区”(而不是1.1)。我使用的是Mac OS X 10.2.8(最新Jaguar版本)。

      还要注意,我不是JavaScript向导,所以可能有人能够改进代码。

    18. 如果有人在黄金时间有一个垂直弹出式/“下拉”菜单,我很想看看;如果你愿意分享,请使用代码。

      我一直在尝试创建一个垂直版本,其中二级菜单向左侧打开。在花了几天时间,包括查看几个著名的CSS站点以获取想法(包括Listamatic)之后,我几乎成功了,但已经放弃了。据我所知,浏览器支持尚不足以在付费客户的商业网站上实现这一点。

      埃里克·梅耶(Eric Meyer)接近了
      http://www.meyerweb.com/eric/css/edge/menus/demo.html
      但它只在一些浏览器中工作,一些重要的细节也不太好(鼠标悬停时,顶级菜单中的菜单“标题”消失了)。还不够满足我的需要。

      考虑到只有CSS的解决方案还没有准备好用于黄金时段,我想找到一个符合ALA通常标准的JavaScript替代品:高质量、高标准兼容性、轻量级、可移植、可定制。当然,它需要在几乎所有浏览器中工作,尤其是IE/Win。

    19. 有什么方法可以链接到外部样式表来做同样的事情吗?我想使用这个IE黑客,但我正在努力保持我的网页干净。

    20. Larry的上述代码似乎获取了“伪造的”Mozilla版本号(即“5”),而不是Safari内部版本号。因此,使用他的代码似乎会对所有版本的Safari禁用下拉功能,而不仅仅是Panther之前的版本。

      我设法编造出了以下代码,似乎抓住了正确的内部版本号。请注意,Javascript根本不是我的专长,所以你们中的一些人无疑会找到“改进的机会”🙂

      //Sniff pre v.86版Safari

      var agt=导航器.userAgent.toLowerCase();
      var appVer=导航器.appVersion.toLowerCase();

      var is_safari=(agt.indexOf(“safari”)!=-1);
      var build=appVer.substring(appVer.lastIndexOf(“/”)+1);

      if(内部版本<86){document.write('

      ‘);
      }

    21. 为您修复了几个问题并进行了验证。我在MSIE6.0、Netscape 7.1、Opera 7.23、Mozilla/Firebird 0.7、K-Meleon 0.8.2中实现了(我认为)你想要的效果。css的主要变化是:

      李{

      清除:左;
      浮动:左;
      }
      ul>li{
      明确:无;
      float:无;
      }

      li>ul{
      顶部:自动;}

      请参见:http://whistlingduck.wrellis.com/menu4.html

      我在Mac浏览器上的网站仍然存在问题。不幸的是,我无法轻松使用Mac,所以周转很慢。如果有人有什么建议,我一定会很感激。
      -威廉·埃利斯

    22. 不要忘记doctype:

      我使用的是Transitional,它在Mac/IE中不起作用。一旦我改为strict,一切都很好。

    23. 我在学校的一个网站上工作,我的老师拒绝放弃框架。他想要一个典型的侧栏式下拉菜单。在尝试了这个例子后,我的下拉框超出了框架,所以效果不太好。
      我正在考虑两种解决方案,想知道这里是否有人能帮我解决其中的任何一种。

      解决方案1:以这样的方式对下拉列表进行编码,以便下拉列表将同一列中的较低选项推到一边。示例(希望能成功):

      标题1
      标题2
      标题3

      当鼠标悬停在标题2上时,您会得到:

      标题1
      标题2
      选项1
      选项2
      标题3

      你明白了吧?

      解决方案2(可能更容易?):他反对表格而不是框架,主要是因为维护一个菜单文件更容易。因此,我想知道是否可以添加一个特殊的HREF,将菜单的代码嵌入到表中,而无需再次复制。我希望你能理解我的意思…

      谢谢你的帮助,我发现这是一个很好的信息网站。

    有话要说吗?

    我们已经关闭了评论,但你可以看到在我们这样做之前人们都说了些什么。

    来自ALA的更多信息