“ javascript:void(0);” vs“返回假”与“ preventDefault()”


75

当我希望某些链接不执行任何操作而仅响应javascript操作时,避免链接滚动到页面顶部的最佳方法是什么?
我知道几种方法,它们似乎都可以正常工作:

<a href="javascript:void(0)">Hello</a>

要么

<a id="hello" href="#">Hello</a>
<script type="text/javascript>
  $(document).ready(function() {
    $("#toto").click(function(){
      //...
      return false;
    });
  });
</script>

乃至 :

<a id="hello" href="#">Hello</a>
<script type="text/javascript>
  $(document).ready(function() {
    $("#toto").click(function(event){
      event.preventDefault();          
      //...
    });
  });
</script>

你有什么喜好吗?为什么呢?在什么条件下?

PS:当然,以上示例假定您使用的是jquery,但是mootools或prototype的等效项是。

Answers:


68

捆绑:

  • javascript: URL总是令人恐惧。
  • 内联事件处理程序属性也不是很好,但是可以进行一些快速的开发/测试。
  • 通常,从脚本进行绑定以使标记保持干净是一种最佳做法。jQuery鼓励这样做,但是没有理由不能在任何库或普通JS中做到这一点。

回应:

  • 在jQuery中,return false表示preventDefaultstopPropagation,因此,如果您关心父元素接收事件通知,则含义不同。
  • jQuery将其隐藏在此处,但preventDefault/stopPropagation通常必须在IE中(returnValue/ cancelBubble)拼写不同。

然而:

  • 您有一个不是链接的链接。它没有链接到任何地方。这是一个动作。<a>并不是真正的理想标记。如果有人尝试单击鼠标中键,或将其添加到书签,或链接具有的其他任何功能,它都会出错。
  • 对于确实指向某物的情况,例如当它打开/关闭页面上的另一个元素时,请将链接设置为指向#thatelementsid并使用不引人注目的脚本从链接名称中获取元素ID。您还可以嗅探location.hash文档上的加载以打开该元素,因此该链接在其他上下文中变得很有用。
  • 否则,对于纯粹是动作的操作,最好将其标记为:<input type="button"><button type="button">。您可以使用CSS设置样式,使其看起来像链接而不是按钮(如果需要)。
  • 但是,按钮样式的某些方面在IE和Firefox中无法完全消除。通常这并不重要,但是如果您确实需要绝对的视觉控制,则可以选择使用a作为折衷方案<span>。您可以添加一个tabindex属性,以使其在大多数浏览器中都可以通过键盘访问,尽管这实际上并没有适当地标准化。您还可以在其上检测到诸如空格或Enter之类的按键来激活。这虽然不尽如人意,但仍然很受欢迎(例如,SO就是这样)。
  • 另一种可能性是<input type="image">。这具有具有完全视觉控制的按钮的可访问性优点,但仅适用于纯图像按钮。

2
+1,但我不同意“内联事件处理程序属性也不是很出色”。除非需要多个处理程序,否则标记属性(例如)onclick是迄今为止将事件处理程序附加到元素的最简单,最干净的方法。
卡萨布兰卡2010年

感谢您的完整答复。我从来没有这样想过……但是现在对我来说,它显然不应该是一个链接。我将尝试上述技术的输入/跨度,看看哪种方法更合适。@casablanca我不太同意,我写了第一个示例,但我从未真正使用过。我讨厌在html中看到css的方式相同,我真的认为javascript代码应始终不引人注目并保留在外部文件中。
迈克,2010年

6
我完全同意“内联事件处理程序属性也不是很出色”。对于快速原型制作来说,它们可能很简单,但是当您必须添加第二个处理程序时,您很快会在附加处理程序的方式上变得不一致,并且不一致会导致错误。这个连接应该在自己的工作,因为bobince状态,并增强其执行花哨的壮举应该是一部分控制器,它应保持独立的模型视图
斯蒂芬·P

3
Stephen P-完全同意,只是暗示MVC是“正确的事情” :)这只是组织事物的一种方法(公认很受欢迎),并且它与其他所有事物一样都有缺点。
sje397 2010年

1
如果您永远不需要一个特定事件和元素的多个侦听器功能,并且知道自己的想法,那么事件处理程序属性就没有问题。实际上,它们比其他所有可以立即工作的事件绑定方法具有优势,而不必等待其他脚本加载和执行绑定。
Tim Down'8

18

我能想到的唯一好处javascript:void(0)是,即使最老的浏览器也将支持它。就是说,我将使用您提到的另一种不引人注目的方法:

  • 对于大多数用途,event.preventDefault()并且return false可以互换使用。
  • event.preventDefault()将阻止页面根据需要进行重新加载,但将使click事件冒泡到父级。如果您想停止冒泡,可以将其与结合使用event.stopPropagation
  • return false 还将阻止事件冒泡到父事件。

我在上面的第一点说“可互换”,是因为在很多时候我们都不在乎事件是否会发生在父母身上。然而,当需要一些微调,我们应该考虑分两个和三个。

考虑以下示例:

<div>Here is some text <a href="www.google.com">Click!</a></div>​

$("a").click(function(e) {
    e.preventDefault();
});

$("div").click(function() {
    $(this).css("border", "1px solid red");
});
​

单击锚点将阻止触发事件的默认操作,因此浏览器将不会重定向到www.google.com。但是,该事件仍将“冒泡”并导致div的click事件触发,这将在其周围添加边框。添加e.stopPropagation() 或仅 添加return falsediv的click事件将不会触发。您可以在这里弄乱它:http : //jsfiddle.net/cMKsN/1/


出于兴趣:event.precentdefault()如果在处理程序代码中发生异常之后,在处理程序顶部进行调用是否有效?
sje397

@ sje397是的,如果有,event.preventDefault(); someFunction();并且someFunction()中断,默认事件仍然会停止。
罗伯特2010年

好吧,您对那里的浏览器支持有所了解,但是也很好地解释了这两个世界,停止传播并阻止默认值+1
Leo

2

默认情况下,Dreamweaver使用一个很好的小技巧,我已经开始使用它。

<a href='javascript:;'></a>

它很小,不会绊倒和锚定,并且与库无关。


我认为这与我的第一个例子相同。浏览器正在等待URL,在两种情况下,表达式都将被评估为null或undefined(null == undefined)。
Mike

@Mike:undefined在两种情况下,它的评估结果实际上都是。null是有效的JavaScript值,与相同undefined
卡萨布兰卡2010年

@casablanca:仍然认为(null ==未定义)=== true,(null ===未定义)=== false。
weiglt 2014年

美丽!这正是我所需要的!
尼克


1

event.preventDefault()而且return false;是一回事-它们指示浏览器不要处理该事件的默认操作(在这种情况下,请导航到所单击的锚标签的href)。 href=javascript:和类似的东西-它们导致默认操作为“不执行任何操作”。

这是一个风格问题。您是要在onclick中完成所有工作,还是要能够在onclick和href中都添加操作,并依靠浏览器的功能在两者之间进行调整?


2
event.preventDefault()return false;不是一两件事
蒂莫Huovinen

1

我喜欢href="javascript:void(0)"在链接中使用,因为这#意味着跳到页面顶部,并且如果由于某种原因您的jQuery事件未加载(例如jQuery无法加载)而实际上可能会发生。

我也使用event.preventDefault();它,因为即使返回false之前遇到错误,它也不会跟随链接;例如:

HTML:

<a id="link" href="http://www.google.com">Test</a>

jQuery示例1:

$("#link").click(
    function(){
        alert("Hi");
        invalidCode();
        return false;
    }
);

jQuery示例2:

$("#link").click(
    function(event){
        event.preventDefault();
        alert("Hi");
        invalidCode();
        return false;
    }
);

由于invalidCode();return false永远不会引发错误,因此如果使用jQuery示例1,则用户将被重定向到Google,而在jQuery示例2中,则不会。


1

我认为我也看过javascript :; 随着网络的发展,很难跟踪到那里可用的技巧。但这主要是关于可访问性(除了javascript:void(0);),而只是一个小小的修正不是javascript:void(0)但是javascript:void(0); 这意味着什么都不做就返回false;尽管不确定javascript:return false; 一样。

我一直使用并且建议使用javascript:void(0); 当然有两个原因。

1.)我使用它的原因是上面提到的同一个人。.href =“#”不适合使用,因为它可能表示要到达顶部,即使在这种情况下,“#top”对于这种情况也足够了。但这也会触发代码中使用#(哈希)的其他内容,因此另一个原因是避免与其他可能使用#的JavaScript发生冲突。而且,例如,在使用插件时,我倾向于查找此字符,并立即将其替换。.href ='#'到href ='javascript:void(0);' 或href ='javascript :;'

2.)如果我想为一组特定的Anchor标记重用一个函数,则可以在任意属性上使用选择器来调用它,而不必担心检测到click事件并防止默认操作,并且我什至没有想到作为发展偏好。

3.)在大多数情况下,如果您使用javascript:void(0);建立链接,尝试使链接不遵循旧的href = rel = nofollow,因此它避免索引作为操作的链接。我对此不太确定,只是因为听说爬虫和机器人现在甚至可以读取Flash,所以如果他们可以读取javascript链接也不会感到惊讶

4.)从2.)进行引用,您可以定位到类似的类,而无需使用href =“ javascript:void(0);”来避免单击事件默认操作。然后直接从jQuery函数的选择器中定位类。

        jQuery(function($)
        {
            //from the rel
            $('a[rel="-your-rel-id"]') ... off('click').on('click',function()

            //from the class
            $('a.-the-class') ... off('click').on('click',function()

            //from the id

            $('a#-the-id').off('click').on('click',function()
            {
            --do something with this link
        });

}); 

我宁愿像往常一样去上课更自在...

$(a#-your-id).hasClass(-yourclass-)

或任何其他有趣的组合,并且会影响许多链接..所以我真的不建议仅将A用作选择器。

通常我在这里看到的是这样的:

  jQuery(function($)
        {
            //from the rel
            $('a[rel="-your-rel-id"]').on('click',function(event)
            //do something
            //prevent the click as is passed to the function as an event
            event.preventDefault();
        });

});

0

我宁愿不要将JavaScript放入,href因为这不是它的意思。我喜欢这样的东西

<a href="#" onclick="return handler();">Link</a>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.