首页IT科技js dom参数(【JavaScript】JS实用案例分享:DOM节点转JSON数据 | 标签输入框)

js dom参数(【JavaScript】JS实用案例分享:DOM节点转JSON数据 | 标签输入框)

时间2025-08-04 22:49:29分类IT科技浏览4970
导读:🖥️ NodeJS专栏:Node.js从入门到精通...

🖥️ NodeJS专栏:Node.js从入门到精通

🖥️ 博主的前端之路(源创征文一等奖作品):前端之行              ,任重道远(来自大三学长的万字自述)

🖥️ TypeScript知识总结:TypeScript从入门到精通(十万字超详细知识点总结)

🧑‍💼个人简介:大三学生                     ,一个不甘平庸的平凡人🍬

👉 你的一键三连是我更新的最大动力❤️!

🏆分享博主自用牛客网🏆:一个非常全面的面试刷题求职网站       ,点击跳转🍬

前言

最近博主一直在牛客网刷题巩固基础知识       ,牛客网不仅具有公司真题              、专项练习                     、面试题库       、在线编程等功能                     ,还具有非常强大的AI模拟面试功能              ,简直是求职者的福音!

牛客网里的题库非常全面的       ,无论你是前端还是后端                     ,是想要备考还是准备面试又或者是想要提高自己              ,你都能在牛客网上找到适合自己的题,赶快点击链接去注册登录吧:点我进入牛客网

牛客网 牛客网

本篇文章所有示例来自于牛客网题库/在线编程/JS篇                     ,这些都是前端开发中常用的功能                     ,借此记录一下刷题过程,巩固基础!

1       、DOM节点转JSON数据

效果演示

有以下HTML和CSS:

HTML结构

<div id="jsContainer"> <ul class="js-test" id="jsParent"> <li data-index="0">1</li> <li data-index="1">2</li> </ul> <span style="font-weight: bold;">3</span> 4 </div>

案例需求

页面上存在id=jsContainer的节点A              ,按照如下需求实现 dom2json 函数

dom2json需要分析整个节点A的dom结构                     ,并将其结构转换为对应的json对象              。 需要获取dom结构的标签名称(tag)       ,所有属性(attributes)              ,子节点(children)                     。 文档片段中的属性形式均为 name="value"                     ,解析之后的格式为{name: value}, 属性值为String类型       ,不需要做解析       。 随机生成的文档片段中       ,只包含 nodeType 为1(element)和3(text)的节点                     ,不需要考虑其他节点类型              。 纯文本也视为一个节点, json格式为 {tag: text, content: 文本内容}              ,content为文本内容执行trim后的结果       ,如果该结果为空                     ,则忽略当前节点                     。 返回结果中的标签名称不区分大小写       。 如果节点不包含属性值或者子节点              ,其对应的结果中需要保留attributes以及children字段,例如 {tag: div, attributes: {}, children: []}       。 上面的HTML结构执行dom2json之后的结果如上面的效果演示                     。

JavaScript实现

function dom2json() { const root = document.getElementById(jsContainer) return JSON.stringify(getDomJson(root)) } function getDomJson(dom) { let domObj; if (dom.nodeType === 1) { // 如果是element节点 domObj = { tag: dom.localName, attributes: {}, children: [] } // 属性列表 let attlist = dom.attributes; for (let i = 0, l = attlist.length; i < l; i++) { // .name获取属性名                     ,.value获取属性值 domObj.attributes[attlist[i].name] = attlist[i].value } // 子元素列表 let childList = dom.childNodes for (let i = 0, l = childList.length; i < l; i++) { // 递归 const childJson = getDomJson(childList[i]) if (childJson) { domObj.children.push(childJson) } } } else if (dom.nodeType === 3) { // 如果是text节点 const ctn = dom.textContent.trim() if (ctn) { domObj = { tag: text, content: ctn } } } return domObj } console.log(测试, dom2json());

这个案例中主要就是对DOM操作以及递归算法的应用              。

知识点:

Node.nodeType 表示的是该节点的类型       。

Element.localName                     、Node.nodeName              、Element.tagName都能获取节点的标签名                     。

元素节点有tagName        、nodeName                      、localName属性;其中tagName              、nodeName相同                     ,都是大写,localName是小写              。 其他节点只有nodeName 、localName属性              ,无tagName属性                     ,其中: 属性节点localName和nodeName相同。 文本节点localName为null       ,nodeName为#text(带有#)                     。

从DOM层次来看              ,nodeName是node接口上的property                     ,而tagName是element接口上的property       ,所有的节点(元素节点       ,属性节点                     ,文本节点等12种)都继承了node接口              ,而只有元素节点才继承了element节点       ,因此nodeName比tagName具有更大的使用范围                     。

Element.attributes 属性返回该元素所有属性节点的一个实时集合。

Node.childNodes 返回包含指定节点的子节点的集合                     ,该集合为即时更新的集合              。

Node.textContent 属性表示一个节点及其后代的文本内容                     。

trim() 方法会从一个字符串的两端删除空白字符       。

2                     、标签输入框

效果演示

有以下HTML和CSS:

HTML结构

<div class="tag-input"> <span class="tag">前端</span> <span class="tag">编程题</span> <span class="tag">示例</span> <span class="tag">标签</span> <input type="text" class="js-input" maxlength="6" placeholder="请输入标签"> </div>

CSS样式

.tag-input{ position: relative; border: 1px solid #cccccc; padding: 0 5px; display: flex; flex-flow: row wrap; } .js-input{ width: 450px; height: 22px; line-height: 22px; font-size: 16px; padding: 0; margin: 5px 0; outline: none; border: none; width: 6.5em; height: 24px; line-height: 24px; } .tag{ padding: 0 10px; margin: 5px 5px 5px 0; background: #25bb9b; color: #ffffff; height: 24px; line-height: 24px; border-radius: 12px; font-size: 13px; }

案例需求

上面展示了一个简化版的标签输入框              ,功能如下:

当用户输入内容并敲回车键时,将输入框的内容在输入框前显示成标签                     ,并清空输入框内容              。 当用户敲删除键时                     ,如果输入框当前没有内容,则删除前一个标签                     。 标签需要去掉字符串两端的多余的空格       。 标签不能为空字符串       。 标签不能重复              ,如果输入已存在的内容相同的标签                     ,则不添加       ,并清空输入框                     。 相关键码值              ,回车键=13                     ,删除键=8              。

JavaScript实现

var tagInput = { // isInited表示是否已初始化 isInited: false, // 初始化方法 init: init, // 绑定事件处理函数的方法 bindEvent: bindEvent, // 添加标签的方法 addTag: addTag, // 移除标签的方法 removeTag: removeTag }; // 初始化 tagInput.init(); // 初始化函数 function init() { var that = this; if (that.isInited) return; that.isInited = true; // 保存class为js-input的输入框的dom元素引用 that.input = document.getElementsByClassName("js-input")[0]; that.bindEvent(); } // 注册事件 function bindEvent() { var that = this; var input = that.input; if (!input) return; // 给input绑定按键按下事件 input.addEventListener(keydown, function (event) { // 判断用户是否按了回车键 var isEnter = (event.keyCode === 13); // 判断用户是否按了删除键 var isDelete = (event.keyCode === 8); // 阻止默认行为 (isEnter || isDelete) && event.preventDefault(); isEnter && that.addTag(); isDelete && that.removeTag(); }); // 给input的父元素绑定点击事件 input.parentNode.addEventListener(click, function () { // 使用input获得焦点 input.focus(); }); } // 添加标签的函数 function addTag() { var that = this, input = that.input, val = input.value.trim(), tagList = document.getElementsByClassName(tag), isAdd = true; // 遍历存在的tag       ,输入的内容在tag中已经存在时不进行添加span元素操作(isAdd=false) for (var i = 0, l = tagList.length; i < l; i++) { if (tagList[i].innerHTML === val) { isAdd = false break } } // 如果val不为空       ,isAdd为true则添加新的span元素 if (isAdd && val) { var newSpan = document.createElement(span) newSpan.className = tag newSpan.innerHTML = val // 在input的父节点中的input节点之前插入newSpan节点 input.parentNode.insertBefore(newSpan, input) } input.value = } // 删除标签的函数 function removeTag() { var that = this, input = that.input, val = input.value, tagList = document.getElementsByClassName(tag); if (val) { // 如果val不为空时                     ,应该删除值的最后一位 input.value = val.slice(0, -1) } else if (tagList.length > 0) { // 如果val为空时              ,tagList中存在span标签       ,则删除最后一个标签 tagList[tagList.length - 1].remove() } }

这个案例的实现并不难                     ,主要就是在于它的逻辑思想              ,只要动脑去想,动手去写                     ,一般都能实现它       。

知识点:

Node.insertBefore() 方法在参考节点之前插入一个拥有指定父节点的子节点                     。 slice(begin, end) 提取某个字符串的一部分                     ,并返回一个新的字符串,且不会改动原字符串              。从下标begin提取到end(包含begin              ,不包含end)                     ,如果end<0       ,表示从末尾开始算              ,例如end是 -3                     ,则end相当于是strLength - 3(strLength 表示字符串长度)

结语

这篇文章的所有内容都出自于牛客网的JS篇题库:

牛客网的JS题库非常贴合实际的       ,在写的过程中自己查漏补缺       ,收获了很多                     ,强烈将牛客网推荐给大家!

如果本篇文章对你有所帮助              ,还请客官一件四连!❤️

基础不牢       ,地动山摇! 快来和博主一起来牛客网刷题巩固基础知识吧!

声明:本站所有文章                     ,如无特殊说明或标注              ,均为本站原创发布。任何个人或组织,在未征得本站同意时                     ,禁止复制                     、盗用、采集              、发布本站内容到任何网站                     、书籍等各类媒体平台                     。如若本站内容侵犯了原著者的合法权益                     ,可联系我们进行处理                     。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
vue直接引入nodemodules里的表格组件,表格出不来(在vue3+vite项目下按需引入vant报错Failed to resolve import解决方案) 抖音能在电脑上玩吗(抖音电脑版如何玩羊了个羊_能玩小程序游戏吗)