我想遍历结果
document.getElementsByTagName("...");
它返回一个HTMLCollection
,而不是一个数组。因此,我不能简单地使用forEach
。
以下是可能的,但看起来不太好:
let elements = document.getElementsByTagName("...");
for (var i = 0, m = elements.length; i < m; i++) {
let element = elements[i];
}
对于javascript,几乎存在完全相同的问题: For loop for HTMLCollection elements
显然,有了最新更新,现代浏览器就支持:
var list = document.getElementsByClassName("events");
for (let item of list) {
log(item.id);
}
但是打字稿编译器抱怨:
error TS2495: Type 'NodeListOf<HTMLParagraphElement>' is not an array type or a string type.
尽管如此,它仍然可以转换为正确的Javascript。它甚至知道我在这里做什么,而不仅仅是复制源代码。编译后的输出是这样的:
var elements = main_div.getElementsByTagName("p");
for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
var element = elements_1[_i];
}
这很好,因为即使在较旧的浏览器上也支持生成的代码。但是我想摆脱错误消息。
我的编译器选项是:
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"sourceMap": true,
"rootDir": "src",
"lib": [
"es2015",
"dom"
]
}
}
我确实尝试编辑我的lib选项。此特定功能是ES6的一部分,并且已进行了多次重做。因此,我在lib中测试了各种ecmascript版本,但找不到有效的设置。
答案 0 :(得分:5)
如果要使用forEach,可以将其转换为数组
const elements: Element[] = Array.from(document.getElementsByTagName("..."));
elements.forEach((el: Element) => {
// do something
})
答案 1 :(得分:2)
要摆脱错误消息,您可以将列表添加为 任何 类型。 Typescript与JavaScript的区别在于 Type 。因此,最佳做法是将类型添加到变量中。供您参考,我添加了 any 类型:
var list: any = document.getElementsByClassName("events");
for (let item of list) {
console.log(item.id);
}
实际上,这是典型的“上下文键入”。当表达式的类型由其位置隐含时,便会发生上下文类型化。对于上面给出类型错误的代码,TypeScript类型检查器使用document.getElementsByClassName(“ events”)的类型来推断ForLoop函数的类型。如果此函数表达式不在上下文键入的位置,则 列表 的类型将为any,并且不会发出任何错误。
如果上下文类型化的表达式包含显式类型 信息,上下文类型将被忽略。
在许多情况下都适用上下文类型。常见的情况包括 函数调用的参数,赋值的右侧,类型 断言,对象和数组文字的成员,然后返回 陈述。上下文类型也最好充当候选类型 普通类型。[来自TypeScript文档]
答案 2 :(得分:2)
用法示例:
const inputs = document.getElementsByTagName("input");
for (let index = 0; index < inputs.length; index++) {
const input = inputs.item(index);
}
答案 3 :(得分:0)
这不应该在typecipt中给出错误,因为for in
也适用于objects
var list = document.getElementsByClassName("events");
for (let key in list) {
if(list.hasOwnProperty(key)) {
log(list[key].id);
}
}
通过for of
循环,您可以使用Object.keys()
var list = document.getElementsByClassName("events");
for (let key of Object.keys(list)) {
if(list.hasOwnProperty(key)) {
log(list[key].id);
}
}
答案 4 :(得分:0)
打字稿编译器在指定了额外的标记downlevelIteration
后支持此操作:
{
"compilerOptions": {
"target": "es5",
"downlevelIteration": true
}
}
但是,这不仅将消除错误,还将改变编译器的输出。 此输入打字稿:
function compileTest(){
let elements = document.getElementsByTagName("p");
for(let element of elements){
console.log(element);
}
}
已编译为此JavaScript:
function compileTest() {
var e_1, _a;
var elements = document.getElementsByTagName("p");
try {
for (var elements_1 = __values(elements), elements_1_1 = elements_1.next(); !elements_1_1.done; elements_1_1 = elements_1.next()) {
var element = elements_1_1.value;
console.log(element);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (elements_1_1 && !elements_1_1.done && (_a = elements_1.return)) _a.call(elements_1);
}
finally { if (e_1) throw e_1.error; }
}
}
答案 5 :(得分:0)
我知道这是一个很晚才回答的问题,但我认为在线程中使用它可能会很不错...在Angular项目中,我正在寻找一种使用数组解构的方法(喜欢HTMLCollectionOf<T>
的数组破坏amiright吗?),如下面的示例所示:
const [zoomControl] = document.getElementsByClassName('leaflet-control-zoom');
但是会得到错误:
“类型'HTMLCollectionOf'必须具有'Symbol.iterator' 返回iterator.ts(2488)'
的方法
此外,我还遇到了对集合进行迭代的很好的情况,例如:
const elementsWithClassName = document.getElementsByClassName('class-name');
for(const a of elementsWithClassName) {
console.log(a)
}
我发现添加了具有以下内容的global-types-extensions.d.ts文件:
declare global {
interface HTMLCollectionOf<T extends Element> {
[Symbol.iterator](): Iterator<T>;
}
}
export {};
...修复了我从TS中收到的错误/警告。
所以现在,我可以愉快地解决数组分解问题,并在任何for...of
??上使用HTMLCollectionOf
。