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

前言

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

小结

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

相关推荐
无限大.5 小时前
前端知识速记:节流与防抖
前端
十八朵郁金香5 小时前
【VUE案例练习】前端vue2+element-ui,后端nodo+express实现‘‘文件上传/删除‘‘功能
前端·javascript·vue.js
学问小小谢6 小时前
第26节课:内容安全策略(CSP)—构建安全网页的防御盾
运维·服务器·前端·网络·学习·安全
LCG元6 小时前
Vue.js组件开发-实现全屏图片文字缩放切换特效
前端·javascript·vue.js
还是鼠鼠7 小时前
图书管理系统 Axios 源码__新增图书
前端·javascript·vscode·ajax·前端框架·node.js·bootstrap
还是鼠鼠10 小时前
图书管理系统 Axios 源码 __删除图书功能
前端·javascript·vscode·ajax·前端框架·node.js·bootstrap
轻口味10 小时前
Vue.js `Suspense` 和异步组件加载
前端·javascript·vue.js
m0_zj12 小时前
8.[前端开发-CSS]Day08-图形-字体-字体图标-元素定位
前端·css
还是鼠鼠12 小时前
图书管理系统 Axios 源码__编辑图书
前端·javascript·vscode·ajax·前端框架
北极象12 小时前
vue3中el-input无法获得焦点的问题
前端·javascript·vue.js