JS DOM API中有部分API功能是可以相互替代的,实际上,其是有细节差异的。
说明:本文的这些差异对比均不考虑兼容性差异。
一、innerText对比textContent
这个之前专门写文章介绍过,详见:“JS DOM innerText和textContent的区别”。
大致总结下就是:
innerText
获取的文字的换行符依然保留;innerText
无法获取隐藏文字;innerText
性能要相对差一些;
具体测试可以参见上面那篇文章,这里不再赘述。
二、getAttribute对比dataset对象
例如,有如下HTML:
<button id="button" data-author="zhangxinxu">作者是谁?</button>
使用getAttribute
和dataset
对象都能获取data-author
属性值,例如:
// 结果是:zhangxinxu
button.getAttribute('data-author');
// 结果也是:zhangxinxu
button.dataset.author;
如果您对dataset对象有些陌生,可以参考我差不多10年前写的这篇文章:“HTML5自定义属性对象Dataset简介”。
乍一看,在获取data-*
自定义属性的场景下,getAttribute
和dataset
对象似乎可以等同。
实际上,两者还是有差异的。
差别在于大小写敏感的区别,getAttribute
方法是无视大小写的,例如:
<button id="button" data-AUTHOR="zhangxinxu">作者是谁?</button>
// 结果是:zhangxinxu
button.getAttribute('DATA-author');
// 结果是:undefined
button.dataset.AUTHOR;
截图示意:
在本例中,要想dataset对象正确获取data-AUTHOR
属性值,需要使用小写:
// 结果是:zhangxinxu
button.dataset.author;
如果自定义属性包含多个词组,则dataset对象属性值需要使用驼峰命名获取,例如:
<button id="button" data-article-author="zhangxinxu">感谢阅读!</button>
// 结果都是:zhangxinxu
button.getAttribute('data-article-author');
button.dataset.articleAuthor;
且只能使用驼峰命名方法,例如下面的语句还是返回undefined
:
// 结果是:undefined
button.dataset['article-author'];
运行结果如下图所示:
三、getElementById对比querySelector
已知一个元素的ID是'thanksForShare'
,则下面两行DOM API的使用最后返回的结果是一样的:
// 结果是:true
document.getElementById('thanksForShare') === document.querySelector('#thanksForShare')
Chrome控制台跑一下,结果如下:
这么一看,对于通过ID选择器获取元素上,getElementById
和querySelector
方法似乎是等效的,究竟用哪个直接看心情就好了,是这样的吗?
实际上不是的,推荐使用getElementById()
方法,因为这个API的容错性最强,不容易导致JS运行中断。
假设某个元素的ID是未知的,通过参数传过来的,但是这个字符串参数可能各种各样,假设这个字符串是'thanksForShare!'
,此时分别运行下面的代码:
// 结果是?
document.getElementById('thanksForShare!');
document.querySelector('#thanksForShare!');
结果getElementById()
方法安全地返回了null
,但是querySelector()
方法直接报错了:
VM309:1 Uncaught DOMException: Failed to execute ‘querySelector’ on ‘Document’: ‘#thanksForShare!’ is not a valid selector.
眼见为实,特意run了下给大家看:
也就是说,在使用querySelector()
方法的时候,我们需要对里面的选择器进行合法性校验,或者try…catch处理,否则就会影响整个JavaScript代码的运行。
麻烦!
因此,如果条件可以,优先使用getElementById()
方法去获取DOM元素。
四、append对比appendChild
append()
API方法以前其实也介绍过,和很多API在一起介绍的,大家可能没注意,这里再讲下。
对于节点,append
和appendChild
功能基本是一致的。
例如:
let div = document.createElement('div');
div.content = '欢迎分享到你的朋友圈';
// 下面两行作用一样的
document.body.append(div);
// 等同于
document.body.appendChild(div);
都能在元素的后面添加DOM节点元素,包括文本节点,注释节点,元素等都可以。
区别在于下面:
append()
方法可以一次append多个元素,例如:dom.append(node1, node2, node3, ...)
appendChild
方法只能一次append一个元素。append()
方法还可以append
字符串(会自动HTML转义)。例如:document.body.append('
', '
');
最后页面上出现的不是图片,而是相关的转义后的HTML字符串,如下所示:
五、scrollIntoView对比scrollIntoViewIfNeeded
scrollIntoView
和scrollIntoViewIfNeeded
方法的区别主要2点:
- 行为上的区别
如果元素已经在视区了,则scrollIntoViewIfNeeded()
方法执行的时候,页面是不会滚动定位的。 语法上的区别
scrollIntoView()
支持设置滚动定位的时候是否是平滑滚动,参数是smooth,详见我的这篇文章“CSS scroll-behavior和JS scrollIntoView让页面滚动平滑”。scrollIntoViewIfNeeded()
的滚动定位只能是硬邦邦的效果。以及
scrollIntoView()
支持精准设置定位的元素是定位到视区的上方、下方还是中间,语法参数使用示意如下:element.scrollIntoView({
// 还支持start和end值 block: 'center', // 平滑滚动 behavior: 'smooth'
});
而
scrollIntoViewIfNeeded()
的定位位置就比较粗糙,无法精确,只支持一个Boolean参数值,true表示居中JS DOM API中有部分API功能是可以相互替代的,实际上,其是有细节差异的。
说明:本文的这些差异对比均不考虑兼容性差异。
一、innerText对比textContent
这个之前专门写文章介绍过,详见:“JS DOM innerText和textContent的区别”。
大致总结下就是:
innerText
获取的文字的换行符依然保留;innerText
无法获取隐藏文字;innerText
性能要相对差一些;
具体测试可以参见上面那篇文章,这里不再赘述。
二、getAttribute对比dataset对象
例如,有如下HTML:
<button id="button" data-author="zhangxinxu">作者是谁?</button>
使用getAttribute
和dataset
对象都能获取data-author
属性值,例如:
// 结果是:zhangxinxu
button.getAttribute('data-author');
// 结果也是:zhangxinxu
button.dataset.author;
如果您对dataset对象有些陌生,可以参考我差不多10年前写的这篇文章:“HTML5自定义属性对象Dataset简介”。
乍一看,在获取data-*
自定义属性的场景下,getAttribute
和dataset
对象似乎可以等同。
实际上,两者还是有差异的。
差别在于大小写敏感的区别,getAttribute
方法是无视大小写的,例如:
<button id="button" data-AUTHOR="zhangxinxu">作者是谁?</button>
// 结果是:zhangxinxu
button.getAttribute('DATA-author');
// 结果是:undefined
button.dataset.AUTHOR;
截图示意:
在本例中,要想dataset对象正确获取data-AUTHOR
属性值,需要使用小写:
// 结果是:zhangxinxu
button.dataset.author;
如果自定义属性包含多个词组,则dataset对象属性值需要使用驼峰命名获取,例如:
<button id="button" data-article-author="zhangxinxu">感谢阅读!</button>
// 结果都是:zhangxinxu
button.getAttribute('data-article-author');
button.dataset.articleAuthor;
且只能使用驼峰命名方法,例如下面的语句还是返回undefined
:
// 结果是:undefined
button.dataset['article-author'];
运行结果如下图所示:
三、getElementById对比querySelector
已知一个元素的ID是'thanksForShare'
,则下面两行DOM API的使用最后返回的结果是一样的:
// 结果是:true
document.getElementById('thanksForShare') === document.querySelector('#thanksForShare')
Chrome控制台跑一下,结果如下:
这么一看,对于通过ID选择器获取元素上,getElementById
和querySelector
方法似乎是等效的,究竟用哪个直接看心情就好了,是这样的吗?
实际上不是的,推荐使用getElementById()
方法,因为这个API的容错性最强,不容易导致JS运行中断。
假设某个元素的ID是未知的,通过参数传过来的,但是这个字符串参数可能各种各样,假设这个字符串是'thanksForShare!'
,此时分别运行下面的代码:
// 结果是?
document.getElementById('thanksForShare!');
document.querySelector('#thanksForShare!');
结果getElementById()
方法安全地返回了null
,但是querySelector()
方法直接报错了:
VM309:1 Uncaught DOMException: Failed to execute ‘querySelector’ on ‘Document’: ‘#thanksForShare!’ is not a valid selector.
眼见为实,特意run了下给大家看:
也就是说,在使用querySelector()
方法的时候,我们需要对里面的选择器进行合法性校验,或者try…catch处理,否则就会影响整个JavaScript代码的运行。
麻烦!
因此,如果条件可以,优先使用getElementById()
方法去获取DOM元素。
四、append对比appendChild
append()
API方法以前其实也介绍过,和很多API在一起介绍的,大家可能没注意,这里再讲下。
对于节点,append
和appendChild
功能基本是一致的。
例如:
let div = document.createElement('div');
div.content = '欢迎分享到你的朋友圈';
// 下面两行作用一样的
document.body.append(div);
// 等同于
document.body.appendChild(div);
都能在元素的后面添加DOM节点元素,包括文本节点,注释节点,元素等都可以。
区别在于下面:
append()
方法可以一次append多个元素,例如:dom.append(node1, node2, node3, ...)
appendChild
方法只能一次append一个元素。append()
方法还可以append
字符串(会自动HTML转义)。例如:document.body.append('
', '
');
最后页面上出现的不是图片,而是相关的转义后的HTML字符串,如下所示:
五、scrollIntoView对比scrollIntoViewIfNeeded
scrollIntoView
和scrollIntoViewIfNeeded
方法的区别主要2点:
- 行为上的区别
如果元素已经在视区了,则scrollIntoViewIfNeeded()
方法执行的时候,页面是不会滚动定位的。 语法上的区别
scrollIntoView()
支持设置滚动定位的时候是否是平滑滚动,参数是smooth,详见我的这篇文章“CSS scroll-behavior和JS scrollIntoView让页面滚动平滑”。scrollIntoViewIfNeeded()
的滚动定位只能是硬邦邦的效果。以及
scrollIntoView()
支持精准设置定位的元素是定位到视区的上方、下方还是中间,语法参数使用示意如下:element.scrollIntoView({
// 还支持start和end值 block: 'center', // 平滑滚动 behavior: 'smooth'
});
而
scrollIntoViewIfNeeded()
的定位位置就比较粗糙,无法精确,只支持一个Boolean参数值,true表示居中,false表示或上边缘或下边缘。// 视区居中定位
element.scrollIntoViewIfNeeded(true);
// 视区上边缘或下边缘滚动定位
element.scrollIntoViewIfNeeded(false);
大部分情况下,这两个方法是可以互相替换使用的。
六、结语
当然,还有很多其他功能可以互相替代,但是实际上有细节差异的DOM API,欢迎补充,我会及时更新。
感谢您的阅读,如果您觉得本文内容还不错,欢迎分享,让更多的小伙伴知道。
最后祝大家圣诞节快乐,马瑞亏瑞美思,笑口常开,^_^,false表示或上边缘或下边缘。
// 视区居中定位
element.scrollIntoViewIfNeeded(true);
// 视区上边缘或下边缘滚动定位
element.scrollIntoViewIfNeeded(false);
大部分情况下,这两个方法是可以互相替换使用的。
六、结语
当然,还有很多其他功能可以互相替代,但是实际上有细节差异的DOM API,欢迎补充,我会及时更新。
感谢您的阅读,如果您觉得本文内容还不错,欢迎分享,让更多的小伙伴知道。
最后祝大家圣诞节快乐,马瑞亏瑞美思,笑口常开,^_^
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。