Element 和 Node的关系是个啥

640?wx_fmt=png

说起这个话题要从一个面试题开始,前两天一个朋友发给我的(某团面试题),这个题简单的很,但是估计很多人不能自信的说出结果和原因。

先看下题目

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
    .box{
        width: 400px;
        border:solid 1px #000;
    }
    img{
        width: 50%;
    }
    </style>
</head>
<body>
    <div class="box">

        <img src="../img/g.jpg"/>
        <img src="../img/g.jpg" />
        <img src="../img/g.jpg" />

    </div>
</body>
</html>

请说出上面代码的显示结果,然后说下原因。

emm.....

其实这个布局的最终目的是想让图片并排显示,但是这样写并不能达到我们想要的结果,还是从细节中考查我们对 DOM 的理解和应用。

问题分析

当然做题是次要的,我们来分析下原因。

先看下效果,下面这个结果应该和你想的差不多吧。

640?wx_fmt=png

这是什么原因呢?我们都知道 img标签默认是内联元素,除非剩余宽度不足才会换行,代码中我们都设置成为50%,宽度也没有超出呀。

这是因为html中标签后的每个换行也会被当做是一个节点,会进行渲染,也会占用空间,这个节点就是text节点,他不像标签那么形象,可以有具体的表示,他就是换行和空字符串的组合。

既然他是存在的,那我们使用 js 拿到这些节点。

document.getElementsByClassName('box')[0].children

上面的代码应该没什么问题,但是结果里没有我们所说的 text节点。

640?wx_fmt=png

请看下MDN 里这个方法的说明

ParentNode.children 是一个只读属性,返回 一个Node的子elements ,是一个动态更新的 HTMLCollection

也就是说children属性返回的是elements,然而 text node属于Node,所以没有返回。

所以我们需要使用另外一个方法得到

document.getElementsByClassName('box')[0].childNodes
640?wx_fmt=png

上面的结果的确得到了text node,但是同时也把 img返回了。

element 和 node 关系

可能你会问 elementnode到底什么区别呢?

一图胜千言

640?wx_fmt=png

从上图中可以很清晰的看到他们的关系,越往上越抽象,越往下越具体,从继承的角度来说Element继承自Node,具有node的方法,同时扩展了很多自己的独有的方法。

所以在Element的一些方法里,是明确区分了Node和Element的,比如说:childNodes, children, parentNode, parentElement等方法。

另外Node表示的是DOM树的结构,在html中,节点与节点之间是可以插入文本的,这个插入的空隙就是TEXT_NODE,也就是我们上题中的情景。

所以总结来说,我们可以把所有的element看作是 node,但是所有的 node 并不是 element

回到题中,我们让 text node显示出来。

给所有的 text node 设置文本

document.getElementsByClassName('box')[0].childNodes.forEach(item=>{
item.nodeType===3?item.appendData('text node'):null
})
640?wx_fmt=png

处理问题

说到这里,我觉得如何解决问题已经不重要了,如果能分析出来,自然就有了解决方法。

最直接的手段就是删除掉 text node。

    <div class="box"><img src="../img/g.jpg"/><img src="../img/g.jpg" /><img src="../img/g.jpg" /></div>

搞定!

但这可读性太差了,看着多别扭。

设置字号为0.font-size:0

最后也不一定能过

如果你的回答只说会换行显示,这个也不能说是100%对,因为还少说了一项。

这个空隙呢?

640?wx_fmt=png

很熟悉吧。

到这里可能面试官就会给过了。好难...ಥ_ಥ

参考

https://developer.mozilla.org/zh-CN/docs/Web/API/Node

https://developer.mozilla.org/zh-CN/docs/Web/API/Element

640?wx_fmt=png

动动小手,让更多人看到
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zz_jesse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值