- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试编写一个可在两个不同页面上使用的书签。一旦掌握了元素,我就可以成功地迭代和处理它们,但为了适应两个不同的页面,我想通过两个不同的类名编译 DIV 列表。我从这个开始:
traces=
[].concat.apply(document.getElementsByClassName('fullStacktrace'),
document.getElementsByClassName('msg'))
但在第一页上结果是这样的:
> traces=[].concat.apply(document.getElementsByClassName('fullStacktrace'),
document.getElementsByClassName('msg'))
[HTMLCollection[2]]
> traces[0]
[div.fullStacktrace, div.fullStacktrace]
> traces[1]
undefined
> traces[0][0]
<div class="fullStacktrace" style="height: auto;">…</div>
而在另一页
> traces=[].concat.apply(document.getElementsByClassName('fullStacktrace'),
document.getElementsByClassName('msg'))
[HTMLCollection[0], div#msg_2.msg.l1, ... div#msg_6460.msg.l1]
> traces[0]
[]
> traces[1]
<div class="msg l1" id="msg_2">…</div>
所以 getElementsByClassName 对两个页面都有效,但看起来 concat.apply 不会迭代其第一个参数,但会迭代其第二个参数?!
所以我尝试使用 concat 两次并全力以赴使用括号:
traces=(
(
[].concat.apply(document.getElementsByClassName('fullStacktrace'))
)
.concat.apply(document.getElementsByClassName('msg'))
)
但它变得更奇怪:第一页说:
Array[1]
> 0: HTMLCollection[0]
length: 0
> __proto__: HTMLCollection
length: 1
> __proto__: Array[0]
另一个:
Array[1]
> 0: HTMLCollection[283] // Lots of div#msg_3.msg.l1 sort of things in here
length: 1
>__proto__: Array[0]
获取其完整的 div 补集。
由于两组元素仅在一个或另一个页面上,因此我可以在特定情况下使用条件,但上面的行为对我来说非常令人惊讶,所以我想理解它。有什么想法吗?
仅供引用,这是 Mac Chrome 版本 56.0.2924.87(64 位)
最佳答案
要使用 concat,集合需要是数组参数。任何其他争论都不会平息。您可以使用 .slice()
来实现:
traces= [].concat([].slice.call(document.getElementsByClassName('fullStacktrace')),
[].slice.call(document.getElementsByClassName('msg')))
现代语法会让它变得更好一些。这使用“spread”语法创建一个新数组,并将两个集合的内容分布到其中:
traces = [...document.getElementsByClassName('fullStacktrace'),
...document.getElementsByClassName('msg')]
或者使用更容易填充的东西,您可以使用 Array.from() 来转换集合:
traces = Array.from(document.getElementsByClassName('fullStacktrace'))
.concat(Array.from(document.getElementsByClassName('msg'))))
总的来说,我一开始就不会使用getElementsByClassName
。我会使用.querySelectorAll
。您将获得更好的浏览器支持和更强大的选择功能:
traces = document.querySelectorAll('.fullStacktrace, .msg')
这使用了与CSS相同的选择器,因此上面的选择器实际上传递了一组两个选择器,每个选择器选择具有各自类的元素。
详细说明
第一个示例:
我对上述问题的解释太简洁了。这是您的第一次尝试:
traces = [].concat.apply(document.getElementsByClassName('fullStacktrace'),
document.getElementsByClassName('msg'))
.concat() 的工作方式是采用任何给定的值作为其 this
值及其参数,并将它们组合成一个数组。但是,当 this
值或任何参数是实际的 Array
时,它会将其内容平铺到结果中。因为 HTMLCollection
不是数组,所以它被视为只是要添加的任何其他值,而不是被展平。
.apply()
允许您设置被调用方法的 this
值,然后将其第二个参数的成员作为单独的参数传播给该方法。因此,在上面的示例中,作为第一个参数传递给 .apply()
的 HTMLCollection
不会被展平到结果中,但作为第二个参数传递给 .apply()
会这样做,因为是 .apply()
进行传播,而不是 .concat()
。从 .concat()
的 Angular 来看,第二个 DOM 选择从未存在过;它只看到具有 msg
类的单个 DOM 元素。
第二个示例:
traces=(
(
[].concat.apply(document.getElementsByClassName('fullStacktrace'))
)
.concat.apply(document.getElementsByClassName('msg'))
)
这有点不同。这部分 [].concat.apply(document.getElementsByClassName('fullStacktrace'))
遇到与第一个示例相同的问题,但您注意到 HTMLCollection
没有t 最终得到结果。原因是当您将 .apply.concat(...
链接到末尾时,您实际上放弃了该调用的结果。
举一个更简单的例子。当你这样做时:
[].concat.apply(["bar"], ["baz", "buz"])
...[]
实际上是一个浪费的数组。这只是访问 .concat()
方法的一个简短方法。在 .concat()
内,["bar"]
将是 this
值,"baz"
和"buz"
将作为单独的参数传递,因为 .apply()
再次将其第二个参数作为单独的参数传递给方法。
如果将简单的示例更改为这样,您可以更清楚地看到这一点:
["foo"].concat.apply(["bar"], ["baz", "buz"])
...请注意,"foo"
不在结果中。那是因为 .concat()
对此一无所知;它只知道 ["bar"]
、"baz"
和 "buz"
。
所以当你这样做时:
[].concat.apply(collection).concat.apply(collection)
你也做了同样的事情。第二个 .concat.apply
基本上会丢弃第一个集合,并仅继续处理提供给 .apply()
的数据,因此第一个集合不会出现。如果您没有在第二次调用中使用 .apply
,那么您最终会得到一个包含两个未展平 HTMLCollection
的数组。
[].concat.apply(collection).concat(collection)
// [HTMLCollection, HTMLCollection]
关于javascript - 如何在纯 Javascript 中连接 getElementsByClassName 的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42856863/
当我想检查 Explorer 是否存在 getElementsByClassName 时。我在代码下使用并且运行良好。 function getClass(obj) { if (document.
我正在尝试编写一个 PowerShell 脚本,以从网站上获取所有名为“newstitle”的类中的文本。 这就是我所拥有的: function check-krpano { $geturl=
我正在尝试在按钮单击时切换“覆盖”。在同一个类下添加这两个按钮并调用此函数后,JS 根本无法完成它。我不确定问题出在哪里: document.getElementsByClassName( 'trig
这个问题已经有答案了: Why does jQuery or a DOM method such as getElementById not find the element? (7 个回答) 已关闭
将尽力使其尽可能简洁。 使用 VB.Net 中的浏览器控件运行 Javascript 来循环浏览网页上的元素。 我已经让它大部分工作了,这将解决我过去几周的问题,我真的很感激这里的指点。 到目前为止:
我遇到了一个小问题,我想查询我的数据库,这样当用户使用自动完成功能时,我可以在名为 *Exist Act * 的另一列“td”上获取该产品的库存,现在好了使用这个新脚本,当我移出任何文本框时,它会更改
这个问题已经有答案了: Setting innerHTML vs. setting value with Javascript (8 个回答) 已关闭 6 年前。 我试图将日期附加到具有相同类的四个输
大家好,我想做这样的事情: function Div(data){ var A=document.getElementsByClassName('title')[data]; A.
我有一个网页爬虫,我正在使用 puppeteer 来爬行。我尝试使用 getElementsByClassName 获取 DOM 中的所有元素,但它返回了一个不稳定的集合。我期望收到一组 html 元
我有一个带有 TreeMap 片的网站,然后我使用 Ajax 删除该树并使用 javascript 插入数字。我用的是; document.getElementById("cut_oak_tree")
这个问题已经有答案了: Strange behavior when iterating over HTMLCollection from getElementsByClassName (3 个回答)
似乎每次都从闭包外部重新执行getElementsByClassName。 我可以通过将元素复制到数组中来解决这个问题,但我不知道是否有更好的方法。 这是一个代码示例: HTML
我用 VBA 抓取一些网站是为了好玩,我使用 VBA 作为工具。我使用 XMLHTTP 和 HTMLDocument(因为它比 internetExplorer.Application 更快)。 Pu
我一直在尝试使用以下指南进行简单的表单设置:https://www.w3schools.com/howto/howto_js_form_steps.asp. 我在表单内有三个带有 class="tab
我的代码不起作用,我不知道为什么。 var getElementsByClassName = function(className){ let result = []; let child =
我有一些元素属于“预览”类。我想让其中一个可以点击,所以首先我想通过 找出它在 HTML 集合中的索引号 console.log(document.getElementsByClassName("pr
我有一个问题,为什么我不想工作一段时间很累。我刚开始学js。非常感谢您的帮助
我正在使用 SnackJS API。我需要将一个事件附加到每个输入元素(文本框),类名称为“qty”。我无法为此使用 id 属性,因为它是动态生成的并且是唯一的,并且正在被其他东西使用: s
这个问题在这里已经有了答案: What do querySelectorAll and getElementsBy* methods return? (12 个答案) 关闭 8 年前。 我只想打印属
我想得到返回类名的长度 我想为一系列按钮添加事件监听器,它们都共享相同的类名。 removeButton = document.getElementsByClassName("removeButton
我是一名优秀的程序员,十分优秀!