html文档中怎么区分节点对象节点类型,DOM(文档对象模型)的12个节点类型

当浏览器载入HTML的时候 会生成相应的DOM树。这个树自然有很多节点 。这些节点虽然都继承Node类型,但是这些节点可能分属于不同的子节点类型。

首先我们看一下Node类,此类为基类。

因此 这个类的方法和属性会被所有的节点共同继承。

属性:

int nodeType//doc 9, element 1, text 3

boolean DOCUMENT_NODE

nodeName 对于元素节点 nodeName就是标签名 对于文本节点 nodeName为”#text”(chrome里面测试的)

nodeValue  对于元素节点nodeValue就是null, 对于文本节点 nodeValue就是实际的值

NodeList<> childNodes: 每个节点还有childNodes属性,这是个十分重要的属性,它保存了这个节点所有直接子元素。调用childNodes返回的是一个NodeList对象,它极其像数组,但是有一个最关键的地方,它是动态查询的,也就是说每次调用它都会对DOM结构查询,所以对它的使用需要慎重,注意性能。访问childNodes可以使用数组下表或者item方法。

hasChildNodes() //如果包含子节点就返回true,比查询childNodes的length来的简单。

ownerDocument //返回文档节点的引用(在html里面也就是document对象)

appendChild()方法 //可以在节点的childNodes的末尾增加一个节点,值得注意的是如果这个节点是已经存在在文档中的,那么便会删除原节点,感觉上就像是移动节点一样。

insertBefore()方法 //接受两个参数,一个是插入的节点,另外一个是参照的节点。如果第二个参数为null,则insertBefore和appendChild效果一样。否则便会把节点插入到参照节点之前。这里要注意的是,如果第二个参数不为null,那么插入的节点不能是已经存在的节点。

replaceChild() //方法可以替换节点,接受两个参数,需要插入的节点和需要替换的节点。返回被替换掉的节点。

removeChild() //移除节点。这里有个常见需求,比如我有一个节点 #waste-node ,那么如何移除它呢?

var wasteNode = document.getElementById("waste-node");

wasteNode.parentNode.removeClhid(wasteNode); // 先拿到父节点,再调用removeClild删除自己

parentNode: //找到父节点

cloneNode(); //复制节点,接受一个参数 true或者false。如果true就是复制那个节点和它的子节点。如果是false,就是复制节点本身(复制出来的节点就会没有任何子元素)。这个方法返回复制的节点,如果需要操作它,那么需要借助前面讲的4个方法来把这个节点放入到html中去。

然后讲一下比较重要的一些子类:

Document类型:

属性:

document.childNodes 继承自上面讲的Node类型,可以返回文档的直接子节点(通常包括文档声明和html节点)

document.documentElement 可以直接拿到html节点的引用(等价于document.getElementsByTagName(“html”)[0])。

document.body body节点的引用

document.title 页面的title,可以修改,会改变浏览器标签上的名字

document.URL 页面的url

document.referrer 取得referrer,也就是打开这个页面的那个页面的地址,做来源统计时候比较有用

document.domain 取得域名,可以设置,但是通常只能设置为不包含子域名的情况,在一些子域名跨域情况下有效。

方法:

getElementById: 传入id,得到元素节点。里面的参数区分大小写(IE8-不区分)。注意:如果有多个id相同的元素,则返回第一个。IE7-里面表单元素的name也会被当做id来使用。

getElementsByTagName: 根据标签取得元素,得到的是HTMLCollection类型。如果传入的是 “*” ,则可以取得全部元素。

write() writeln() open() close(): open和close分别是打开和关闭网页的输出流,在页面加载过程中,就相当于open状态。这两个方法一般不会去用它。然后重要的方法就是write和writeln,它们都是向页面写入东西,区别就是后者会多加入一个换行符。

注意的是:在页面加载的过程中,可以使用这两个方法向页面添加内容。如果页面已经加载完了,再调用write,会重写整个页面。

还有一点,如果要动态写入脚本 例如 分开来拼装下,否则会被误以为是脚本结束的标志,导致这个结束符匹配到上面一个开始符。可以这样写"”;

Element类:

这个类型可以说是相当重要:

我们日常所操作的都是Element类型(实质是HTMLElement,这里为了方便理解,就简单这么说),比如document.getElementById("test")返回的就是Element类型。

属性:

String tagName

Element类还有一种子类 叫HTMLElement类型,是HTML元素的实际类型。这个类型有一些标准属性,比如:id, title, className (这三个类型是可读写的) ,此外 还有几个重要的方法:getAttribute, setAttribute, removeAttribute(这三个方法是我们常用来取自己自定义的属性,预定义的属性我们可以直接取用).此外还有一个属性 叫做attributes(保存了元素的全部属性)。

那么 如何创建元素并且初始化其属性呢?用下面的操作:

document.createElement("div");

//之后为元素设置属性:两种方法:直接node.property或者node.setAttribute("propertyName","value")

//但是做完这些之后,这个元素还是没有在页面中,所以你还得通过最上面讲的类似appendChild这些方法把元素添加到页面里面。

Text类:

这个类型也非常常见

简单的来说 这个就是一段字符串。而且一个很重要的特征就是 这种类型的节点没有子节点。

访问这个节点的内容 可以通过nodeValue或者data属性。

此外 还有

appendData()用于在末尾添加内容

deleteData(offset, count) //在Index==offset起删除count个字符。

还有insertDate、replaceData、splitText等方法,就不一一说了,用的机会很少,可以用的时候再查阅。

length:返回字符串长度

创建文本节点的方法是document.createTextNode.

Comment类

注释节点

DocumentType类

docttype节点,通过document.doctype来访问

DocumentFragment类

此节点是一个文档片段 偶尔会用到。使用场景:

比如一种常见的用法是,在一个ul中插入3个li。如果你循环插入3次,那么浏览器就要渲染3次,对性能有蛮大的影响。所以大家一般这么做。先var fragment = document.createDocumentFragment();然后循环把li,用appendChild插入到fragment里面。 最后在一次把fragment插入到ul里面。这样就会很快。

最后要说明一下一些问题:

1 浏览器为了方便开发者 扩展了一些DOM功能。我们在使用的时候要注意兼容性的问题。

我们利用document.compatMode和document.documentMode来判断当前模式是标准模式还是混杂模式。

2 上面不是说了一个文本节点作为第一子元素的坑吗,所以浏览器又实现了一个children属性,这个属性只包含元素节点。为了方便判断A节点是不是B节点的子节点,引入了contains方法,比如B.contains(A); // true就代表是,false就代表不是

3 针对访问元素,有四个额外方法可以供使用:innerText/innerHTML/outerTEXT/outerHTML。其中,而outer*则是代表是否包含元素本身。*TEXT是返回文本内容 *HTML是返回html文本。实际使用来看,在读内容的时候 inner和outer没有区别。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您解释一下HTML解析器的基本原理。HTML解析器的主要任务是将HTML文档解析为文档对象模型DOM),这是一个树形结构,其每个节点代表HTML元素或文本节点。在实现HTML解析器时,通常会分为两个主要步骤: 1. 词法分析(Lexical Analysis):将HTML文档的字符序列分解为符号(Tokens)。符号是HTML的最小单元,通常由一个标签、一个属性或者一段文本组成。符号的类型可以是标签起始、标签结束、标签自闭合、属性名、属性值或文本等。 2. 语法分析(Syntax Analysis):将符号序列转化为DOM树。在语法分析,需要识别标签、属性和文本等元素,并将它们组织成DOM树的节点。在构建DOM树时,需要注意标签的嵌套关系和属性的赋值关系。 下面是一个简单的HTML解析器的代码示例,它可以解析HTML的标签、属性和文本等元素: ```python # 定义符号类型 class TokenType: TAG_START = 1 TAG_END = 2 TAG_SELF_CLOSE = 3 ATTR_NAME = 4 ATTR_VALUE = 5 TEXT = 6 # 定义符号类 class Token: def __init__(self, type, value): self.type = type self.value = value # 定义HTML解析器类 class HTMLParser: def __init__(self, html): self.html = html self.pos = 0 self.tokens = [] # 获取下一个符号 def next_token(self): if self.pos >= len(self.html): return None # 判断当前符号类型 if self.html[self.pos] == '<': if self.html[self.pos + 1] == '/': self.pos += 2 end_pos = self.html.find('>', self.pos) tag_name = self.html[self.pos:end_pos] self.pos = end_pos + 1 return Token(TokenType.TAG_END, tag_name) else: self.pos += 1 end_pos = self.html.find('>', self.pos) if self.html[end_pos - 1] == '/': tag_name = self.html[self.pos:end_pos - 1] self.pos = end_pos + 1 return Token(TokenType.TAG_SELF_CLOSE, tag_name) else: tag_name = self.html[self.pos:end_pos] self.pos = end_pos + 1 return Token(TokenType.TAG_START, tag_name) else: end_pos = self.html.find('<', self.pos) text = self.html[self.pos:end_pos] self.pos = end_pos return Token(TokenType.TEXT, text) # 解析HTML文档 def parse(self): while True: token = self.next_token() if token is None: break if token.type == TokenType.TEXT: self.tokens.append(token) elif token.type == TokenType.TAG_START: tag_name = token.value attrs = {} while True: attr_name_token = self.next_token() if attr_name_token.type == TokenType.TAG_END: break attr_name = attr_name_token.value attr_value_token = self.next_token() if attr_value_token.type == TokenType.ATTR_VALUE: attrs[attr_name] = attr_value_token.value self.tokens.append((tag_name, attrs)) elif token.type == TokenType.TAG_END: tag_name = token.value self.tokens.append((tag_name, None)) elif token.type == TokenType.TAG_SELF_CLOSE: tag_name = token.value self.tokens.append((tag_name, {})) return self.tokens ``` 使用该HTML解析器,您可以将HTML字符串解析为DOM树,并对其进行操作。例如,您可以使用以下代码将DOM树转换为JSON格式: ```python # 将DOM树转换为JSON格式 def to_json(node): if isinstance(node, str): return node elif isinstance(node, tuple): tag_name = node[0] attrs = node[1] children = node[2:] return { 'tag': tag_name, 'attrs': attrs, 'children': [to_json(child) for child in children] } # 解析HTML文档,并将DOM树转换为JSON格式 parser = HTMLParser('<html><head><title>Hello, World!</title></head><body><p>This is a paragraph</p></body></html>') tokens = parser.parse() dom_tree = ('html', None, ('head', None, ('title', None, 'Hello, World!')), ('body', None, ('p', None, 'This is a paragraph'))) json_tree = to_json(dom_tree) print(json_tree) ``` 输出结果如下: ```json { "tag": "html", "attrs": null, "children": [ { "tag": "head", "attrs": null, "children": [ { "tag": "title", "attrs": null, "children": [ "Hello, World!" ] } ] }, { "tag": "body", "attrs": null, "children": [ { "tag": "p", "attrs": null, "children": [ "This is a paragraph" ] } ] } ] } ``` 这样,您就可以使用HTML解析器将HTML字符串解析为DOM树,并对其进行操作了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值