[英]TS2339: Property 'style' does not exist on type 'Element'
Here's the code:这是代码:
const test = Array.from(document.getElementsByClassName('mat-form-field-infix'));
test.forEach((element) => {
element.outerHTML = '<div class="good-day-today" style="width: 0px;"></div>'; // Please note that this line works fine!
element.style.padding = '10px';
element.style.borderTop = '0';
});
Error I get when compiled:编译时出现的错误:
ERROR in src/app/ / .component.ts(101,21): error TS2339: Property 'style' does not exist on type 'Element'. src/app/ / .component.ts(101,21) 中的错误:错误 TS2339:“元素”类型上不存在属性“样式”。 src/app/ / .component.ts(102,21): error TS2339: Property 'style' does not exist on type 'Element'. src/app/ / .component.ts(102,21):错误 TS2339:“元素”类型上不存在属性“样式”。
How can I fix it?我该如何解决?
I tried to remove the Array.from...
part, tried to use for of
and for in
, tried as any
, but above is the way I have to do it.我试图删除Array.from...
部分,尝试使用for of
和for in
,尝试as any
,但以上是我必须这样做的方式。
You need a typecast:你需要一个类型转换:
Array.from(document.getElementsByClassName('mat-form-field-infix') as HTMLCollectionOf<HTMLElement>)
That's because getElementsByClassName
only returns HTMLCollection<Element>
, and Element
does not have a style
property.这是因为getElementsByClassName
只返回HTMLCollection<Element>
,而Element
没有style
属性。 The HTMLElement
however does implement it via it's ElementCSSInlineStyle
extended interface.然而, HTMLElement
确实通过它的ElementCSSInlineStyle
扩展接口实现了它。
Note that this typecast is typesafe in the way that every Element
is either a HTMLElement
or an SVGElement
, and I hope that your SVG Elements don't have a class.请注意,这种类型转换是类型安全的,因为每个Element
都是HTMLElement
或SVGElement
,我希望您的SVG 元素没有 class。
Another option is to use querySelectorAll
and a type parameter.另一种选择是使用querySelectorAll
和类型参数。 getElementsByClassName
is not generic, but querySelectorAll
is - you can just pass the type of the elements that will be selected, like this: getElementsByClassName
不是通用的,但querySelectorAll
是 - 您可以只传递将被选择的元素的类型,如下所示:
const test = document.querySelectorAll<HTMLElement>('.mat-form-field-infix');
This doesn't require any type casting, and it will allow you to use forEach
immediately, rather than converting it to an array first.这不需要任何类型转换,它将允许您立即使用forEach
,而不是先将其转换为数组。 ( getElementsByClassName
returns an HTMLCollection, which does not have a forEach
method; querySelectorAll
returns a NodeList
, which does have a forEach
method, at least on somewhat up-to-date browsers. To support ancient browsers too, you'll need a polyfill , or convert it to an array first.) ( getElementsByClassName
返回一个 HTMLCollection,它没有forEach
方法; querySelectorAll
返回一个NodeList
,它确实有一个forEach
方法,至少在一些最新的浏览器上是这样。为了也支持古老的浏览器,你需要一个polyfill ,或先将其转换为数组。)
If you happen to just need a single element, you can use querySelector
, which is generic as well:如果您碰巧只需要一个元素,则可以使用querySelector
,它也是通用的:
const elm = document.querySelector<HTMLElement>('.foo')!;
elm.style.padding = '10px';
Another benefit of querySelectorAll
(and querySelector
) over the many other options is that they accept CSS selector strings, which can be far more flexible and precise. querySelectorAll
(和querySelector
)相对于许多其他选项的另一个好处是它们接受 CSS 选择器字符串,这可以更加灵活和精确。 For example, the selector string例如,选择器字符串
.container > input:checked
will select children of <div class="container">
which are <input>
s and are checked.将 select 的<div class="container">
的孩子是<input>
s 并被检查。
I was also facing a similar type of issue while doing我在做的时候也面临着类似的问题
document.querySelectorAll(".<className>");
so instead of adding the style property, I simply got around it by just adding another class.所以我没有添加样式属性,而是通过添加另一个 class 来解决它。
example:例子:
//css file
.<classname> {
display: none;
}
.<classname>.show {
display: flex;
}
//ts file
elements.forEach((ele, index) => {
const errors = something.length;
if (index < errors) {
ele.classList.add("show");
} else {
ele.classList.remove("show");
}
}); }); }; };
A workaround could be doing something like this:一种解决方法可能是这样做:
element["style"].padding = '10px';
element["style"].borderTop = '0';
Maybe it's not the best solution, but it should work, I used it multiple times:)也许这不是最好的解决方案,但它应该可以工作,我多次使用它:)
When you set the outerHTML, you're destroying the original element that was there.当您设置 outerHTML 时,您正在破坏那里的原始元素。 So, your styling doesn't work.所以,你的造型不起作用。
You'll notice that if you change it to set innerHTML, your styling does work.您会注意到,如果您将其更改为设置 innerHTML,您的样式确实有效。
This does not do the same exact thing, but I hope it points you in the right direction.这不会做同样的事情,但我希望它能为您指明正确的方向。
const test = Array.from(document.getElementsByClassName('mat-form-field-infix'));
test.forEach((element) => {
element.innerHTML = '<div class="good-day-today" style="width: 0px;"></div>'; // Please note that this line works fine!
element.style.padding = '10px';
element.style.borderTop = '0';
});
I think I found a way easier method:我想我找到了一种更简单的方法:
Just create an index.d.ts file and add:只需创建一个 index.d.ts 文件并添加:
interface Element {
style: CSSStyleDeclaration
}
Maybe this could help:也许这会有所帮助:
let element = <HTMLElement> document.getElementsByClassName(className)[0];
The answer from Jonas Wilms is not totally right (anymore?). Jonas Wilms 的回答并不完全正确(现在?)。
While I suspect that type casting will not cause any problems in this case, I would still avoid type casting whenever possible.虽然我怀疑在这种情况下类型转换不会导致任何问题,但我仍然会尽可能避免类型转换。 In this case, you can avoid type casting with instanceof narrowing :在这种情况下,您可以避免使用instanceof narrowing进行类型转换:
const test = Array.from(
document.getElementsByClassName('mat-form-field-infix')
)
test.forEach((element) => {
if (!(element instanceof HTMLElement)) {
return
}
element.outerHTML =
'<div class="good-day-today" style="width: 0px;"></div>' // Please note that this line works fine!
element.style.padding = '10px'
element.style.borderTop = '0'
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.