如何动态生成一个新的节点及它的子节点

前言

相信许多js小白都只会在html里的body里用最普通的方式来创建标签,这种做法有一个最大的弊端就是灵活性太差及难以复用,本文将用一个具体的例子------面向对象设计的EditInPlace功能类,来讲解如何动态生成节点和它的子节点,并简单聊聊这样做的优劣。

基础概念

定义:动态生成节点是指在页面加载后,使用JavaScript代码根据用户交互或其他条件实时创建新的HTML元素,并将其添加到现有文档结构中的过程。

主要API

  • document.createElement(tagName): 创建一个新的HTML元素。
  • element.appendChild(childNode): 将一个子节点添加到指定父节点下。
  • element.insertBefore(newNode, referenceNode): 在指定参考节点之前插入新节点。
  • element.replaceChild(newChild, oldChild): 用新节点替换旧节点。

这些API提供了强大的能力,使得开发者能够轻松地改变页面内容而无需重新加载整个页面。这对于实现单页应用(SPA)或需要频繁更新数据的应用程序尤为重要。

EditInPlace类的设计与实现

EditInPlace是一个用于实现就地编辑功能的JavaScript类。它允许用户直接在网页上编辑文本内容,而不需要跳转至另一个页面或打开对话框。这个类的设计采用了面向对象的方法,封装了创建可编辑区域所需的所有逻辑。

类构造函数

先创建一个构造函数,在这个构造函数里,我们初始化了三个主要属性:唯一标识符id、目标父元素parent以及默认显示的文本value。如果没有提供parent,则默认为文档体;如果没有设置value的值,则默认打印这个家伙很懒,什么都没有留下 。紧接着调用了createElement方法来创建并配置相应的DOM元素。具体代码如下图:

javascript 复制代码
function EditInPlace(id, parent, value) {
  this.id = id; // 跨函数共享属性
  this.parent = parent || document.body;
  this.value = value || '这个家伙很懒,什么都没有留下';
  this.createElement(this.id);
}

创建容器元素

这里,createElement方法负责实际创建所需的DOM结构。首先,创建了一个<div>元素作为容器,并设置了它的id属性。然后,将该容器添加到指定的父元素下。接着,在此容器内部再创建一个<span>元素用于展示初始文本值,并将其添加到div容器中。

javascript 复制代码
EditInPlace.prototype.createElement = function(id) {
  this.containerElement = document.createElement('div');
  this.containerElement.id = this.id;
  this.parent.appendChild(this.containerElement);

  this.staticElement = document.createElement('span');
  this.staticElement.innerText = this.value;
  this.containerElement.appendChild(this.staticElement);
}

输出效果

我们可以在html里实例化两次EditInPlace类,将他们分别指定不同的id和初始值,然后我们可以在网页中添加两个可编辑的区域,并在这些区域中输入或修改内容,我们先确保<div id="app">存在于页面上,然后引入EditInPlace功能。随后,两个新的EditInPlace实例被创建出来,它们都被添加到了#app下,但各自拥有独立的ID和初始化文本

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>面向对象的editInPlace</title>
</head>
<body>
  <div id="app">
  </div>
  <script src="./editInPlace.js"></script>
  <script>
  // 流程代码, 走向面向对象封装
  new EditInPlace(
    'ep1', 
    document.getElementById('app')
  );
  new EditInPlace(
    'ep2', 
    document.getElementById('app'),
    '好嗨哟'
  );
  </script>
</body>
</html>

因为我们第一个实例化时并没有输入任何东西,所以在<div id="ep1"></div>标签里应该输出的是这个家伙很懒,什么都没有留下 ,在<div id="ep2"></div>标签输出的是好嗨哟 ,而且span标签应该是div标签的子集 ,下面一起来看看结果吧

动态生成节点的优劣

动态生成节点好处

  • 增强用户体验:允许用户直接在页面上编辑内容,减少了用户的操作步骤,提高效率。
  • 易于扩展:基于面向对象的设计使得新增功能变得相对简单,只需继承或扩展现有类即可,开发者可以更好地专注于业务逻辑
  • 更好的代码组织:将相关功能封装在一个类中有利于保持代码整洁,便于后期维护。同时,良好的封装也促进了代码的复用性。
  • 适应性强:能够根据不同的输入参数灵活调整自身行为,适用于多种场景。

动态生成节点弊端

虽然本文着重讲的是如何创建及应用动态节点,但不可否认的是它仍然有弊端。频繁的创建和删除它可能会导致性能下降,而且复杂的动态生成逻辑会导致代码难以阅读和维护。由于动态生成节点需要执行js代码来创建和插入DOM元素,所以初始加载速度可能会稍慢一些。

小结

在实际开发中,我们应根据具体需求和应用场景选择合适的方法。对于静态内容较多且不经常变动的页面,推荐使用静态方式;而对于需要频繁更新或具有复杂交互性的区域,则应考虑使用动态生成节点。

相关推荐
mCell3 小时前
GSAP ScrollTrigger 详解
前端·javascript·动效
gnip3 小时前
Node.js 子进程:child_process
前端·javascript
excel6 小时前
为什么在 Three.js 中平面能产生“起伏效果”?
前端
excel7 小时前
Node.js 断言与测试框架示例对比
前端
天蓝色的鱼鱼9 小时前
前端开发者的组件设计之痛:为什么我的组件总是难以维护?
前端·react.js
codingandsleeping9 小时前
使用orval自动拉取swagger文档并生成ts接口
前端·javascript
石金龙10 小时前
[译] Composition in CSS
前端·css
白水清风10 小时前
微前端学习记录(qiankun、wujie、micro-app)
前端·javascript·前端工程化
Ticnix10 小时前
函数封装实现Echarts多表渲染/叠加渲染
前端·echarts
用户221520442780010 小时前
new、原型和原型链浅析
前端·javascript