javascript 如何在JS中同步HTML片段而不替换所有内容?

axzmvihb  于 2023-04-19  发布在  Java
关注(0)|答案(2)|浏览(138)

我想根据服务器上呈现的HTML片段动态更新页面,第一种简单的方法是从服务器获取片段,然后通过.innerHTML更新目标。
不幸的是,这会导致两个问题(基本上是相同的):
1.当用户选择动态内容中的任何文本时,选择将被清除。即使,如果所选文本没有更改。这可以在下面的示例中看到:当选择foo时,它将在更新后被清除,但实际上并没有改变。
1.任何附加到元素的状态也会被删除。特别是我的页面的动态内容有一些按钮,它们会在请求处理时显示加载指示器。对我来说,如果内容更改时指示器消失了,这没关系,但每秒被清除的状态使指示器变得无用。
我真正的问题是,是否有一种简单的方法只更新更改的元素。特别是当元素可以添加,删除或重新排序时。

let counter = 0;

setInterval(() => {  
  counter++;
 
  // assume this is fetched from the server
  content = '<ul><li>foo</li><li>'+counter+'</li><li>bar</li></ul>'; 
  
  document.getElementById("dynamic-content").innerHTML = content;
}, 1000);
<div>
  <h1>my page</h1>
  <div id="dynamic-content">
      <ul>
        <li>foo</li>
        <li>0</li>
        <li>bar</li>
      </ul>
  </div>
</div>
x8diyxa7

x8diyxa71#

这取决于你想替换什么,以及知道如何针对它。在这里我做了一个完全人工的部分替换的例子。

  • 我会在一个承诺中做这件事,而不是在一段时间内
  • 你需要知道你想做什么-这里我展示了如何从返回的(假的)内容中选择一个子部分并使用它。
let counter = 0;

setInterval(() => {
  counter++;
  const newDiv = document.createElement("div");

  // assume this is fetched from the server
  let content = '<ul><li>foo</li><li class="counter-thing"><span class="new-count">' + counter + '</span></li><li>bar</li></ul>';
  newDiv.innerHTML = content;
  let newc = newDiv.querySelector(".counter-thing").innerHTML;
  console.log(newc);
  let dy = document.querySelector("#dynamic-content >ul");
  let x = dy.querySelector("li:nth-of-type(2)");
  console.log(x);
  x.innerHTML = newc;
  // another way to put some text in (be careful of HTML here)
  document.querySelector('.example-two').dataset.content = counter;
}, 3000);
#dynamic-content>ul {
  list-style: none;
  display: block;
  margin: 1rem;
  padding: 0;
}

.foo-me {
  border: solid 1px #00FF00;
}

.new-count {
  background-color: #FF44FF44;
  padding: 1rem;
  margin: 1rem;
  border: 1px solid red;
}

.example-two[data-content]:before {
  content: attr(data-content);
}
<div>
  <h1>my page</h1>
  <div id="dynamic-content">
    <ul>
      <li class="foo-me">foo</li>
      <li>0</li>
      <li>bar</li>
    </ul>
  </div>
</div>

Fake out another way to replace content:
<div class="example-two" data-content="Some content goes here."></div>
wfypjpf4

wfypjpf42#

我发现了一个简单的库,叫做idiomorph,它可以完成我想要的很多功能。通常有多个库可以用于这个用例,它们将自己描述为DOM“变形”库。
所以你不用

document.getElementById("dynamic-content").innerHTML = content;

我只需要

Idiomorph.morph(document.getElementById("dynamic-content"), content, {morphStyle:'innerHTML'});

此外,我必须在每个元素上放置id标记,但在我的情况下这很容易。

相关问题