我正在使用Django渲染包含<a>
标签的html模板。我想将rel="noopener noreferrer nofollow"
添加到所有外部链接。现在,一种方法是在所有模板上手动执行此操作,或者引入一个自定义标签,其中包含检查url并将属性附加到锚标签的逻辑。当我们显示动态生成的URL链接(也可以是外部链接)时,就会出现问题。为了覆盖所有链接,有几种方法可以在客户端添加此属性。
我尝试获取所有锚点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);
这将从开始执行,但只会影响预渲染的锚标记。
另一种选择是创建一个全局事件侦听器,该事件侦听器侦听单击,然后检查单击了哪种元素。
document.addEventListener('click', function (event) {
var t = event.target;
if (t.nodeName !== 'A') {
return
}
...
})
两种方法都有缺点吗?
答案 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/
),但是这些路径不会到达外部站点。您的第二种方法会令人困惑,因为没有简单的方法知道该方法正在处理点击。如果您将事件监听器附加到文档中,那么我很容易感到困惑。浏览器已经在执行这项工作,计算点击的位置和点击的内容,因此请利用它!
您当然可以将整个事件包装在DOMContentLoaded
或pageshow
事件中:
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>