使 JavaScript 等到元素在页面上呈现后将 JS 对象绑定到它

Make JavaScript wait until element is rendered on the page an after bind JS object to it

我正在从事某种项目,它需要动态前端元素,但我没有时间学习 React 或其他东西。因此,我决定编写一些迷你逻辑,这意味着我向我的 DOM 添加了一些元素,然后将一些 JS 对象绑定到它来表示它的逻辑并提供它的方法。您可以在下面看到解释我的问题的示例。

`

function itemHTML(name,price){
  return  `
    <div class="item">
      <span class="item__name">${name}</span>
      <span class="item__price">${price}$</span>
      <button class="item__delete-button">X</button> 
    </div>
  `
}

class ContainerObj {
  constructor (self){
    this.self = self
    this.items = []
  }
  add(item) {
    this.self.innerHTML += itemHTML(item.name,item.price)
    this.items.push(
      new ItemObj(
        self = this.self.querySelector(".item:last-child")
      )
    )
  }
}

class ItemObj {
  constructor(self){
    this.self = self 
    this._name = self.querySelector(".item__name")
    this._price = self.querySelector(".item__price")
    this._deleteButton = self.querySelector(".item__delete-button")
    this._deleteButton.addEventListener("click",(event)=>{
      this.self.remove()
    })
  }
  get name() {
    return this._name
  }
  get price() {
    return this._price
  }
  set name(value) {
      this._name = value
  }
  set price(value) {
      this._price = value
  }
}

class AppenderObj {
  constructor (self,container) {
    this.self = self
    this.container = container 
    this._name = self.querySelector(".appender__name")
    this._price = self.querySelector(".appender__price")
    this._addButton = self.querySelector(".appender__add-button")
    this._addButton.addEventListener("click",(event)=>{
        this.container.add({
          name:this._name.value,
          price:this._price.value
        })
        this._name.value = ""
        this._price.value = ""
    })
  }
}

items = [
  {
    name: "Apple",
    price: 5
  },
  {
    name: "Pen",
    price: 20
  }
];

$container = new ContainerObj(
  self = document.querySelector("#container")
)

$appender = new AppenderObj(
  self = document.querySelector("#appender"),
  container = $container
)


items.forEach((item)=>{
  $container.add(item)
})
#container{
  border:1px solid black;
}
#appender{
  margin-top: 10px;
}
.item{
  display: flex;
  justify-content: space-between;
  border: 1px solid black;
  margin: 5px;
  padding: 5px;
}
<div id="container">    </div>
<div id="appender">
    <input class="appender__name" type="text" placeholder="Name">
    <input class="appender__price" type="text" placeholder="Price">
    <input class="appender__add-button" type="button" value="add">
</div>

`

我无法理解为什么它确实在添加但不能

感谢您的建议... 尽量少写:) 如果没有足够的问题信息,我会发送其余的。

问题在于 HTML 的串联,您在 ContainerObj class 中执行 this.self.innerHTML += itemHTML(item.name,item.price)。如果您要改用 insertAdjactentHTML,像这样:

this.self.insertAdjacentHTML('beforeend', itemHTML( item.name, item.price ) );

事件侦听器将正常运行。

function itemHTML(name,price){
  return  `
    <div class="item">
      <span class="item__name">${name}</span>
      <span class="item__price">${price}$</span>
      <button class="item__delete-button">X</button> 
    </div>
  `;
};

class ContainerObj {
  constructor(n){
    this.self=n;
    this.items=[];
  }
  
  add(item) {
    /* do not concatenate the HTML, insert new like this */
    this.self.insertAdjacentHTML('beforeend', itemHTML( item.name, item.price ) );
    this.items.push(
      new ItemObj( this.self.querySelector(".item:last-child") )
    )
  }
};

class ItemObj {
  constructor(n){
    this._name = n.querySelector(".item__name");
    this._price = n.querySelector(".item__price");
    this._deleteButton = n.querySelector(".item__delete-button");
    
    this._deleteButton.addEventListener("click",(event)=>{
      n.remove();
    })
  }
  get name() {
    return this._name;
  }
  get price() {
    return this._price;
  }
  set name(value) {
      this._name = value;
  }
  set price(value) {
      this._price = value;
  }
};

class AppenderObj {
  constructor (n,container) {
    this.container = container;
    this._name = n.querySelector(".appender__name");
    this._price = n.querySelector(".appender__price");
    this._addButton = n.querySelector(".appender__add-button");
    
    this._addButton.addEventListener("click",(event)=>{
        this.container.add({
          name:this._name.value,
          price:this._price.value
        })
        
        this._name.value = "";
        this._price.value = "";
    });
  }
};


$container = new ContainerObj(
  document.querySelector("#container")
);
$appender = new AppenderObj(
  document.querySelector("#appender"),$container
);



const items = [
  {
    name: "Apple",
    price: 5
  },
  {
    name: "Pen",
    price: 20
  }
];

items.forEach(item=>{
  $container.add(item)
});
#container{
  border:1px solid black;
}
#appender{
  margin-top: 10px;
}
.item{
  display: flex;
  justify-content: space-between;
  border: 1px solid black;
  margin: 5px;
  padding: 5px;
}
<div id="container"></div>
<div id="appender">
    <input class="appender__name" type="text" placeholder="Name" />
    <input class="appender__price" type="text" placeholder="Price" />
    <input class="appender__add-button" type="button" value="add" />
</div>