美文网首页基础前端
JS 如何判断一个 DOM 是否存在于另一个 DOM 中

JS 如何判断一个 DOM 是否存在于另一个 DOM 中

作者: CondorHero | 来源:发表于2020-06-19 12:40 被阅读0次

    前言: 好长时间不写文章了,水也的水个几篇,最重要的是节奏不能打乱,闲个一两星期就会越变越懒,然后人就很焦虑,不会的想学却不深入,因为懒而浮于表面,还谈什么进步😂。

    一、问题出现场景

    无论是 Vue 还是 React 在我们在操作 DOM 的时候,一般会先 appendChild 上树再去 removeChild 下树。很完美没什么问题,但是我就遇见一个场景:有限滚动底部 loading 图,比如知乎的通知消息:

    往下面滚动的时候,可以看到一个骨架屏,其实就是 loading 图,滚动翻页发送请求是通过 intersectionObserve 技术来实现的。

    • 初次加载消息,appendChild loading图
    • 滚动到底部或关闭窗口移除 loading DOM。

    这时候要分两种场景:

    • 初始数据超过一屏,loading DOM 一上来就加到页面上,然后滚动加载,有可能有三页的数据但是我就滚动了一页,所以我点击其他地方关闭消息移除 DOM 正常。但是如果我滚动三页到底部,此时 loading 图应该被移除,OK 我们移除 loading 图的 DOM,但是当我们点击其他地方进行关闭的时候,就需要检测 loading DOM 是否存在了。

    • 上来数据就一条,因为之前想的是上来就 appendChild 进行 loading,现在肯定是不合时宜了,此处不应该出现 loading。此时应该移除 loading DOM,但是关闭窗口又要移除 DOM ,此时已经没有了。我们就的进行判断力,也就是 JS 如何判断一个 DOM 是否存在于另一个 DOM 中

    总结:1. 数据少,loading DOM 被提前移除,2. 滚动到底部,loading DOM 被提前移除。这两种情况会导致关闭消息弹框无法正确移除 DOM。

    解决办法:消息关闭的时候不移除 DOM,因为消息弹框是个组件,它会自己消亡,再次打开会重新加载。所以我们只需要滚动到底和数据不超过一屏移除 Loading DOM,而滚动不加载完全部数据就点击关闭,不需要移除 DOM,让 appendChild 更随组件自己消亡,不会出现重复创建的情况。

    杠一下:我非不要利用组件的特性,就要自己判断。

    二、contains 方法

    如果非要组件销毁自己手动移除自己创建的 DOM,就一个判断就 OK 了。只需要判断消息 DOM 中有 loading DOM 就移除,没有就不移除。

    看下 contains 的用法:

    parentNode.contains( childNode ) 
    parentNode 节点级别大于或等于 childNode 节点
    

    如果 childNode 是 parentNode 的后代节点或是 parentNode 节点本身,则返回 true ,,否则返回 false。

    看 👀 两个例子 🌰:

    级别:document.documentElement > document.body true
    document.documentElement.contains(document.documentElement)
    级别:document.documentElement == document.documentElement true
    document.documentElement.contains(document.body)
    

    说到这里我们可以想想可以有几种方法判断当前节点是否有子节点。

    • node.firstChild !== null
    • node.childNodes.length > 0
    • node.hasChildNodes()
    • node.children.length > 0

    前三个缺点非常致命就是我们想要检测的标签节点,只是众多节点中的一种,所以还是 children 靠谱,只会检测标签节点,虽然浏览器支持良好,但是 children 不是 W3C 的内容。

    相关文章

      网友评论

        本文标题:JS 如何判断一个 DOM 是否存在于另一个 DOM 中

        本文链接:https://www.haomeiwen.com/subject/fwfpxktx.html