Javascript卡的降序排序
我试图创建一种排序方法,当我按下一个按钮时,将DOM中的卡从Z排序到a。到目前为止,我已经创建了正确排序数组的逻辑,但似乎无法将其呈现出来 我有一个Drink类和一个DrinkCard类,DrinkCard实际创建卡片,而Drink创建饮料 我觉得调用Drink类有助于将排序数组呈现给DOM,但我不确定该如何做。绘制空白 这就是我目前所拥有的 更新我根据下面的建议进行了更新,但我在任何地方都没有呈现内容的id。因此,我在类Javascript卡的降序排序,javascript,sorting,Javascript,Sorting,我试图创建一种排序方法,当我按下一个按钮时,将DOM中的卡从Z排序到a。到目前为止,我已经创建了正确排序数组的逻辑,但似乎无法将其呈现出来 我有一个Drink类和一个DrinkCard类,DrinkCard实际创建卡片,而Drink创建饮料 我觉得调用Drink类有助于将排序数组呈现给DOM,但我不确定该如何做。绘制空白 这就是我目前所拥有的 更新我根据下面的建议进行了更新,但我在任何地方都没有呈现内容的id。因此,我在类.card上使用了querySelector,这是当前的错误 Uncaug
.card
上使用了querySelector
,这是当前的错误
Uncaught DOMException: Failed to execute 'appendChild' on 'Node': The new child element contains the parent.
at Drink.render (file:///Users/austinredmond/dev/caffeine_me/frontend/src/models/drink.js:28:17)
at file:///Users/austinredmond/dev/caffeine_me/frontend/src/index.js:43:38
at Array.forEach (<anonymous>)
at HTMLInputElement.<anonymous> (file:///Users/austinredmond/dev/caffeine_me/frontend/src/index.js:43:17)
render @ drink.js:28
(anonymous) @ index.js:43
(anonymous) @ index.js:43
饮料卡类
class DrinkCard {
constructor(drink, comments) {
// Create Card //
const card = document.createElement('div')
card.setAttribute("class", "card w-50")
main.append(card)
card.className = 'card'
// Add Nameplate //
const drinkTag = document.createElement('h3')
drinkTag.innerText = drink.name
card.append(drinkTag)
// Add CaffeinePlate //
const caffeineTag = document.createElement('p')
caffeineTag.innerText = `Caffeine Amount - ${drink.caffeine}`
card.append(caffeineTag)
// Adds Create Comment Input Field //
const commentInput = document.createElement("input");
commentInput.setAttribute("type", "text");
commentInput.setAttribute("class", "input-group mb-3")
commentInput.setAttribute("id", `commentInput-${drink.id}`)
commentInput.setAttribute("placeholder", "Enter A Comment")
card.append(commentInput);
// Adds Create Comment Button //
const addCommentButton = document.createElement('button')
addCommentButton.innerText = "Add Comment"
addCommentButton.setAttribute("class", "btn btn-primary btn-sm")
card.append(addCommentButton)
addCommentButton.addEventListener("click", () => this.handleAddComment())
// Add Comment List //
this.commentList = document.createElement('ul')
card.append(this.commentList)
comments.forEach(comment => this.addCommentLi(comment))
// Create Delete Drink Button
const addDeleteButton = document.createElement('button')
addDeleteButton.setAttribute("class", "btn btn-danger btn-sm")
addDeleteButton.innerText = 'Delete Drink'
card.append(addDeleteButton)
addDeleteButton.addEventListener("click", () => this.handleDeleteDrink(drink, card))
// Connects to Drink //
this.drink = drink
this.cardContent = card;
}
// Helpers //
addCommentLi = comment => {
// Create Li //
const li = document.createElement('li')
this.commentList.append(li)
li.innerText = `${comment.summary}`
// Create Delete Button
const button = document.createElement('button')
button.setAttribute("class", "btn btn-link btn-sm")
button.innerText = 'Delete'
li.append(button)
button.addEventListener("click", () => this.handleDeleteComment(comment, li))
}
// Event Handlers //
// Handle Adding Comment to the DOM //
handleAddComment = () => {
const commentInput = document.getElementById(`commentInput-${this.drink.id}`)
api.addComment(this.drink.id, commentInput.value)
.then(comment => {
commentInput.value = ""
const newComment = new Comment(comment)
Drink.findById(newComment.drinkId).comments.push(newComment)
this.addCommentLi(newComment)
})
}
// Loads last comment created for drink object //
handleLoadComment = () => {
const newComment = this.drink.comments[this.drink.comments.length - 1]
this.addCommentLi(newComment)
}
// Deletes Comment from API and Removes li //
handleDeleteComment = (comment, li) => {
comment.delete()
li.remove()
}
// Deletes Drink from API and Removes drink card //
handleDeleteDrink = (drink, card) => {
drink.delete()
card.remove()
}
}
有几种方法可以做到这一点:
class-DrinkCard{
建造师(饮料、评论){
//您现有的代码
this.cardContent=card;//或card.innerHTML
}
}
饮料.js
class饮料{
//您现有的代码
渲染(el){
//此方法将渲染每张卡;el是对DOM节点的引用
el.appendChild(此.card.cardContent);
}
}
最后,将DOM引用传递给已排序的条目:
const node=document.getElementById('rendered-content');//确保这个存在
sortedArray.forEach(card=>card.render(节点));
希望这能给你一些提示,告诉你如何为你的目的呈现这些卡片
更新
出现错误的原因如下:
id
呈现内容的元素
.card
附加渲染元素会导致周期性错误,因为您试图将元素(.card
)附加到同一元素
添加到HTML中需要呈现已排序卡片的某个位置const rc=document.createElement('div');
rc.setAttribute('id','rendered content');
文件.正文.附件(rc);
const node=document.getElementById('rendered-content');
sortedArray.forEach(card=>card.render(节点));
这将有助于消除错误
进一步解释
我将向您简要介绍浏览器渲染以及它在本例中的工作方式。我还将为一篇更深入的详细文章留下一个链接
在渲染流中,会发生以下情况:
DrinkCard
类中那样动态创建元素,则需要将其附加到现有DOM中。否则,浏览器无法知道您的卡在DOM中。修改DOM后,将触发布局和重新绘制,然后在显示器上显示内容
使用id='rendered-content'
的div
的目的是提供一个存在于DOM中或在使用它之前添加的容器。将节点添加到DOM时,需要一个引用元素来添加新节点。此引用可以很容易地定义为document.body
。在这种情况下,render
方法将把卡添加到DOM中主体的底部。在这种情况下,提供一个单独的容器可以让您更好地控制如何显示该容器
下面深入讨论了渲染及其在浏览器中的工作方式。希望解释能回答您的问题。谢谢Abrar-它看起来好像抛出了一个错误drink.js:28未捕获类型错误:无法读取null的属性'appendChild'
我想我注意到这是因为我没有将呈现内容的id
放在某个地方。哪里应该存在?我在上面的总结中更新了我的错误和内容。@MarrixRed我更新了我的答案。让我知道这是否对你有效。它确实有效,谢谢你!然而,我想我对如何渲染和this.cardContent=card仍然有点模糊代码>工作。你是否有任何资源来帮助解释这一点,或者你可以吗?
class Drink {
constructor(data) {
// Assign Attributes //
this.id = data.id
this.name = data.name
this.caffeine = data.caffeine
this.comments = []
this.card = new DrinkCard(this, this.comments)
}
// Searches allDrinks Array and finds drink by id //
static findById(id) {
return allDrinks.find(drink => drink.id === id)
}
// Delete function to Delete from API //
delete = () => {
api.deleteDrink(this.id)
delete this
}
render(element) {
// this method will render each card; el is a reference to a DOM node
console.log(element)
element.appendChild(this.card.cardContent);
}
}
class DrinkCard {
constructor(drink, comments) {
// Create Card //
const card = document.createElement('div')
card.setAttribute("class", "card w-50")
main.append(card)
card.className = 'card'
// Add Nameplate //
const drinkTag = document.createElement('h3')
drinkTag.innerText = drink.name
card.append(drinkTag)
// Add CaffeinePlate //
const caffeineTag = document.createElement('p')
caffeineTag.innerText = `Caffeine Amount - ${drink.caffeine}`
card.append(caffeineTag)
// Adds Create Comment Input Field //
const commentInput = document.createElement("input");
commentInput.setAttribute("type", "text");
commentInput.setAttribute("class", "input-group mb-3")
commentInput.setAttribute("id", `commentInput-${drink.id}`)
commentInput.setAttribute("placeholder", "Enter A Comment")
card.append(commentInput);
// Adds Create Comment Button //
const addCommentButton = document.createElement('button')
addCommentButton.innerText = "Add Comment"
addCommentButton.setAttribute("class", "btn btn-primary btn-sm")
card.append(addCommentButton)
addCommentButton.addEventListener("click", () => this.handleAddComment())
// Add Comment List //
this.commentList = document.createElement('ul')
card.append(this.commentList)
comments.forEach(comment => this.addCommentLi(comment))
// Create Delete Drink Button
const addDeleteButton = document.createElement('button')
addDeleteButton.setAttribute("class", "btn btn-danger btn-sm")
addDeleteButton.innerText = 'Delete Drink'
card.append(addDeleteButton)
addDeleteButton.addEventListener("click", () => this.handleDeleteDrink(drink, card))
// Connects to Drink //
this.drink = drink
this.cardContent = card;
}
// Helpers //
addCommentLi = comment => {
// Create Li //
const li = document.createElement('li')
this.commentList.append(li)
li.innerText = `${comment.summary}`
// Create Delete Button
const button = document.createElement('button')
button.setAttribute("class", "btn btn-link btn-sm")
button.innerText = 'Delete'
li.append(button)
button.addEventListener("click", () => this.handleDeleteComment(comment, li))
}
// Event Handlers //
// Handle Adding Comment to the DOM //
handleAddComment = () => {
const commentInput = document.getElementById(`commentInput-${this.drink.id}`)
api.addComment(this.drink.id, commentInput.value)
.then(comment => {
commentInput.value = ""
const newComment = new Comment(comment)
Drink.findById(newComment.drinkId).comments.push(newComment)
this.addCommentLi(newComment)
})
}
// Loads last comment created for drink object //
handleLoadComment = () => {
const newComment = this.drink.comments[this.drink.comments.length - 1]
this.addCommentLi(newComment)
}
// Deletes Comment from API and Removes li //
handleDeleteComment = (comment, li) => {
comment.delete()
li.remove()
}
// Deletes Drink from API and Removes drink card //
handleDeleteDrink = (drink, card) => {
drink.delete()
card.remove()
}
}