将rel =“ noopener noreferrer nofollow”添加到所有使用Vanilla JS的外部链接的最佳方法

时间:2019-10-03 13:13:08

标签: javascript

问题

我正在使用Django渲染包含<a>标签的html模板。我想将rel="noopener noreferrer nofollow"添加到所有外部链接。现在,一种方法是在所有模板上手动执行此操作,或者引入一个自定义标签,其中包含检查url并将属性附加到锚标签的逻辑。当我们显示动态生成的URL链接(也可以是外部链接)时,就会出现问题。为了覆盖所有链接,有几种方法可以在客户端添加此属性。

解决方案1 ​​

我尝试获取所有锚点DOM元素,并检查href是内部还是外部。如果在外部,请添加rel属性。

function setRelAttribute() {
    var elems = document.body.getElementsByTagName('a');
    for (var i = 0; i < elems.length; i++) {
        var elem = elems[i]
        var re = /mydomain.com/
        var isInternal = re.test(elem.href)
        if (!isInternal) {
            elem.rel= 'noopener noreferrer nofollow'
        }
    }
}

document.addEventListener('DOMContentLoaded', function () {
    setRelAttribute()
}, false);

这将从开始执行,但只会影响预渲染的锚标记。

解决方案2

另一种选择是创建一个全局事件侦听器,该事件侦听器侦听单击,然后检查单击了哪种元素。

document.addEventListener('click', function (event) {
    var t = event.target;
    if (t.nodeName !== 'A') {
        return
    }
    ...
})

两种方法都有缺点吗?

1 个答案:

答案 0 :(得分:0)

您最好只编写一个像这样的简单选择查询:

const anchors = document.querySelectorAll( 'a[href^="http"]:not([href*="example.com"])' )

这将选择所有以a开头的http元素(以免在本地选择相对路径)并且不包含example.com。然后简单地将其应用于所有对象:

anchors.forEach(anchor => anchor.setAttribute( 'rel', 'noopener noreferrer nofollow'));

您的第一种方法仍然选择本地路径(例如/images/),但是这些路径不会到达外部站点。您的第二种方法会令人困惑,因为没有简单的方法知道该方法正在处理点击。如果您将事件监听器附加到文档中,那么我很容易感到困惑。浏览器已经在执行这项工作,计算点击的位置和点击的内容,因此请利用它!

您当然可以将整个事件包装在DOMContentLoadedpageshow事件中:

document.addEventListener( 'DOMContentLoaded', event => {

    document.querySelectorAll( 'a[href^="http"]:not([href*="example.com"])' ).forEach(anchor => anchor.setAttribute( 'rel', 'noopener noreferrer nofollow' )); 

});

document.addEventListener( 'DOMContentLoaded', event => {
    
  document.querySelectorAll( 'a[href^="http"]:not([href*="example.com"])' ).forEach(anchor => { 
  
      anchor.setAttribute( 'rel', 'noopener noreferrer nofollow' );
      
  });

});
a { padding: 20px; }
a[rel]:after { content: ' (has [rel] attribute)'}
<a href="https://google.com/query">External</a>
<a href="/">Internal</a>
<a href="http://example.com/query">My Domain</a>