如何在 TypeScript 中获取ElementsByclassName?

Posted

技术标签:

【中文标题】如何在 TypeScript 中获取ElementsByclassName?【英文标题】:How to getElementsByclassName in TypeScript? 【发布时间】:2019-07-04 23:19:25 【问题描述】:

我正在尝试从 typescript 中的 DOM 中按类名获取元素。我在这里所做的似乎很简单,但控制台显示错误。

function showSlides() 
   var i;
   var slides = <htmlElement[]<any>document.getElementsByClassName('slide');

   for (i = 0; i < slides.length; i++) 
     slides[i].style.display = "none";
   

预期结果应该是一个包含 3 个项目的数组,并且应该将显示样式更改为 none,但实际结果是 JS 错误:Uncaught TypeError: Cannot read property 'style' of undefined.

【问题讨论】:

这不是 TS 错误。是JS。这只是表示某个索引处的slides[] 没有元素(值),因此它是undefined 并且您无法读取“无”的属性。 那么有什么办法可以解决这个问题呢?我试过 querySelectorAll,但它只适用于元素而不适用于类名。 当您记录slides 的值时会发生什么? 我不确定你为什么使用&lt;HTMLElement[]&lt;any&gt;getElementsByClass 已经返回了一个 HTML 元素数组。我已经使用您的代码示例创建了一个 Plunkr,我没有遇到问题 > plnkr.co/edit/f5XKghZz7aEQLKZdz2af?p=preview @PeterBoomsma 因为当我使用 document.getElementByClassName 时,我在代码中有一个错误:“元素”类型上不存在属性“样式”,我认为它是 TypesCript 的东西,这就是我需要的原因将其转换为 HtmlElement 【参考方案1】:

花了我一点时间。但我也为此苦苦挣扎。

const slides = Array.from(document.getElementsByClassName('slide'));

for (const x of slides) 
    const y = <HTMLElement> x;
    y.style.display = 'none';

这应该可行。

更多关于 for of 循环的信息 > https://www.typescriptlang.org/docs/handbook/iterators-and-generators.html

如果你使用 TS,你应该跳过 JS 循环遍历数组的方式,而使用 TypeScript 方式。

getElementsByClassName 返回一个元素数组。而且您不能在元素上使用样式。仅在 HTMLElement 上。因此,您必须将 Element 转换为 HTMLElement。如果将 getElementsByClassName 包含在 Array.from 中,它将返回一个 Element 数组。从那时起,您可以在 for 循环中遍历 Element 数组。然后将该 Element 数组中的每个对象转换为 HTML 元素数组,然后可以在该对象上使用 .style

有问题可以私信我。

【讨论】:

【参考方案2】:

document.getElementsByClassName 返回 HTMLCollectionElement 对象。

这些Elements could be one of a few different types、HTMLElementSVGElement 是两个常见的。

如果您确定循环遍历的所有元素都是 HTMLElements,那么您可以强制转换。

const showSlides = () => 
    const slides = document.getElementsByClassName('slide');

    for (let i = 0; i < slides.length; i++) 
        const slide = slides[i] as HTMLElement;
        slide.style.display = "none";
    
;

如果您有可能返回非HTMLElement 元素,那么您需要弄清楚如何测试它们。

一种方法可能是:

const showSlides = () => 
    const slides = document.getElementsByClassName('slide');

    for (let i = 0; i < slides.length; i++) 
        const slide = slides[i];

        if (slide instanceof HTMLElement) 
            // slide is a HTMLElement
            slide.style.display = "none";
         else if (slide instanceof SVGElement) 
            // slide is a SVGElement
            const svgOwner = slide.ownerSVGElement;
         else 
            // slide is a Element
            const baseUri = slide.baseURI;
        
    
;

【讨论】:

【参考方案3】:

style 属性仅存在于HTMLElement,但slides 是更广泛类型的集合:Element

为了安全地操作style,首先查看一个元素是否实际上是HTMLElement

function showSlides() 
  var i;
  var slides = document.getElementsByClassName('slide');

  for (i = 0; i < slides.length; i++) 
    const slide = slides[i];

    if (slide instanceof HTMLElement) 
      slide.style.display = "none";
    
  

【讨论】:

以上是关于如何在 TypeScript 中获取ElementsByclassName?的主要内容,如果未能解决你的问题,请参考以下文章

Typescript - 在字符串的开头和结尾删除多个字符/获取列表 JSON 元素的属性

React 中 JSX.Element 的 TypeScript 接口问题

如何使用第三方库提供的类型? (打字稿,Element-UI)

打字稿 + Vue + Element-ui

如何在TypeScript中手动触发Touch事件

JSDoc Typescript声明:如何隐藏“私有”方法