TypeScript中使用getElementXXX()

如果只是看解决方法,可以直接跳到第二小节

简述

Angular 1.x版本是用JavaScript编写的,我们在百度Angular经常会搜索到AngularJS,并不是JavaScript的什么衍生版本,就是Angular 1.x。在后续版本中,改用TypeScript来重写了Angular框架。改动较大,所以做了个区分,Angular v1.x就叫AngularJS,v2及后续版本统称为Angular。

查资料和解决方案的时候,经常会搜索到大量的AngularJS内容,注意区分。

在这里提一下Angular的历史,是因为本文是在使用这个框架的时候遇到的,所以啰嗦两句。

问题来了

现在有如下html文件:

<!-- 这俩随便挑一个用就行 -->
<input type="text" id="infoInput" name="infoInput">
<textarea id="infoArea" name="infoArea" rows="8" cols="80"></textarea>

<!-- 这俩也随便挑一个用就行 -->
<span id="some">something happen!</span>
<p id="any">anything ok!</p>

我现在要通过TypeScript获取上面任意一个DOM元素,怎么做?有JS基础都知道,操作DOM可以通过document完成:

// 由于DOM元素的ID是惟一的,所以这种方式获取的是唯一的DOM元素
dom = document.getElementById('infoInput');

// name属性是不唯一的,所以这种方式获取的是所有 name=infoInput 的DOM元素,即一个数组
dom1 = document.getElementsByName('infoInput');

而在TypeScript中当然也可以这么做,但是在具体使用的时候除了需要声明变量保存获取到的DOM元素之外,还有一点小小的问题。

// Angular框架中
export class Some implements OnInit {
  ngOnInit() {
    let dom = document.getElementById('infoArea');
    // 1. 获取输入框中的内容
    let html = dom.innerHTML;
    let val = dom.value;

    // 2. 打印输出
    console.log(html);
    console.log(val);
  }
}

这段代码写完会报一个错:

Property ‘value‘ does not exist on type ‘HTMLElement‘
不要紧,即使有错误提示,我们依旧可以运行并得到正确的结果。如果想在ts文件编译失败时不生成js文件,可以通过配置实现。

HTMLElement是什么?这是一个对象,它包含了所有HTML元素公有的属性。

关于HTMLElement的详细内容以及浏览器的兼容,可以查看MDN的这篇文章

来看一张图:

图源自nanaistaken的博客

如果你恰好有一点面向对象编程的知识,那么这张图就很容易理解,没有也没关系,毕竟无论是js还是ts,现在都增加了class关键字,引入了类的思想。

经过上面的分析,我们能够知道:getElementXXX()返回的是一个HTMLElement对象,而这个对象包含了所有DOM元素的公有属性。而每种不同类别的DOM元素,又有自己的特性,也就是图中的子类。

ts会做编译检查,所以会有错误提示,而js则不检查,所以这也会留下安全隐患。

到这里,其实应该已经明白了现在这种情况该怎么解决以及以后该怎么使用getElementXXX函数了。

修改后的代码:

export class Some implements OnInit {
  ngOnInit() {
    // *. 做一次类型转换,或者做类型断言
    let dom = <HTMLInputElement>document.getElementById('infoArea');
    let dom1 = document.getElementById('infoArea') as HTMLElement;

    // 1. 获取输入框中的内容
    let html = dom.innerHTML;
    let val = dom.value;

    // 2. 打印输出
    console.log(html);
    console.log(val);
  }
}

总结

HTMLElement是DOM结点共有的属性,TypeScript库中抽取该属性作为一个公共接口,类似于其他面向对象语言如Java和c++中所说的基类。这样做可以保证在操作DOM结点的时候不会出现访问不存在属性的问题。

HTMLInputElement是HTMLElement的一个子接口(或说子类,但TypeScript是支持class的,所以说接口更好一些),其内部封装了如input,textarea这类dom结点的属性。

本文首发于个人博客,欢迎来撩^ - ^

原文地址:https://www.cnblogs.com/keepsmart/p/11504151.html

时间: 2024-10-10 20:12:39

TypeScript中使用getElementXXX()的相关文章

TypeScript 中的 this指向问题

TypeScript 中的 this指向问题 如果你接触过TypeScript有一段时间,那么你会发现很多并非语言设计当中的"特征".这些所谓的特征并非真正TypeScript的语法糖部分,也并非语言设计当中绝妙的点子.仔细研究TypeScript代码与编译后的 JavaScript 代码,你会发现,很多东西其实都是委曲求全的产物. 这篇文章里,我们仅来讨论关于TypeScript中 this 作用域的问题,你应该透过我的描述来了解如何去理解问题的思路. 我们来一段 TypeScrip

在TypeScript中扩展JavaScript基础对象的功能

最近工作中用到,记录一下:假设我们需要一个功能,把一个数字比如10000输出为下面的字符串格式“10,000”,一般是写一个方法,那么我希望更方便一点,直接向Number类型添加一个格式化方法,比如叫toFormat的方法来实现得到格式化后的字符串. 添加.d.ts定义 要在TypeScript中扩展一个基础对象的方法需要预先告知编译器有该方法才行: 1 interface Number { 2 toFormat(): string; 3 } 添加实现 具体实现根据需要编写即可,需要注意的是要添

Typescript中的装饰器原理

Typescript中的装饰器原理 1.小原理 因为react中的高阶组件本质上是个高阶函数的调用, 所以高阶组件的使用,我们既可以使用函数式方法调用,也可以使用装饰器. 也就是说,装饰器的本质就是一个高阶函数, 就是利用TypeScript的弱类型特性和装饰器特性,实现了一个加强版. 2.以一个例子来讲 //定义一个装饰器函数decTest function decTest(constructor: Function) { console.log(constructor("hello!&quo

解读typescript中 super关键字的用法

传统的js,使用prototype实现父.子类继承.如果父.子类有同名的方法,子类去调用父类的同名方法需要用 “父类.prototype.method.call(this)”.但是在typescript中,提供了一个关键字super,指向父类.super.method() 这样就可以达到调用父类同名的方法. class Animal { constructor() { console.log('animal') } get() { console.log("吃饭") } } class

typeScript中的数据类型

/* typeScript中的数据类型 typescript中为了使编写的代码更规范,更有利于维护,增加了类型校验,在typescript中主要给我们提供了以下数据类型 布尔类型(boolean) 数字类型(number) 字符串类型(string) 数组类型(array) 元组类型(tuple) 枚举类型(enum) 任意类型(any) null 和 undefined void类型 never类型 */ //布尔类型(boolean) /* es5的写法 (正确写法) ts中(错误写法) v

Typescript中的class interface 只是在声明,其实什么也没有干!

由于vue.js的特殊机制,初始化后给对象添加的属性是无法更新UI的. 最近结合typescript和vue进行web开发,就遇到了这样的坑. class user{ name:string; age:number; constructor(){ } } var v=new Vue(var v2 = new Vue({            el: '#app',            data: {               user:new user()            }}); 如

在TypeScript中使用其他JS框架或库的方法

最近刚刚接触TypeScript,感觉非常强大,但是也有一些问题. 比如我们正常写js时,只要把其他js库引入页面,甚至于只要加入到项目中,ReSharper就会自动分析他,并提供语法只能感知,写代码很舒服. 但是由于TypeScript是强类型语言,他不允许其他未知的js库在当前使用,因为没有办法做编译检测,所以如何在ts中使用其他js库就成了一个问题. 查了下有以下几种方法: 1.使用declare关键字 declare var $: any; declare var jQuery: any

【转载】在Angular 2/Typescript中声明全局变量的最佳方式是什么?

问题详细描述 我想在Typescript语言中的Angular 2中声明一些全局可见的变量.最佳的实践方法是? 推荐的实现方法 这是最简单的解决方案,无需使用Service或Observer: 将全局变量放在文件中然后导出它们. // // ===== File globals.ts // 'use strict'; export const sep='/'; export const version: string="22.2.2"; 要在另一个文件中使用这些全局变量,请使用impo

TypeScript 中的类和接口

在面向对象(OOP)编程中,经常会使用到class(类)和interface(接口).在TypeScript(以下简称TS)中也引入了类和接口的概念,使得TS强大的类型检测机制更加完善.就像我们所知道的,一个类是一堆抽象概念的集合,我们可以从类的构造方法中创建出享有共同属性和方法的对象.一个接口所描述的是一个对象相关的属性和方法,但并不提供具体创建此对象实例的方法. 我们的前端项目使用Angular2.0+作为技术栈,Angular2.0+基于TS实现,我们在对代码中某些部分添加类型注释的时,经