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

前言

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

小结

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

相关推荐
学习编程的小羊9 分钟前
探索HTML5 Canvas:创造动态与交互性网页内容的强大工具
前端·html·html5
SaebaRyo21 分钟前
如何优雅的更新你的npm包
前端·后端·npm
计算机软件程序设计22 分钟前
Vue中有什么组件可以实现轮播效果,每次出现四个元素?
前端·javascript·vue.js
GISer_Jing1 小时前
[本周五题]Javascript面试常考题&手撕&场景UR缓存、new关键字、大数相加、最长递增子序列、高并发请求、大文件上传和WebWorks
开发语言·javascript·面试
好_快1 小时前
Lodash源码阅读-baseIndexOf
前端·javascript·源码阅读
古柳_Deserts_X1 小时前
这个强大的插件能让网页里的 Shader 代码一览无余
前端·webgl·three.js
好_快1 小时前
Lodash源码阅读-indexOf
前端·javascript·源码阅读
积水成江1 小时前
【Vue3+Vite指南】全局引入SCSS文件后出现Undefined mixin?一招解决命名空间陷阱!
前端·vue.js·html5·scss
一个处女座的程序猿O(∩_∩)O1 小时前
harmonyOS NEXT开发与前端开发深度对比分析
前端·华为·harmonyos