将JavaScript代码放入<a>的不同方法之间有什么区别?


87

我已经看到以下将JavaScript代码放入<a>标记中的方法:

function DoSomething() { ... return false; }
  1. <a href="javascript:;" onClick="return DoSomething();">link</a>
  2. <a href="javascript:DoSomething();">link</a>
  3. <a href="javascript:void(0);" onClick="return DoSomething();">link</a>
  4. <a href="#" onClick="return DoSomething();">link</a>

我了解尝试放置有效URL而不只是JavaScript代码的想法,以防万一用户未启用JavaScript。但出于讨论的目的,我需要假定JavaScript已启用(没有JavaScript,他们将无法登录)。

我个人喜欢选项2,因为它使您可以查看将要运行的内容–在调试将参数传递到函数的位置时特别有用。我已经使用了很多,还没有发现浏览器问题。

我已经读过人们推荐4,因为它给用户提供了一个真正的链接,但是#实际上不是“真实的”。绝对不会到哪里去。

当您知道用户启用了JavaScript时,是否存在不支持或真的很糟糕的应用?

相关问题:JavaScript的Href链接:“#”还是“ javascript:void(0)”?


小语法问题:选择#2应该是-<a href="javascript:DoSomething();">链接</a>不带“返回”
DRosenfeld,2015年

请将接受的答案更改为@eyelidlessness答案。我认为这是最好的方法,因为它关心语义。
米哈尔Perłakowski

Answers:


69

我非常喜欢Matt Kruse的Javascript Best Practices文章。他在其中指出,使用该href部分执行JavaScript代码是一个坏主意。即使您已声明用户必须启用JavaScript,但也没有理由没有一个简单的HTML页面,href如果有人在登录后碰巧关闭了JavaScript ,则所有JavaScript链接都可以指向其相应部分。我强烈建议您仍然允许这种备用机制。这样的事情将遵循“最佳实践”并实现您的目标:

<a href="javascript_required.html" onclick="doSomething(); return false;">go</a>

4
因为href值会在状态栏中显示给用户?(底部的栏)我会考虑使用一些更用户友好的链接,例如。“ js.html?doSomething”页面仍可以是静态html。这样,用户将清楚地看到链接之间的差异。
基因

7
您可以使用title属性覆盖此值,例如<a href="javascript_required.html" title="Does Something" onclick="doSomething(); return false;"> go </a>
显眼的编译器2010年

最好的做法是将请求记录到javascript_required.html页面并记录导致错误的函数。
蒂莫·霍维宁

2
您是否考虑过SEO的后果?
DanielBlazquez 2012年

Matt Kruse的javascripttoolbox.com似乎已离线销售。
showdev

10

可以使用addEventListener/时为什么要这样做attachEvent?如果不存在href-equivalent,则不要使用<a><button>并相应地设置其样式。


9
在许多情况下,使用按钮代替链接不是可行的选择。
尼克

2
因为看起来很丑。您可以在链接旁边添加一个图标。它们很难在浏览器中格式化。通常,人们正在转向链接而不是按钮-着眼于栈中的大部分流量。
Darryl Hein

2
看起来很丑吗?它看起来像您想要的样子。实际上,我认为按钮实际上比链接具有更多的样式灵活性,因为它们是内联的,但可以适当地跨浏览器填充。就CSS而言,任何可以通过链接完成的操作都可以通过按钮完成。
2008年

2
跨度不能以键盘为中心。
bobince

3
按钮在语义上是正确的。跨度在语义上没有意义。从语义上讲,按钮正是作者打算使用的按钮。
2008年

5

您忘记了另一种方法:

5: <a href="#" id="myLink">Link</a>

使用JavaScript代码:

document.getElementById('myLink').onclick = function() {
    // Do stuff.
};

我无法评论哪个选项提供了最好的支持,或者哪个选项在语义上是最好的,但是我只是说我更喜欢这种样式,因为它将您的内容与JavaScript代码分开。它将所有JavaScript代码保持在一起,这很容易维护(特别是如果您将其应用于许多链接),甚至可以将其放在一个外部文件中,然后将其打包以减小文件大小并由客户端浏览器缓存。


7
如果您有20或30个与JS的不同链接,这可能会变得很乏味,最终会产生很多JS。
达里尔·海因

它比遍历HTML更改javascript更乏味。...或者您可以使用类似jQuery的东西,它可以一次轻松地更改多个元素上的事件... $('#menu a')。click(function(){..})
尼克

1
@JKirchartz如果答案背后有原因,我不知道这是如何讲道的。如果您读了这个问题,那的确是“这四个中的哪一个最好”,我只是指出他没有考虑过另一种选择。
尼克

不要在意,trololo,ABC和d之间进行选择时,一个不选择E.
JKirchartz

3
@JKirchartz是的,我认为您当时并没有真正实现Stack Overflow的目的。如果有人问“用以下哪种方式构建Web应用程序更好:Cobol或Fortran?” 告诉那个人他们没有考虑所有可能性是可以接受的。问题显然不是在问“仅在这四件事中哪一个是最好的”。
尼克

3
<a href="#" onClick="DoSomething(); return false;">link</a>

我将这样做,或者:

<a href="#" id = "Link">link</a>
(document.getElementById("Link")).onclick = function() {
    DoSomething();
    return false;
};

视情况而定。对于较大的应用程序,第二个最好,因为这样可以合并您的事件代码。


如果您有20或30个与JS的不同链接,这可能会变得很乏味,最终会产生很多JS。
Darryl Hein

而且蠕虫会渗入您的代码中,很难调试。如您的第一个示例所示,这些错误非常容易出现。:)
尼克

1

方法2在FF3和IE7中存在语法错误。我更喜欢方法#1和#3,因为#4尽管用'#'使URI变脏,尽管键入的次数较少...显然,如其他响应所指出的那样,最好的解决方案是将HTML与事件处理分开。


什么是方法2?这些问题与您看到时的顺序不同。
Diodeus-詹姆斯·麦克法兰(James MacFarlane)

如果您确定,方法#4不会弄乱URI return false。因此,(列出的)方法#4可能是最好的。
2008年

2
@Diodeus,我相信Pier指的是问题中的编号列表,实际上自问题发布以来就一直存在。
失明眼2012年

1

我注意到这之间的一个区别:

<a class="actor" href="javascript:act1()">Click me</a>

还有这个:

<a class="actor" onclick="act1();">Click me</a>

是无论哪种情况,您都有:

<script>$('.actor').click(act2);</script>

那么对于第一个示例,act2它将act1在第二个示例之前运行,而在第二个示例中,情况将相反。


1

仅现代浏览器

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
(function(doc){
    var hasClass = function(el,className) {
        return (' ' + el.className + ' ').indexOf(' ' + className + ' ') > -1;
    }
    doc.addEventListener('click', function(e){
      if(hasClass(e.target, 'click-me')){
          e.preventDefault();
          doSomething.call(e.target, e);
      }
    });
})(document);

function doSomething(event){
  console.log(this); // this will be the clicked element
}
</script>
<!--... other head stuff ...-->
</head>
<body>

<!--buttons can be used outside of forms https://stackoverflow.com/a/14461672/175071 -->
<button class="click-me">Button 1</button>
<input class="click-me" type="button" value="Button 2">

</body>
</html>

跨浏览器

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
(function(doc){
    var cb_addEventListener = function(obj, evt, fnc) {
        // W3C model
        if (obj.addEventListener) {
            obj.addEventListener(evt, fnc, false);
            return true;
        } 
        // Microsoft model
        else if (obj.attachEvent) {
            return obj.attachEvent('on' + evt, fnc);
        }
        // Browser don't support W3C or MSFT model, go on with traditional
        else {
            evt = 'on'+evt;
            if(typeof obj[evt] === 'function'){
                // Object already has a function on traditional
                // Let's wrap it with our own function inside another function
                fnc = (function(f1,f2){
                    return function(){
                        f1.apply(this,arguments);
                        f2.apply(this,arguments);
                    }
                })(obj[evt], fnc);
            }
            obj[evt] = fnc;
            return true;
        }
        return false;
    };
    var hasClass = function(el,className) {
        return (' ' + el.className + ' ').indexOf(' ' + className + ' ') > -1;
    }

    cb_addEventListener(doc, 'click', function(e){
      if(hasClass(e.target, 'click-me')){
          e.preventDefault ? e.preventDefault() : e.returnValue = false;
          doSomething.call(e.target, e);
      }
    });
})(document);

function doSomething(event){
  console.log(this); // this will be the clicked element
}
</script>
<!--... other head stuff ...-->
</head>
<body>

<!--buttons can be used outside of forms https://stackoverflow.com/a/14461672/175071 -->
<button class="click-me">Button 1</button>
<input class="click-me" type="button" value="Button 2">

</body>
</html>

您可以在文档准备好之前运行此程序,因为我们将事件附加到文档上,所以单击按钮将起作用。

资料来源:

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.