【SSD系列】没了jquery, vue, react,你还会DOM节点的增删改查吗?

简介: 关于【SSD系列】:前端一些有意思的内容,旨在3-10分钟里, 500-1500字,有所获,又不为所累。

4.JPG


前言



关于【SSD系列】


前端一些有意思的内容,旨在3-10分钟里, 500-1500字,有所获,又不为所累。


先提问一波:(无框架前提下)


  • 常用查询节点方法有哪些
  • 什么是空白节点??她又到底是个什么东西
  • querySelectorAll 有哪些坑
  • 怎么查询伪元素
  • 四种删除节点方式你都知道吗
  • HTMLCollection 和 NodeList的区别
  • 怎样删除所有的孩子节点


我们已经先jquery, vue, react等前端框架带来的便利了:


  • jquery就不说了,一个$走天下,无限连。
  • vue和react使用ref就能拿到对应节点。


离开了这些框架,你还能666的操作Node节点吗?


本文源码


crud-doms


节点查询


先放一段测试的html代码


<div class="outer" id="outer">
    <ul class="list list-1">
      <li class="item">list-one</li>
      <li class="item">list-two</li>
      <li class="item">list-three</li>
    </ul>
  </div>
  <input type="button" name="btnSubmit" value="刷新"/>
复制代码


常用的节点查询方法


  1. getElementById
    根据元素的id属性值进行节点查询,返回单一节点。


document.getElementById("outer")  // <div class="outer" id="outer">......
复制代码


  1. getElementsByClassName
    根据元素的classname属性值就行查询。
document.getElementsByClassName("item") // HTMLCollection(3) [li.item, li.item, li.item]
复制代码


  1. getElementsByName
    根源节点的name属性进行查询。
document.getElementsByName("btnSubmit") // NodeList [input]
复制代码


  1. getElementsByTagName
    根据节点标签名进行查询。
document.getElementsByTagName("li") // HTMLCollection(3) [li.item, li.item, li.item]
复制代码


  1. querySelector
    根绝css选择器进行节点查询,返回单个节点。
document.querySelector("#outer") // <div class="outer" id="outer">......
复制代码


  1. querySelectorAll
    根绝css选择器进行节点查询,返回节点列表。
document.querySelectorAll(".item") // NodeList(3) [li.item, li.item, li.item]
复制代码


  1. 在没有querySelectorquerySelectorAll出现之前,基本都是通过前四个查询方法配合 childNodesparentNode方法扩展出各种方法。


一些特殊查询属性


  • document.all 返回所有的节点
  • document.images 返回所有的图片
  • document.forms 返回所有的form表单
  • document.links 返回所有的链接标签
  • document.embeds 返回所有的 object标签元素,以前主要用于flash,pdf等等


querySelectorAll 注意事项


  • 其返回的静态的NodeList, 随后对DOM元素的改动不会影响其集合的内容。
    下面的代码可以看到,添加一个节后后, nodeList长度并没有变化。


<ul class="list list-1">
    <li class="item">list-one</li>
    <li class="item">list-two</li>
    <li class="item">list-three</li>
  </ul>
  <script>
      var  nodeList = document.querySelectorAll(".item");
      console.log("len:", nodeList.length);  // 3
      var liEl = document.createElement("li");
      liEl.className = "item";
      liEl.innerHTML = "list-for"
      document.querySelector(".list").appendChild(liEl);
      console.log("len:", nodeList.length); //3 
  </script>
复制代码


  • querySelectorAll可能返回的不是你期望的值


<div class="outer">
  <div class="select">
    <div class="inner">
    </div>
  </div>
</div>
<script>
var select = document.querySelector('.select');
var inner = select.querySelectorAll('.outer .inner');
inner.length; // 1, not 0!
</script>
复制代码


  • 那么怎样才能返回期望的结果呢?答案是 :scope


var select = document.querySelector('.select');
var inner = select.querySelectorAll(':scope .outer .inner');
inner.length; // 0
复制代码



<div id="foo\bar"></div>
  <div id="foo:bar"></div>
  <script>
    console.log('#foo\bar')               // "#fooar"
    document.querySelector('#foo\bar')    // 不匹配任何元素
    console.log('#foo\\bar')              // "#foo\bar"
    console.log('#foo\\\\bar')            // "#foo\\bar"
    document.querySelector('#foo\\\\bar') // 匹配第一个div
    document.querySelector('#foo:bar')    // 不匹配任何元素
    document.querySelector('#foo\\:bar')  // 匹配第二个div
  </script>
复制代码


HTMLCollection 和 NodeList的区别


细心的通知可能发现了,上面的方法,有的返回的是HTMLCollection,有的返回的是NodeList。 他们有什么区别呢?


这里先要弄清晰继承关系:


HTMLElement -> Element -> Node-> EventTarget
复制代码


EventTarget 前一个提供了事件分发能力,本身也是一个订阅发布中心,更多详情参见 3行代码一个订阅发布中心,不会不知道吧


Node 有 12种节点类型,详情参见 NodeType,我们常用的 div, span等等属于nodeType=1的节点类型。


所以:

HTMLCollection 是元素节点类型,即nodeType为1的节点。

NodeList 是节点集合,包含文本节点,注释节点等等其他节点。


怎么查询伪元素


// html代码  
<style>
    .nihao::before{
      content: '你好,';
    }
  </style>
  <div class="nihao" id="nihao">
    Tom
  </div>
复制代码


答案是不能,但你可以通过 window.getComputedStyle 来获取其样式。


window.getComputedStyle(nihao, "before")["content"] // "\"你好,\""
复制代码


节点删除


先特出测试的html代码段


<ul class="list list-1">
    <li class="item">list-one</li>
    <li class="item">list-two</li>
    <li class="item">list-three</li>
  </ul> 
复制代码


Node.removeNode


这种我们用的最多的方法,前提是首先得获得要被删除元素的父节点,可以使用parentNode或者parentElement获得。


var ul = document.querySelector(".list");
    console.log("li length", ul.children.length);  // 3
    ul.removeChild(ul.children[0])  // removeChild
    console.log("li length", ul.children.length); // 2
复制代码


Element.remove


这个方法属于 Element对象上,也就表明,其他nodeType类型是不可以使用的, 其不需要获得副节点。


var ul = document.querySelector(".list");
    console.log("li length", ul.children.length);  // 3
    ul.children[0].remove();  // remove
    console.log("li length", ul.children.length); // 2
复制代码


outerHTML或者innerHTML


var ul = document.querySelector(".list");
    console.log("li length", ul.children.length);  // 3
    ul.children[0].outerHTML = null   // outerHTML
    console.log("li length", ul.children.length); // 2
复制代码


Document.adoptNode


从其他的document文档中获取一个节点。 该节点以及它的子树上的所有节点都会从原文档删除。


var ul = document.querySelector(".list");
console.log("li length", ul.children.length);  // 3
document.adoptNode(ul.children[0]); // adoptNode
console.log("li length", ul.children.length); // 2
复制代码


批量删除节点


批量删除,比如清除某个节点下的所有子节点,一般是使用while循环,暴力的方式是 innerHTML = null


innerHTML = null可能导致事件监听器没有被取消,以导致内存泄漏,具体有么有,还得看浏览器的实现。


我们封装一个吧:


function clearChildNodes(node){
    while(node.hasChildNodes()){
        node.removeChild(node.firstChild);
    }
}
const ul = document.querySelector(".list");
console.log("nodes:", ul.childNodes.length);  // 7
clearChildNodes(ul);   
console.log("nodes:", ul.childNodes.length);  // 0
复制代码


空白节点


为什么是7个节点呢? 看图上的空白节点,有4个, 4+3 =7楼。


1.JPG


我们调整一下代码, 删除空白,再看输出


<ul class="list list-1"><li class="item">list-one</li><li class="item">list-two</li><li class="item">list-three</li></ul>
复制代码

2.JPG


那空白节点,究竟是个什么东西??


看代码,其实就是nodeType为3的文本节点。进行输出的时候其textConent为空。


var ul = document.querySelector(".list");
    console.log("li length", ul.childNodes.length);  // 7
    var firstNode = ul.childNodes[0];
    console.log("nodeType", firstNode.nodeType);  // 3 
    console.log("content", firstNode.textContent); // 
复制代码


我们不妨添加一点内容, 你就能清晰的知道了, 其childNodes长度依旧是7,第一个文本节点的内容是 text content


<ul class="list list-1">text content
    <li class="item">list-one</li>
    <li class="item">list-two</li>
    <li class="item">list-three</li>
  </ul> 
复制代码

3.JPG


小结



是不是很简单,一切都看起来没那么难,这样,你才容易入坑啊。

篇幅优先,如果star超过 100, 再写一篇节点增加和更新的文章。


写在最后



写作不易,你的一赞一评就是我前行的最大动力。

技术交流群,请加微信 dirge-cloud。

相关文章
|
23天前
|
XML JavaScript 前端开发
Vue和React有什么区别
【8月更文挑战第28天】Vue和React有什么区别
116 0
|
7天前
|
前端开发 JavaScript 开发者
Express.js与前端框架的集成:React、Vue和Angular的示例与技巧
本文介绍了如何将简洁灵活的Node.js后端框架Express.js与三大流行前端框架——React、Vue及Angular进行集成,以提升开发效率与代码可维护性。文中提供了详细的示例代码和实用技巧,展示了如何利用Express.js处理路由和静态文件服务,同时在React、Vue和Angular中构建用户界面,帮助开发者快速掌握前后端分离的开发方法,实现高效、灵活的Web应用构建。
29 3
|
6天前
|
JavaScript 前端开发 API
如何在前端开发中有效管理状态:React vs. Vue
在现代前端开发中,状态管理是一个关键因素,它直接影响到应用的性能和可维护性。React 和 Vue 是当前最流行的前端框架,它们在状态管理方面各有优势和劣势。本文将深入探讨 React 和 Vue 在状态管理中的不同实现,分析它们的优缺点,并提供实际应用中的最佳实践,以帮助开发者选择最适合他们项目的解决方案。
|
1月前
|
移动开发 JavaScript 前端开发
【Vue面试题二十二】、什么是虚拟DOM?如何实现一个虚拟DOM?说说你的思路
这篇文章深入探讨了虚拟DOM的概念、必要性以及在Vue中的实现方式,解释了虚拟DOM如何作为真实DOM的轻量级抽象,通过优化DOM操作提高性能,并实现跨平台渲染的能力。
【Vue面试题二十二】、什么是虚拟DOM?如何实现一个虚拟DOM?说说你的思路
|
1月前
|
缓存 监控 前端开发
WEB前端三大主流框架:React、Vue与Angular
在Web前端开发中,React、Vue和Angular被誉为三大主流框架。它们各自具有独特的特点和优势,为开发者提供了丰富的工具和抽象,使得构建复杂的Web应用变得更加容易。
86 6
|
19天前
|
前端开发 Java Spring
Spring与Angular/React/Vue:当后端大佬遇上前端三杰,会擦出怎样的火花?一场技术的盛宴,你准备好了吗?
【8月更文挑战第31天】Spring框架与Angular、React、Vue等前端框架的集成是现代Web应用开发的核心。通过RESTful API、WebSocket及GraphQL等方式,Spring能与前端框架高效互动,提供快速且功能丰富的应用。RESTful API简单有效,适用于基本数据交互;WebSocket支持实时通信,适合聊天应用和数据监控;GraphQL则提供更精确的数据查询能力。开发者可根据需求选择合适的集成方式,提升用户体验和应用功能。
52 0
|
30天前
|
存储 JavaScript 前端开发
"探索Redux的Vuex化:如何在React世界中享受Vue状态管理的优雅与强大"
【8月更文挑战第21天】在现代前端开发中,状态管理至关重要。Vuex作为Vue.js的状态管理库,通过集中式存储和严格规则确保状态变更的追踪。Redux则以其在React生态中的可预测性和灵活性著称。两者都强调单一数据源、状态只读及使用纯函数变更状态。尽管API设计不同,理解Redux的核心概念——单一数据源(`store`)、状态只读与纯函数变更(`reducers`),并参考Vuex的`state`、`mutations`等,能帮助开发者快速掌握Redux,高效管理应用状态。
15 0
|
1月前
|
缓存 前端开发 JavaScript
前端框架选择指南:React vs Vue vs Angular
React、Vue与Angular是主流前端框架,各有千秋。React专注视图层,学习曲线平缓,生态丰富,适用于中大型项目;Vue简洁易学,模板直观,内置状态管理,适合中小项目及快速原型;Angular全栈框架,结构严谨,适合大型企业应用。React需手动处理状态管理,Vue提供完整CLI加速开发,Angular虽学习曲线陡峭但提供全套解决方案。性能方面,三者均利用虚拟DOM优化渲染。社区支持上,React最为庞大,Vue活跃度高,Angular有Google背书。选型应基于项目需求、团队技能及维护考量。
40 0
|
1月前
|
设计模式 JavaScript 前端开发
现代JavaScript框架比较:React、Vue和Angular
在现代Web开发中,JavaScript框架已成为开发高效、动态用户界面的关键工具。本文将深入比较三大主流框架:React、Vue和Angular。通过探讨它们的核心特性、优缺点和适用场景,帮助开发者根据项目需求选择最合适的框架。重点分析包括性能、学习曲线、社区支持和生态系统等方面,以便开发者能够做出明智的决策,优化开发流程并提升应用性能。
|
1月前
|
JavaScript 前端开发 API
浅谈:为啥 Vue 和 React 都选择了 Hooks?
浅谈:为啥 Vue 和 React 都选择了 Hooks?