django 在一个段落中替换子段落

au9on6nz  于 2023-04-22  发布在  Go
关注(0)|答案(2)|浏览(119)

我试图编辑一个帖子,并使用我的editPost函数动态更新Dom(帖子是用另一个Javascript函数创建的)。

function editPost(post_id){

  // get the post text
  const post_element = document.getElementById(post_id);
  const post_text_element = post_element.querySelector('p.card-text');
  const post_text = post_text_element.textContent.trim();

  console.log(post_text_element)

  // create the textarea and populate it with the content of the post
  const textarea = document.createElement('textarea');
  textarea.setAttribute('rows', 3);
  textarea.setAttribute('cols', 50);
  textarea.setAttribute('id', `edit-post-${post_id}`);
  textarea.value = post_text;

  // create the save button and add Event Listener
  const save_button = document.createElement('button');
  save_button.textContent = 'Save';

  save_button.addEventListener('click', () => {
    
    const new_post_text = textarea.value;
    
    fetch('/update_post/' + post_id, {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ new_text: new_post_text })
    })
    .then(response => response.json())
    .then(data => {
      const updated_post_text = data.new_text;
      const updated_post_element = document.createElement('p');
      updated_post_element.className = "card-text";
      updated_post_element.textContent = updated_post_text;

      post_element.replaceChild(updated_post_element, textarea);
      post_element.removeChild(save_button);

    });
  });

    post_element.replaceChild(textarea, post_text_element);
    post_element.appendChild(save_button);    

}

但是当点击编辑按钮时,我在控制台中看到一个错误,指向底部的post_element.replaceChild,说:
未捕获DOM异常:无法在“Node”上执行“replaceChild”:要替换的节点不是此节点的子节点。at editPost(http://127.0.0.1:8000/static/network/index.js:214:18)at HTMLButtonElement.onclick(http://127.0.0.1:8000/:75:9)editPost @ index.js:214 onclick @(index):75
Post_text_element是一个html段落元素控制台。log(post_text_element)显示正确的元素。
下面你可以看到post_element的创建post_text_element在中间,类名为“card-text”

// create a div element for each post
    posts.forEach(post => {
        let cardDiv = document.createElement('div');
        cardDiv.className = "card";
        cardDiv.setAttribute('id', post['id']);
        cardDiv.innerHTML = `
        <div class="card-body">
          <div class="row card-title">
            <span class="col">
              <a id="user-link" href="profile/${post['user'][0].username}">
                <h6>${post['user'][0].username}</h6>
              </a>
            </span>
            <h7 class="col d-flex justify-content-end card-subtitle mb-2 text-muted">${post['timestamp']}</h7>
          </div>

          <p class="card-text">${post['text']}</p>

          <div class="row">
            <div class="col d-flex justify-content-start">
              <button class="like-button" onclick="likePost(${post.id});">
                ♥ 
                <span class="like-count">${post['total_likes']}</span>
              </button>
            </div>
            ${post['user'][0].id == request_user_id ? 
              `<span class="col d-flex justify-content-end">
                <button class="edit-button" onclick="editPost(${post.id});">Edit</button>
              </span>` : ''}
          </div>
        </div>
        `;
wsxa1bj1

wsxa1bj11#

对于Node.replaceChild(newChild, oldChild)Node必须是oldChild的直接父级。在代码中,oldChildpost_text_element,但其父级是<div class="card-body">,而不是post_elementpost_element<div class="card" id=…>)。不要在post_element上调用.replaceChild()方法,而是用.parentElement获取post_text_element的父对象,然后在上面调用.replaceChild(),如下所示:

function editPost(post_id){

  // get the post text
  const post_element = document.getElementById(post_id);
  const post_text_element = post_element.querySelector('p.card-text');
  const post_text = post_text_element.textContent.trim();

  console.log(post_text_element)

  // create the textarea and populate it with the content of the post
  const textarea = document.createElement('textarea');
  textarea.setAttribute('rows', 3);
  textarea.setAttribute('cols', 50);
  textarea.setAttribute('id', `edit-post-${post_id}`);
  textarea.value = post_text;

  // create the save button and add Event Listener
  const save_button = document.createElement('button');
  save_button.textContent = 'Save';

  save_button.addEventListener('click', () => {
    
    const new_post_text = textarea.value;
    
    fetch('/update_post/' + post_id, {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ new_text: new_post_text })
    })
    .then(response => response.json())
    .then(data => {
      const updated_post_text = data.new_text;
      const updated_post_element = document.createElement('p');
      updated_post_element.className = "card-text";
      updated_post_element.textContent = updated_post_text;

      post_element.replaceChild(updated_post_element, textarea);
      post_element.removeChild(save_button);

    });
  });

    post_text_element.parentElement.replaceChild(textarea, post_text_element);
    post_element.appendChild(save_button);    

}
<div class="card" id=0>
  <div class="card-body">
    <div class="row card-title">
      <span class="col">
      <a id="user-link" href="profile/${post['user'][0].username}">
        <h6>${post['user'][0].username}</h6>
      </a>
    </span>
      <h7 class="col d-flex justify-content-end card-subtitle mb-2 text-muted">${post['timestamp']}</h7>
    </div>

    <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed leo mi, hendrerit vitae quam sit amet, gravida mattis odio. Etiam fermentum vitae leo vitae gravida. Quisque id dolor sit amet risus semper fermentum at id tellus. Nam nisl magna, lobortis
      sed egestas eget, varius at nibh. Sed vestibulum rhoncus felis in sodales.</p>

    <div class="row">
      <div class="col d-flex justify-content-start">
        <button class="like-button" onclick="likePost(${post.id});">
        ♥ 
        <span class="like-count">${post['total_likes']}</span>
      </button>
      </div>
      <span class="col d-flex justify-content-end">
      <button class="edit-button" onclick="editPost(0);">Edit</button>
    </span>
    </div>
  </div>
</div>

您可能还需要在save_button.addEventListener()回调中执行类似的操作。

mwg9r5ms

mwg9r5ms2#

要替换的节点不是本节点的子节点
所以你可能需要父类。我已经试着把你的代码简化为minimal reproducable example。也许这会有所帮助。

document.addEventListener(`click`, handle);

function handle(evt) {
  if (evt.target.id === `bttn`) {
    const newTextarea = Object.assign(
      document.createElement(`textarea`), {
        className: `card-text`,
        textContent: `${new Date().toLocaleString()}\nSome new text!`
      });
    const oldText = document.querySelector(".card-text");
    oldText.parentNode.replaceChild(newTextarea, oldText);
    //      ^ the parent
  }
}
<div>
  <div>
    <span>
        <h6>Pete</h6>
    </span>
    <h7></h7>
  </div>

  <p class="card-text">The original text</p>

  <div>
    <div>
      <button>♥<span>0 likes</span></button>
    </div>
  </div>
</div>

<p>
  <button id="bttn">replaceChild Example</button>
</p>

相关问题