簡體   English   中英

JavaScript removeChild無法按預期工作

[英]Javascript removeChild doesn't work as expected

我有一個代碼,可在單擊電影名稱后獲取角色名稱和性別。 此信息出現在模式窗口中,我的目標是每次關閉模式時都刪除帶有字符的HTML元素,因此,如果我選擇另一部電影,則會出現新的字符集,而舊的字符已被刪除。

問題是removeChild方法無法按預期工作。 我嘗試了包括parentNode在內的各種變體,但沒有任何幫助。

這是代碼:

 window.addEventListener('DOMContentLoaded', function() { let btn = document.querySelector('.sw-btn'); let content = document.querySelector('.content'); let modal = document.querySelector('.modal'); let modalBody = document.querySelector('.modal-body'); let closeBtn = document.querySelector('.close-btn'); let filmsList = document.createElement('ul'); let charsList = document.createElement('ol'); function getFilms() { axios.get('https://swapi.co/api/films/').then(res => { content.appendChild(filmsList); for (var i = 0; i < res.data.results.length; i++) { res.data.results.sort(function(a, b) { let dateA = new Date(a.release_date), dateB = new Date(b.release_date); return dateA - dateB; }); (function updateFilms() { let addFilm = document.createElement('li'); filmsList.appendChild(addFilm); let addFilmAnchor = document.createElement('a'); let addFilmId = document.createElement('p'); let addFilmCrawl = document.createElement('p'); let addFilmDirector = document.createElement('p'); let addFilmDate = document.createElement('p'); addFilmAnchor.textContent = res.data.results[i].title; addFilmId.textContent = `Episode ID: ${res.data.results[i].episode_id}`; addFilmCrawl.textContent = `Episode description: ${res.data.results[i].opening_crawl}`; addFilmDirector.textContent = `Episode director: ${res.data.results[i].director}`; addFilmDate.textContent = `Episode release date: ${res.data.results[i].release_date}`; addFilm.append(addFilmAnchor, addFilmId, addFilmCrawl, addFilmDirector, addFilmDate); })(); } let links = document.getElementsByTagName('a'); for (let j = 0; j < links.length; j++) { links[j].onclick = function() { modal.style.display = 'block'; modalBody.appendChild(charsList); let chars = res.data.results[j].characters; for (let k = 0; k < chars.length; k++) { const element = chars[k]; axios.get(element).then(res => { let addChar = document.createElement('li'); charsList.appendChild(addChar); let addCharName = document.createElement('p'); let addCharGender = document.createElement('p'); addCharName.textContent = `Character name: ${res.data.name}`; addCharGender.textContent = `Character gender: ${res.data.gender}`; addChar.append(addCharName, addCharGender); }) } closeBtn.addEventListener('click', () => { modal.style.display = 'none'; console.log(modalBody.childNodes[0]); // Problem is here modalBody.removeChild(modalBody.childNodes[0]); }); window.addEventListener('click', (e) => { if (e.target == modal) { modal.style.display = 'none'; console.log(modalBody.childNodes[0]); modalBody.removeChild(modalBody.childNodes[0]); } }) } } }).catch(err => { console.log("An error occured"); }) }; btn.addEventListener('click', getFilms); closeBtn.addEventListener('click', () => { modal.style.display = 'none'; }); window.addEventListener('click', (e) => { if (e.target == modal) { modal.style.display = 'none'; } }) }); 
 body { max-height: 100vh; padding: 0; margin: 0; font-family: Muli; } body::before { background: url('https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/Star_Wars_Logo.svg/1200px-Star_Wars_Logo.svg.png') no-repeat center / cover; background-size: cover; content: ""; display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -2; opacity: 0.1; } h1 { text-align: center; color: #660d41; font-size: 3em; margin-top: 10px; letter-spacing: 1px; } main { display: flex; align-items: center; flex-direction: column; } .content { max-width: 55%; overflow-y: scroll; max-height: 75vh; } .modal { display: none; position: fixed; z-index: 1; left: 0; top: 0; width: 100%; height: 100%; overflow: auto; background-color: rgba(0, 0, 0, 0.5); } .modal-content { background-color: #f4f4f4; margin: 20% auto; width: 40%; box-shadow: 0 5px 8px 0 rgba(0, 0, 0, 0.2), 0 7px 20px 0 rgba(0, 0, 0, 0.2); animation: modalOpen 1s; } .modal-header { background: coral; padding: 15px; color: white; letter-spacing: 1px; position: relative; } .modal-header h2 { margin: 0; } .modal-body { padding: 10px 20px; } .close-btn { color: white; float: right; font-size: 30px; position: absolute; top: 0px; right: 10px; } .close-btn:hover, .close-btn:focus { color: black; text-decoration: none; cursor: pointer; transition: all 0.4s ease-in; } ul { list-style-type: none; padding: 10px 20px; } li { border-bottom: 1px solid orangered; margin-bottom: 30px; } li:last-child { border-bottom: none; margin-bottom: 0; } a { font-size: 1.7em; color: #b907d9; cursor: pointer; margin-bottom: 10px; } p { font-size: 1.2rem; color: #0f063f; margin: 10px 0; } button { padding: .5em 1.5em; border: none; color: white; transition: all 0.2s ease-in; background: #da2417; border-radius: 20px; font-size: 1em; cursor: pointer; margin-top: 15px; } button:focus { outline: none; } button:hover { background: #e7736b; } button:active { box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.7) inset; } @keyframes modalOpen { from { opacity: 0 } to { opacity: 1 } } 
 <link href="https://fonts.googleapis.com/css?family=Muli&display=swap" rel="stylesheet"> <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.0/axios.min.js"></script> <h1>Star wars films</h1> <main> <div class="content"></div> <div class="modal"> <div class="modal-content"> <div class="modal-header"> <span class="close-btn">&times;</span> <h2>Episode Characters</h2> </div> <div class="modal-body"></div> </div> </div> <button class="sw-btn">Find Films</button> </main> 

任何幫助,將不勝感激。

問題在於,將字符追加到列表時會使用相同的ol元素,因為您是在開始時實例化它並在以后重新使用它: let charsList = document.createElement('ol');

關閉模態時,將從模態中刪除該ol元素,但不會刪除其內容。 當再次打開該模式中, ol將再次增加-與您的舊內容。

如果在onclick處理程序中移動charsList聲明,它將起作用。

另外,您應該只注冊一次模態的關閉處理程序。 否則,它將在您打開模態時被調用。

演示:

 window.addEventListener('DOMContentLoaded', function () { let btn = document.querySelector('.sw-btn'); let content = document.querySelector('.content'); let modal = document.querySelector('.modal'); let modalBody = document.querySelector('.modal-body'); let closeBtn = document.querySelector('.close-btn'); let filmsList = document.createElement('ul'); closeBtn.addEventListener('click', () => { modal.style.display = 'none'; console.log(modalBody.childNodes[0]); modalBody.removeChild(modalBody.childNodes[0]); }); window.addEventListener('click', (e) => { if (e.target == modal) { modal.style.display = 'none'; console.log(modalBody.childNodes[0]); modalBody.removeChild(modalBody.childNodes[0]); } }) function getFilms() { axios.get('https://swapi.co/api/films/').then(res => { content.appendChild(filmsList); for (var i = 0; i < res.data.results.length; i++) { res.data.results.sort(function (a, b) { let dateA = new Date(a.release_date), dateB = new Date(b.release_date); return dateA - dateB; }); (function updateFilms() { let addFilm = document.createElement('li'); filmsList.appendChild(addFilm); let addFilmAnchor = document.createElement('a'); let addFilmId = document.createElement('p'); let addFilmCrawl = document.createElement('p'); let addFilmDirector = document.createElement('p'); let addFilmDate = document.createElement('p'); addFilmAnchor.textContent = res.data.results[i].title; addFilmId.textContent = `Episode ID: ${res.data.results[i].episode_id}`; addFilmCrawl.textContent = `Episode description: ${res.data.results[i].opening_crawl}`; addFilmDirector.textContent = `Episode director: ${res.data.results[i].director}`; addFilmDate.textContent = `Episode release date: ${res.data.results[i].release_date}`; addFilm.append(addFilmAnchor, addFilmId, addFilmCrawl, addFilmDirector, addFilmDate); })(); } let links = document.getElementsByTagName('a'); for (let j = 0; j < links.length; j++) { links[j].onclick = function () { modal.style.display = 'block'; let charsList = document.createElement('ol'); modalBody.appendChild(charsList); let chars = res.data.results[j].characters; for (let k = 0; k < chars.length; k++) { const element = chars[k]; axios.get(element).then(res => { let addChar = document.createElement('li'); charsList.appendChild(addChar); let addCharName = document.createElement('p'); let addCharGender = document.createElement('p'); addCharName.textContent = `Character name: ${res.data.name}`; addCharGender.textContent = `Character gender: ${res.data.gender}`; addChar.append(addCharName, addCharGender); }) } } } }).catch(err => { console.log("An error occured"); }) }; btn.addEventListener('click', getFilms); closeBtn.addEventListener('click', () => { modal.style.display = 'none'; }); window.addEventListener('click', (e) => { if (e.target == modal) { modal.style.display = 'none'; } }) }); 
 body { max-height: 100vh; padding: 0; margin: 0; font-family: Muli; } body::before { background: url('https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/Star_Wars_Logo.svg/1200px-Star_Wars_Logo.svg.png') no-repeat center / cover; background-size: cover; content: ""; display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -2; opacity: 0.1; } h1 { text-align: center; color: #660d41; font-size: 3em; margin-top: 10px; letter-spacing: 1px; } main { display: flex; align-items: center; flex-direction: column; } .content { max-width: 55%; overflow-y: scroll; max-height: 75vh; } .modal { display: none; position: fixed; z-index: 1; left: 0; top: 0; width: 100%; height: 100%; overflow: auto; background-color: rgba(0, 0, 0, 0.5); } .modal-content { background-color: #f4f4f4; margin: 20% auto; width: 40%; box-shadow: 0 5px 8px 0 rgba(0, 0, 0, 0.2), 0 7px 20px 0 rgba(0, 0, 0, 0.2); animation: modalOpen 1s; } .modal-header { background: coral; padding: 15px; color: white; letter-spacing: 1px; position: relative; } .modal-header h2 { margin: 0; } .modal-body { padding: 10px 20px; } .close-btn { color: white; float: right; font-size: 30px; position: absolute; top: 0px; right: 10px; } .close-btn:hover, .close-btn:focus { color: black; text-decoration: none; cursor: pointer; transition: all 0.4s ease-in; } ul { list-style-type: none; padding: 10px 20px; } li { border-bottom: 1px solid orangered; margin-bottom: 30px; } li:last-child { border-bottom: none; margin-bottom: 0; } a { font-size: 1.7em; color: #b907d9; cursor: pointer; margin-bottom: 10px; } p { font-size: 1.2rem; color: #0f063f; margin: 10px 0; } button { padding: .5em 1.5em; border: none; color: white; transition: all 0.2s ease-in; background: #da2417; border-radius: 20px; font-size: 1em; cursor: pointer; margin-top: 15px; } button:focus { outline: none; } button:hover { background: #e7736b; } button:active { box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.7) inset; } @keyframes modalOpen { from { opacity: 0 } to { opacity: 1 } } 
 <link href="https://fonts.googleapis.com/css?family=Muli&display=swap" rel="stylesheet"> <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.0/axios.min.js"></script> <h1>Star wars films</h1> <main> <div class="content"></div> <div class="modal"> <div class="modal-content"> <div class="modal-header"> <span class="close-btn">&times;</span> <h2>Episode Characters</h2> </div> <div class="modal-body"></div> </div> </div> <button class="sw-btn">Find Films</button> </main> 

這樣做charsList.innerText = ''; 單擊關閉按鈕時。

當您調用removeChild您將從UI的模態主體中刪除<ol> 單擊關閉按鈕后,您可以看到modalBody為空。

但是您已經通過let charsList = document.createElement('ol');<ol>元素存儲在js變量中let charsList = document.createElement('ol'); 因此ol元素本身實際上並沒有改變。 <li>元素仍在<ol> 然后,添加更多新的<li>並將其放回modalBody

在此處輸入圖片說明

我的解決方案是單擊關閉按鈕時刪除<ol>中的所有元素。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM