【问题标题】:Override default behaviour for link ('a') objects in Javascript覆盖 Javascript 中链接 ('a') 对象的默认行为
【发布时间】:2018-09-30 10:35:02
【问题描述】:

我不知道我想要完成的事情是否可行。我想覆盖给定 HTML 页面的所有锚对象(A 标记)的默认行为。我知道我可以遍历所有A 元素,并从body 元素onload 方法中动态地为每个元素添加onclick 调用,但我正在寻找更绝对的解决方案。我需要的是为所有A 元素分配一个onclick 操作,该操作调用一个将元素href 属性作为参数传递的方法,因此如下:

<a href="http://domain.tld/page.html">

动态变为:

<a href="http://domain.tld/page.html" onclick="someMethodName('http://domain.tld/page.html'); return false;">

就像我说的那样,理想的方法是在文档加载时以某种方式完全覆盖 Anchor 类。如果不可能,那么我将求助于循环所有 A 元素方法(我已经知道该怎么做)。

【问题讨论】:

  • 好吧,有了事件委托,他们并不都需要将事件附加到他们身上。例如,参见 jQuery 中的“Live”。或者阅读 JavaScript 事件委托。
  • 通常这应该在 HTML 到达客户端之前完成。如果您的页面很复杂,您可能会遇到很多带有事件委托的程序。
  • 实际上,对于“点击”事件,我希望委派问题更少。像跟踪鼠标这样的事情会杀了你。
  • 看看这个关于 jQuery 的“Live”...zachleat.com/web/2009/05/08/…

标签: javascript dom overriding anchor


【解决方案1】:

如果您不想遍历所有锚元素,可以简单地使用event delegation,例如:

document.onclick = function (e) {
  e = e ||  window.event;
  var element = e.target || e.srcElement;

  if (element.tagName == 'A') {
    someFunction(element.href);
    return false; // prevent default action and stop event propagation
  }
};

查看上面的例子here

【讨论】:

  • 问题明确提到不迭代锚元素。
  • @Benji XVI:此方法的优点之一是如果在此事件绑定后以编程方式添加更多锚元素(即:使用 Ajax 加载的内容),它将继续为那些新的锚点。
  • 像往常一样,最好的答案是“视情况而定”。如果您有很多很多项目,并且都打算运行基本相同的代码,那么委托非常好。如果您要进入 switch 语句并为每个 id 列出不同的事情要做,那就太糟糕了。
  • CMS:谢谢,您的方法非常有效,它又短又甜,就像您在其中一个 cmets 中所说的那样,它实现了应用于所有“A”元素的目的,而不仅仅是那些最初呈现页面时的页面 - 这样做的目的是允许通过 AJAX 加载的内容中的新“A”标签继续工作。干得好!
【解决方案2】:

使用 jQuery:

$(function() {
    $("a").click(function() {
        return someMethodName($(this).attr('href'));
    });
});

function someMethodName(href)
{
    console.log(href);
    return false;
}

【讨论】:

    【解决方案3】:

    没有办法覆盖所有的锚元素 onlick 事件。您可以将 onclick 添加到文档正文并具有逻辑来查看是否从锚元素向上传播,并在这种情况下执行事件,但如果您的页面很复杂并且不传播点击,此解决方案可能会导致问题在某些情况下。

    如果可行,我会坚持使用 getElementsByTagName 解决方案。

    【讨论】:

      【解决方案4】:

      类似于 Benji XVI 的回答,但使用 querySelectorAll,例如在具有类“容器”的容器 div 中并使用 es6。

      const $elems = document.querySelectorAll('.container a')
      var elems = Array.from($elems)
      elems.map(a => {
        a.onclick = (e) => {
          e.preventDefault()
          window.alert('Clicking external links is disabled')
        }
      })
      

      【讨论】:

        【解决方案5】:

        CMS 的解决方案是最好的解决方案。请务必注意,如果您引用函数或检查需要从存储在基锚/元素上设置的原型属性中的字符串或以声明方式在锚/元素上运行的字符串,则可以获得更好的性能。通过使用此属性,可以找到并从一个决策分支调用您要调用的函数,而不是为每种可能性编写一个新的决策分支。如果您打破或使用包含超过一两个案例的案例语句,您应该开始考虑这一点,今天可能是发现控制反转和注入编码风格的好日子。

        同样,如果您需要处理多个事件,请不要使用 case。改用字符串组合来构造需要调用的函数的路径。这需要将原型添加到定义默认值和要组合的字符串的“A”元素中。元素上的数据属性应该能够覆盖默认值。本质上,我们只希望默认情况下传递消息和操作,并在标记中以声明方式进行更改。指定的操作应作为 API 或其他可访问的库函数在某处发布,并可由 lib['funName'] 调用。只需给它一个属性,不用担心名称或 id。原型和属性对去抖动很有用,因为你必须去抖动。

        有些人正在开发客户端路由器,试图完善这一点。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-03-10
          • 2023-03-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-08-03
          • 1970-01-01
          相关资源
          最近更新 更多