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

前言

相信许多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元素,所以初始加载速度可能会稍慢一些。

小结

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

相关推荐
KL's pig/猪头/爱心/猪头1 分钟前
lws-minimal-ws-server前端分析
前端
TheK1 分钟前
【源码分析】 一文搞清楚React全流程
前端
渔樵江渚上3 分钟前
使用 Web Worker 解析 CSV 文件
前端·javascript·面试
悟空和大王3 分钟前
win11下使用wsl2 + docker 打造前端开发环境
前端
Silence_xl4 分钟前
nvm安装node版本
前端
星光不问赶路人6 分钟前
梳理字节数据(Uint8Array)转换成字符串的4种方法
前端
前端卧龙人7 分钟前
如何通过 Nginx 实现前端与后端的协同部署
前端
simple丶8 分钟前
领域模型 DSL设计与解析引擎
前端
我不是迈巴赫9 分钟前
虚拟列表业务封装思路分享
前端·javascript
twohands10 分钟前
使用两段代码,通过 View Transitions API 为主题切换添加平滑过渡动画
前端