如何在Bootstrap下拉菜单中防止URL末尾出现#号?

10

我有这个链接:

<a href="#" id="myBtn"><i class="icon-user"></i><span>Add user</span></a>

为了避免地址末尾的#,我使用preventDefault()return false,这很有效。但问题是当我在Bootstrap下拉菜单中这样做时,如果我保留return false,它不会像预期的那样在末尾添加#,但也会阻止下拉菜单消失,如果我删除return false则下拉菜单可以正常工作。 这是我的下拉菜单代码:

<li class="dropdown">
  <a class="dropdown-toggle" data-toggle="dropdown" href="#" id="ddBtn">
    <i class="icon-wrench"></i><span>Parent Item<b class="caret"></b></span>
  </a>
  <ul class="dropdown-menu">
    <li><a href="#" id="ddSonBtn">Child item</a></li>

Javascript:

$("#ddSonBtn").click(function () {
    //some code

    e.preventDefault();
});

有解决方案吗?

我正在使用

Bootstrap 2
jQuery

谢谢。


你的 JavaScript 代码呢? - MassivePenguin
@MassivePenguin,没有什么不同于通常的,但我已经按照你的要求更新了我的问题。 - eestein
6个回答

14
根据Bootstrap文档:http://getbootstrap.com/javascript/#dropdowns,需要用"data-target"属性替换"href",即:
<a data-target="#" id="myBtn"><i class="icon-user"></i><span>Add user</span></a>

我认为更符合"bootstrapish"的方式是执行操作,而不是抑制事件处理程序或手动操纵显示/隐藏行为。


谢谢!我正在使用Bootstrap折叠功能,但是文本锚点没有导致#anchor被添加到浏览器URL中,然而,具有相同锚点的字体awesome图标会导致#anchor被添加,所以我交换了href和data-target,现在一切正常! - William Worley

12

可能有文档记录,但在jQuery事件中不需要同时调用preventDefault() return false;

编辑:来自jQuery的on 文档:“从事件处理程序返回false将自动调用event.stopPropagation() event.preventDefault()”(http://api.jquery.com/on/#event-handler)

return false; 等同于 e.preventDefault();e.stopPropagation();

preventDefault 阻止元素的默认行为 - 如提交按钮提交表单,锚点导航到特定的 href 等。

stopPropagation 停止事件在DOM中向上冒泡。这意味着,目标元素的父级元素将不会触发事件。

在处理事件时,选择使用哪个功能。在您的情况下,您可能只需要在Dropdown的click处理程序中调用preventDefault

此外,在您的代码中,函数作用域中使用return是执行的最后一行。当运行函数时,其后的任何代码都不会被执行。


嗨Ian,谢谢你,但实际上不是这样的,如果我只调用preventDefault,就像我在问题中所说的那样,它会在地址末尾添加#。谢谢。 - eestein
我已经尝试过仅使用 return false,它确实可以工作,不会添加 #,但仍然会防止下拉菜单消失。 :( - eestein
@eestein 我不确定是否仍应添加 #。如果您绑定到正确的元素并且做正确的事情,它将正常工作。无论如何,您提供的HTML与您的Javascript不匹配。您正在将单击事件绑定到具有“id”为“xptoBtn”的元素,但我在您的HTML中没有看到该元素。您不应使用 return false; 因为它实际上调用了 stopPropagation(),这会停止冒泡,因此不允许Bootstrap正确处理事件。您应该在正确的位置上只使用 preventDefault。请发布您的实际代码。 - Ian
Ian,对不起我误读了你的评论。我刚刚试过使用preventDefault,结果与我在第一条评论中说的一样。它确实允许Bootstrap隐藏下拉菜单,但是会在末尾添加# - eestein
@eestein 你绑定事件使用的是 $("#ddSonBtn").click(function () {,但你需要设置事件参数。请改用 $("#ddSonBtn").click(function (e) { - 注意 e - Ian
显示剩余3条评论

2

只需从 href 属性中删除 # 值即可。将 href 留空是有效的HTML。

<a href="" id="myBtn"><i class="icon-user"></i><span>Add user</span></a>

现在既然这个回答被踩了,我很想知道为什么它不是一个好的解决方案。对我来说,在所有当前的浏览器中,它都像魔法一样运行得很好,而且正如预期的那样。但也许我没有看到整个情况,所以我很好奇... - Bernhard Koenig
1
尽管我绝对不赞成使用JavaScript伪协议,但空href是一个合适的解决方案。帮了我一个大忙——谢谢! - JAAulde
1
@JAAulde 谢谢你,你是对的。我的帖子读起来好像JavaScript解决方案和空href一样,而我的意图只是提供另一种选择,如果由于某些原因空href不可行的话。经过再次思考,我决定删除这个替代方案(因为你已经确认更好/更清洁的解决方案已经实现了它应该实现的功能)。 - Bernhard Koenig
1
请注意,如果您删除 # 值,则需要显式使用 e.preventDefault() 禁用链接,否则页面将重新加载。 - Tim Mackey

0

使用此代码适用于Bootstrap + jQuery:

$(this).parent().parent().parent().removeClass("open")

0

我曾经遇到同样的问题,经过长时间的搜索后才意识到是我的错误。我链接到bootstrap js文件时出现了错误(完整性哈希值不正确),因此无法加载。这导致某些页面上的下拉菜单无法正常工作。


-1

我尝试了这种方法,它有效。示例(CoffeeScript)如下:

jQuery ->
  $('.your_mark ul.dropdown-menu li').click ->
    # Do what you want
    $(this.parentElement.parentElement).removeClass('open')
    return false
  1. 通过从btn-group div中删除css类“open”来手动关闭下拉菜单。
  2. 返回false以避免在您的url中出现#。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接