我正在尝试实现一个简单的水平导航菜单,它只为每个链接显示一个 div。它有点像下拉菜单,但不是鼠标悬停触发下拉菜单,而是 onclick 事件将触发 div 的显示。我想确保我在走得更远之前采取了正确的方法,我们将不胜感激。这是我目前所拥有的:
<ul id="settings_nav">
<li>
<a>Theme</a>
<div id="settings_block"><%= render :partial => 'email_password' %></div>
</li>
<li>
<a href="index.htm">Lists</a>
<div id="settings_block"><%= render :partial => 'lists' %></div>
</li>
</ul>
window.onload = function(){
settingsMenuInit('settings_nav')
}
function settingsMenuInit(settings_nav){
$(settings_nav).childElements().each(
function(node){
node.onclick= function(){ this.next.show() };
})
}
类似的东西,但我不确定如何获取当前显示的 div 并将其隐藏。我可以遍历所有 childElements 并隐藏每个 div,然后显示被点击的那个,但也许有更好的方法?
最佳答案
一些笔记 FW(T)W:
使用 Prototype 和类似的库,您不想通过将函数分配给元素的
onclick
和类似的属性来连接事件处理程序;这种风格有几个缺点(尤其是元素上的事件只能有一个处理程序)。相反,使用 Prototype 的observe
功能:someElement.observe('click', functionRefHere); // or Element.observe(someElementOrID, 'click', functionRefHere);
这还可以让 Prototype 为您解决一些 IE 内存丢失错误。
您可能会看到 Prototype 的
dom:loaded
事件,它比window.onload
发生得更快(直到您的所有图像和其他外部资源已加载,可能在页面显示后一两秒):document.observe('dom:loaded', initFunctionRefHere);
您可以使用事件委托(delegate)并只观察您的 settings_nav 元素,而不是单独观察每个子节点。
$(settings_nav).observe('click', handleNavClick); function handleNavClick(event) { var elm = event.findElement("some CSS selector here"); if (elm) { event.stop(); // Handle it } }
如您所见,
Event#findElement
接受 CSS 选择器。它从被点击的实际元素开始,并尝试将其与选择器匹配;如果匹配,则返回该元素,否则去父节点看是否匹配;等。因此,对于您的 HTML,您可能会查找li
(event.findElement('li')
) 或链接 (event.findElement('a' )
).但是如果你想单独观看每一个,他们可以共享一个函数(就像他们在你的例子中所做的那样):
$(settings_nav).childElements().invoke('observe', 'click', handleNavClick); function handleNavClick(event) { // Prototype makes `this` reference the element being observed, so // `this` will be the `li` element in this example. }
您是单独观察每个元素还是使用事件委托(delegate)取决于您在做什么(和个人偏好)。每当任何事情可能改变(例如,添加和删除导航
li
元素)或有很多事情需要注意时,请查看事件委托(delegate)——这要容易得多使用事件委托(delegate)并仅观察父元素来处理不断变化的元素集会更简单。在处理只有少数事物的稳定结构时(如您的示例),单独观察元素可能更简单。进入处理程序后,您可以使用
Element#down
找到子元素(所以从li
,你可以使用li.down('div')
来找到 div),或者Element#next
到达下一个兄弟元素(例如,从链接到 div)。无论哪种方式,一旦你有对 div 的引用,你就可以使用Element#show
和Element#hide
(或Element#toggle
)。我建议使用命名函数 而不是匿名函数(参见我上面的示例)。命名函数帮助您的工具(调试器、显示错误的浏览器等)帮助您。请确保不要声明命名函数并将其用作表达式(例如,不要立即将其分配给某物):
// Don't do this because of browser implementation bugs: someElement.observe('click', function elementClickHandler(event) { // ... }); // Do this instead: someElement.observe('click', elementClickHandler); function elementClickHandler(event) { // ... }
...因为虽然您应该能够根据规范做到这一点,但实际上各种浏览器中的各种错误使其无法可靠地工作(article)。
关于javascript - 带有原型(prototype)的简单水平 Javascript 导航,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2360953/