首页 > 解决方案 > 为什么 getAttribute('href') 与 reduce 一起使用时会返回完整的 URL?

问题描述

我有一个带有内部 ID 的锚点列表,我想使用以下命令选择所有目标.querySelectorAll()

const targets = document.querySelectorAll('#target-1, #target-2, …')

为了准备这个查询,我使用了reduce

anchors.reduce((previous, current, index) =>
    index === 0 ?
        current.getAttribute('href') :
        previous + ', ' + current.getAttribute('href')
)

这几乎可以工作,但有一个奇怪的问题,结果如下所示:

https://full-url.com/#target-1, #target-2, #target-3

当我只运行时:

targets[0].getAttribute('href')

…它返回预期的结果:

target-1

你可以自己试试:

const anchors = Array.from(document.querySelectorAll('a'));

console.log(anchors[0].getAttribute('href'));

console.log(anchors.reduce((previous, current, index) => index === 0 ? current.getAttribute('href') : previous + ', ' + current.getAttribute('href')));
<a href="#target-1"></a>
<a href="#target-2"></a>
<a href="#target-3"></a>


这至少发生在 macOS 上的 Chrome、Safari 和 Firefox 中。

为什么完整的 URL 会附加到第一个元素?

标签: javascripthtmlhref

解决方案


发生这种情况是因为reduce需要传递一个初始值。尝试传递空字符串:

const anchors = Array.from(document.querySelectorAll('a'));
const first = anchors[0].getAttribute('href');
const all = anchors.reduce((previous, current, index) => index === 0 ? current.getAttribute('href') : previous + ', ' + current.getAttribute('href'), "");

/* The first 'href' value. */
console.log(first);

/* All 'href' values. */
console.log(all);

/* When concatenating an <a> element with a string, a link is returned. */
console.log(anchors[0] + "");
<a href="#target-1"></a>
<a href="#target-2"></a>
<a href="#target-3"></a>

如果不传递初始值,则使用数组的第一个元素。由于您的数组中的元素是<a>元素,因此整个 URL 都在前面,因为当您将锚元素与字符串连接时,锚元素会被转换为实际链接(如此处所述)。


推荐阅读