在锚点上执行 Javascript 的最佳方式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7516235/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 00:22:40  来源:igfitidea点击:

Best way to execute Javascript on an anchor

javascriptonclick

提问by steveo225

Generally, there are 3 ways (that I am aware of) to execute javascript from an <a/>tag:

通常,有 3 种方法(我知道)从<a/>标签执行 javascript :

1) Use onclick():

1)使用onclick()

<a href="#" onclick="alert('hello'); return false">hello</a>

2) Directly link:

2)直接链接:

<a href="javascript:alert('hello')">hello</a>

3) Or attach externally:

3)或外部连接:

// In an onload event or similar
document.getElementById('hello').onclick = window.alert('Hello'); 
return false;
<a id="hello" href="#">hello</a>

I am actually loading the link via AJAX, so #3 is basically out. So, is it better to do #1 or #2 or something completely different? Also, why? What are the pitfalls that I should be aware of?

我实际上是通过 AJAX 加载链接的,所以 #3 基本上已经结束了。那么,做#1 或#2 或完全不同的事情更好吗?还有,为什么?我应该注意哪些陷阱?

Also of note, the anchor really doesn't link anywhere, hence the href="#", I am using aso the styles conform as this is still an object to be clicked and a button is inappropriate in the context.

另外值得注意的是,锚点真的没有链接到任何地方,因此href="#",我正在使用 ,a所以样式符合,因为这仍然是一个要单击的对象,并且按钮在上下文中是不合适的。

Thanks

谢谢

采纳答案by jfriend00

If you are loading the content via ajax and need to hook up event handlers, then you have these choices:

如果您通过 ajax 加载内容并需要连接事件处理程序,那么您有以下选择:

  1. Put a javascript handler in your HTML with your option 1) or 2). In my mind option 1) is a cleaner way of specifying it, but I don't think there's a mountain of difference between 1) or 2) - they both do essentially the same thing. I'm not a fan of this option in general because I think there's value in keeping the markup and the code separate.
  2. After loading the content with ajax, call some local code that will find and hook up all the links. This would be the same kind of code you would have in your page and execute on DOMReady if the HTML had been static HTML in your page. I would use addEventListener (falling back to attachEvent) to hook up this way as it more cleanly allows multiple listeners for a single object.
  3. Call some code after you load the content with ajax that finds all the links and hooks up the clicks to some generic click handler that can then examine meta data in the link and figure out what should be done on that click based on the meta data. For example, this meta data could be attributes on the clicked link.
  4. When you load the content, also load code that can find each link individually and hook up an appropriate event handler for each link much the way one would do it if the content was just being loaded in a regular page. This would meet the desire of separating HTML from JS as the JS would find each appropriate link and hook up an event handler for it with addEventListener or attachEvent.
  5. Much like jQuery .live()works, hook up a generic event handler for unhandled clicks on links at the document level and dispatch each click based on some meta data in the link.
  6. Run some code that uses an actual framework like jQuery's .live()capability rather than building your own capability.
  1. 使用选项 1) 或 2) 在 HTML 中放置一个 javascript 处理程序。在我看来,选项 1) 是一种更清晰的指定方式,但我认为 1) 或 2) 之间没有太大区别——它们本质上都是一样的。我一般不喜欢这个选项,因为我认为将标记和代码分开是有价值的。
  2. 使用ajax加载内容后,调用一些本地代码,将查找并连接所有链接。如果 HTML 是页面中的静态 HTML,这将与您在页面中拥有并在 DOMReady 上执行的代码相同。我将使用 addEventListener(回退到 attachEvent)以这种方式连接,因为它更干净地允许单个对象有多个侦听器。
  3. 在使用 ajax 加载内容后调用一些代码,它会查找所有链接并将点击连接到一些通用点击处理程序,然后可以检查链接中的元数据,并根据元数据确定应该对点击执行什么操作。例如,这个元数据可以是点击链接的属性。
  4. 当您加载内容时,还要加载可以单独查找每个链接的代码,并为每个链接连接一个适当的事件处理程序,就像内容只是在常规页面中加载时所做的那样。这将满足将 HTML 与 JS 分离的愿望,因为 JS 会找到每个合适的链接并使用 addEventListener 或 attachEvent 为其挂钩一个事件处理程序。
  5. 与 jQuery 的.live()工作原理非常相似,在文档级别为未处理的链接点击连接一个通用事件处理程序,并根据链接中的一些元数据调度每次点击。
  6. 运行一些使用实际框架(如 jQuery 的.live()功能)而不是构建您自己的功能的代码。

Which I would use would depend a little on the circumstances.

我会使用哪个取决于具体情况。

First of all, of your three options for attaching an event handler, I'd use a new option #4. I'd use addEventListener (falling back to attachEvent for old versions of IE) rather than assigning to onclick because this more cleanly allows for multiple listeners on an item. If it were me, I'd be using a framework (jQuery or YUI) that makes the cross browser compatibility invisible. This allows complete separation of HTML and JS (no JS inline with the HTML) which I think is desirable in any project involving more than one person and just seems cleaner to me..

首先,在附加事件处理程序的三个选项中,我将使用一个新选项 #4。我会使用 addEventListener(对于旧版本的 IE 回退到 attachEvent)而不是分配给 onclick 因为这更干净地允许一个项目上的多个侦听器。如果是我,我会使用一个框架(jQuery 或 YUI)使跨浏览器兼容性不可见。这允许完全分离 HTML 和 JS(没有 JS 与 HTML 内联),我认为这在涉及多人的任何项目中都是可取的,对我来说似乎更清晰..

Then, it's just a question for me for which of the options above I'd use to run the code that hooks up these event listeners.

然后,这对我来说只是一个问题,我会使用上面的哪个选项来运行连接这些事件侦听器的代码。

If there were a lot of different snippets of HTML that I was dynamically loading and it would be cleaner if they were all "standalone" and separately maintainable, then I would want to load both HTML and relevant code at the same time so have the newly loaded code handle hooking up to it's appropriate links.

如果我动态加载了很多不同的 HTML 片段,并且如果它们都是“独立的”并且可以单独维护会更清晰,那么我会希望同时加载 HTML 和相关代码,因此有新的加载的代码句柄连接到它的适当链接。

If a generic standalone system wasn't really required because there were only a few snippets to be loaded and the code to handle them could be pre-included in the page, then I'd probably just make a function call after the HTML snippet was loaded via ajax to have the javascript hook up to the links in the snippet that had just been loaded. This would maintain the complete separation between HTML and JS, but be pretty easy to implement. You could put some sort of key object in each snippet that would identify which piece of JS to call or could be used as a parameter to pass to the JS or the JS could just examine the snippet to see which objects were available and hook up to whichever ones were present.

如果真的不需要通用的独立系统,因为只有几个片段要加载,并且处理它们的代码可以预先包含在页面中,那么我可能只是在 HTML 片段之后进行函数调用通过 ajax 加载,让 javascript 连接到刚刚加载的代码段中的链接。这将保持 HTML 和 JS 之间的完全分离,但非常容易实现。您可以在每个片段中放置某种关键对象,以识别要调用的 JS 片段,或者可以用作传递给 JS 的参数,或者 JS 可以只检查片段以查看哪些对象可用并连接到无论谁在场。

回答by Keith

Modern browsers support a Content Security Policyor CSP. This is the highest level of web security and strongly recommended if you can apply it because it completely blocks all XSS attacks.

现代浏览器支持内容安全策略或 CSP。这是最高级别的 Web 安全性,如果您可以应用它,强烈建议您使用它,因为它可以完全阻止所有XSS 攻击

The way that CSP does this is disabling all the vectors where a user could inject Javascript into a page - in your question that is both options 1 and 2 (especially 1).

CSP 执行此操作的方式是禁用用户可以将 Javascript 注入页面的所有向量 - 在您的问题中,这既是选项 1 又是选项 2(尤其是选项 1)。

For this reason best practice is always option 3, as any other option will break if CSP is enabled.

出于这个原因,最佳实践始终是选项 3,因为如果启用 CSP,任何其他选项都会中断。

回答by Brad Christie

I'm a firm believer of separating javascript from markup. There should be a distinct difference, IMHO, between what is for display purposes and what is for execution purposes. With that said, avoid using onclickattribute and embedding javascript:*in a hrefattribute.

我坚信将 javascript 与标记分开。恕我直言,用于显示目的和用于执行目的之间应该有明显的区别。随着中说,避免使用onclick属性和嵌入javascript:*href属性。

Alternatives?

备择方案?

  1. You can include javascript library files using AJAX.
  2. You can setup javascript to look for changes in the DOM (i.e. if it's a "standard task", make the anchor use a CSS class name that can be used to bind a specific mechanism when it's later added dynamically. (jQuery does a great job at this with .delegate()))
  3. Run your scripts POST-AJAX call. (Bring in the new content, then use javascript to [re]bind the functionality) e.g.:
  1. 您可以使用 AJAX 包含 javascript 库文件。
  2. 您可以设置 javascript 以查找 DOM 中的更改(即,如果它是“标准任务”,则使锚点使用 CSS 类名,该类名可用于在稍后动态添加时绑定特定机制。(jQuery 做得很好)在这与.delegate()))
  3. 运行脚本 POST-AJAX 调用。(引入新内容,然后使用 javascript [重新]绑定功能)例如:

function ajaxCallback(content){
  // add content to dom
  // search within newly added content for elements that need binding
}

回答by Dennis

Number 3 is not "out" if you want to load via AJAX.

如果您想通过 AJAX 加载,则数字 3 不是“out”。

var link = document.createElement("a");
//Add attributes (href, text, etc...)
link.onclick = function () { //This has to be a function, not a string
    //Handle the click
    return false; //to prevent following the link
};
parent.appendChild(link); //Add it to the DOM