简体   繁体   English

如何使用来自 DOM 的元素更新 HTML 字符串

[英]How to update an HTML string with an element from DOM

I'm trying to update a stringify HTML element with element from the DOM.我正在尝试使用来自 DOM 的元素更新字符串化 HTML 元素。 This stringify HTML element is in an array in the localStorage.此字符串化 HTML 元素位于 localStorage 的数组中。

First, here is how I convert it into manipulable HTML:首先,这是我如何将其转换为可操作的 HTML:

let toBeUpdated = document.createElement('div');
toBeUpdated.innerHTML = `${var_stringify_html_from_localstorage}`;
toBeUpdated = toBeUpdated.firstElementChild;

This toBeUpdated element is a div that contains, among other thing, an element with id updateMe .这个toBeUpdated元素是一个 div,其中包含一个 id updateMe的元素。 I want to update this "virtual" (not visible) #updateMe element with the one from the DOM.我想用来自 DOM 的元素更新这个“虚拟”(不可见) #updateMe元素。

I tried first:我先试过:

let updateme = toBeUpdated.querySelector("#updateMe");
let updateme_DOM = document.querySelector("#updateMe");

toBeUpdated.replaceChild(updateme, updateme_DOM);

Which returns Uncaught DOMException: Node.replaceChild: Child to be replaced is not a child of this node返回Uncaught DOMException: Node.replaceChild: Child to be replaced is not a child of this node

And secondly I tried:其次,我尝试了:

let updateme = toBeUpdated.querySelector("#updateMe");
let updateme_DOM = document.querySelector("#updateMe");

updateme.replaceWith(updateme_DOM);

Which removes the originale #updateMe from the DOM and dosn't update the toBeUpdated element.这会从 DOM 中删除原始的#updateMe并且不会更新toBeUpdated元素。

I'm obviously missing something, but I can't see what...我显然错过了一些东西,但我看不到什么......

I tried to reproduce as much as possible my situation:我试图尽可能地重现我的情况:

 //initial state of local storage let motd = ["<div id='toBeUpdated'><h1>Hello World</h1><p id='updateMe'>Message of tomorrow</p></div>"]; window.localStorage.setItem('motds', JSON.stringify(motd)); // My situation, later in the code let motds = JSON.parse(window.localStorage.getItem('motds')); let toBeUpdated = document.createElement('div'); toBeUpdated.innerHTML = `${motds[0]}`; toBeUpdated = toBeUpdated.firstElementChild; // this is the div#toBeUpdated let DOMUpdateMe = document.getElementById('updateMe'); let storageUpdateMe = toBeUpdated.querySelector("#updateMe"); // getElementById doesn't work here // Replace storageUpdateMe.replaceWith(DOMUpdateMe); // Back in local storage motds[0] = toBeUpdated.outerHTML; window.localStorage.setItem('motds', JSON.stringify(motds));
 <body> <div id="toBeUpdated"> <h1>Hello World</h1> <p id="updateMe">Message of tomorrow</p> </div> </body>

It works using firstChild rather than firstElementChild它使用firstChild而不是firstElementChild

 let toBeUpdated = document.createElement('div'); //toBeUpdated.innerHTML = `${var_stringify_html_from_localstorage}`; toBeUpdated.innerHTML = `<div id="updateMe">New DIV</div>`; let updateme = document.getElementById('updateMe') updateme.replaceWith(toBeUpdated.firstChild);
 <div id='updateMe'>Old DIV</div>

It seems the only thing you're missing is cloning the DOM node before inserting it into the non-DOM.您似乎唯一缺少的是在将 DOM 节点插入非 DOM 之前克隆它。

Here's a step-by-step reproduction of your code changing only this, that works.这是您的代码的逐步复制,仅更改此代码即可。 I also set the initial state of localStorage to "Message of today" for clarity.为了清楚起见,我还将localStorage的初始 state 设置为“今天的消息”。

localStorage is emulated with variables, as it triggers a security error inside snippet due to CORS localStorage是用变量模拟的,因为由于 CORS 它会在代码段内触发安全错误

 //initial state of local storage let motd = ["<div id='toBeUpdated'><h1>Hello World</h1><p id='updateMe'>Message of today</p></div>"]; //window.localStorage.setItem('motds', JSON.stringify(motd)); //Read from local storage //let motds = JSON.parse(window.localStorage.getItem('motds')); const motds = JSON.parse(JSON.stringify(motd)); //Simulate local storage console.log("In storage:", motds); //Create element outside of DOM const toBeUpdated = document.createElement('div'); toBeUpdated.innerHTML = motds[0]; console.log("To be updated:", toBeUpdated.outerHTML); //Get part to update const DOMUpdateMe = document.getElementById('updateMe'); const storageUpdateMe = toBeUpdated.querySelector("#updateMe"); console.log(DOMUpdateMe, storageUpdateMe); //Replace part outside of DOM with clone of part from DOM storageUpdateMe.replaceWith(DOMUpdateMe.cloneNode(true)); console.log(toBeUpdated.outerHTML); //Store back motds[0] = toBeUpdated.outerHTML; motd = JSON.stringify(motds); //Simulate local storage console.log(motd); //window.localStorage.setItem('motds', JSON.stringify(motds));
 <body> <div id="toBeUpdated"> <h1>Hello World</h1> <p id="updateMe">Message of tomorrow</p> </div> </body>

Shouldn't you be using a simple newUpdateMe = DOMUpdateMe;您不应该使用简单的newUpdateMe = DOMUpdateMe;

 //initial state of local storage let motd = ["<p class='updateMe'>Message of the day<p>"]; window.localStorage.setItem('motds', JSON.stringify(motd)); // My situation, later in the code let motds = JSON.parse(window.localStorage.getItem('motds')); let dOMUpdateMe = document.querySelectorAll('#toBeUpdated > *'); let counter = 0; dOMUpdateMe.forEach(function(dOMToUpdate) { console.log(dOMToUpdate); if(dOMToUpdate.classList.contains('updateMe')) { motds[counter] = dOMToUpdate.outerHTML; counter++; } }) window.localStorage.setItem('motds', JSON.stringify(motds));
 <div id="toBeUpdated"> <h1 class="updateMe">Hello World</h1> <p class="updateMe">Update Me</p> <p class="no">No not Update Me</p> <p class="no">No not Update Me</p> <p class="no">No not Update Me</p> <p class="updateMe">Update Me too</p> <p class="no">No not Update Me</p> </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM