那些年 HTML 中的灵异事件

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

最近在看 Angular 官方文档时看到了 Html 的 attribute 与 DOM 的 property,一下子解惑了许久以前困扰过我的一些问题,那些年以为的 HTML 灵异事件,原来是这样子的。

一、看不懂的操作

写一个 test.html 页面,代码如下:


    
    
        
        
    

灵异事件 1

在浏览器中打开,顺便打开控制台,在控制台中输入如下代码:

1 document.getElementsByTagName('input')[0].value = 21
2 21
3 document.getElementsByTagName('input')[0].getAttribute('value')
4 "12"

可以看到在第 1 行代码执行完成后页面中文本框已经变成了 21,第 2 行也打印了 21,但是第 3 行获取文本框 value 属性时发现打印出来的竟然还是 12,这就不免有些奇怪了。

此时在控制台的 Elements 选项卡里看页面 html 源码,可以看到 input 框里的 value 值依然是 12,但是页面中文本框的值命名是 21??

灵异事件 2

打开页面看到页面中按钮为禁用状态,这是因为设置了 disabled = "true" 的原因。(这里不管值为什么,都会禁用按钮,可以试试 "false" 或者空字符串 "")

1 document.getElementsByTagName('button')[0].getAttribute('disabled')
2 "true"
3 document.getElementsByTagName('button')[0].disabled
4 true
5
6 document.getElementsByTagName('button')[0].setAttribute('disabled', false)
7 undefined
8 document.getElementsByTagName('button')[0].getAttribute('disabled')
9 "false"
10 document.getElementsByTagName('button')[0].disabled = false
11 false
12 document.getElementsByTagName('button')[0].disabled
13 false

上述操作可以看到第 1 3 行是获取 button 元素的 disabled 属性,结果一个打印的是字符串 "true" ,一个打印的是布尔值 true,为何有此区别呢???

第 6 行通过 setAttribute() 方法设置 disabled 属性为 false,第 7 行打印 disabled 属性,发现打印出来的是字符串 "false",查看 Elements 源码发现 button 元素变成了 但是此时页面中的按钮依然是禁用状态,按理说设置为 false 状态不应该是可用状态了吗???

第 10 行通过 disabled 属性设置 disabled 属性为 false,第 11 行打印 disabled 属性发现是布尔值 false,此时查看 Elements 源码发现 button 元素变成了 ,同时页面中按钮终于变成了可用状态。

上面三段话可以听起来有点绕口,但是业务中当我们想将一个按钮禁用时发现怎么也无法禁用那种灵异事件困扰时,静下心来弄懂为什么并不算吃亏。从上面可以看到,只有改变 disabled 的值为布尔值时才能有效的控制按钮是否禁用,打印出来的是字符串时并没有任何影响。

二、 HTML 的 Attribute 与 DOM 的 property

HTML 是页面语言,本身呈现树形结构,是静态的,在浏览器中可以渲染出我们看到的东东;

1. 概念介绍

// html 树形结构展示
|-- html
    |-- head
    |-- body
        |-- input
        |-- button

DOM 是另一种语言,可以看成是页面语言的辅助语言。DOM 也是树形结构,并且与 HTML 的树形结构一一对应,因为 HTML 是静态的,所以我们想要改变 HTML 中某个值时是没有办法的,DOM 的出现可以让我们改变 DOM 进而改变页面显示。

// DOM 树形结构展示
|-- html
    |-- head
    |-- body
        |-- input
        |-- button

在文字开始介绍的两种灵异事件中用到了两种方法,一种是 getAttribute()setAttribute() 方法,另一种是直接修改属性,如:xxx.value = 21xxx.disbaled = false

getAttribute()setAttribute() 是 HTML 中的两个方法,通过该方法设置的值会影响 HTML 树的变化,比如 document.getElementsByTagName('button')[0].setAttribute('disabled', false) 时可以看到控制台中 Elements 源码中的 disabled 属性确实变成了 'false'。HTML 树只是初始化时被浏览器渲染一次,显示一次页面,后面不管 HTML 树怎么变化,都不会影响页面中值的显示,这也就是为什么命名 disabled 设置为了 false 但是按钮依然是禁用的原因。

直接修改属性是 DOM 中 property 的行为。property 直接影响页面中值的变化,想要文本框中的值变成 21,就设置 document.getElementsByTagName('input')[0].value = 21,此时可以看到页面中文本框的值变成了 21,但是控制台 Elements 源码中 input 元素的 value 依然是 12。

2. 总结

HTML 中 attribute 只会改变源码,不会改变页面值显示,在第一次渲染页面时用到。

DOM 中 peroperty 不会改变源码,但会改变页面值显示。

现在,如果你想让解除按钮禁用状态,看到 document.getElementsByTagName('button')[0].setAttribute('disabled', false) 这种写法应该就会立马大叫出声:“it is stupid,attribute 是不会改变页面显示的,得用 property 去改变属性值才行”

转载于:https://my.oschina.net/dkvirus/blog/1541836

你可能感兴趣的:(那些年 HTML 中的灵异事件)