首页 > 解决方案 > 无法通过 id/classname 捕获元素

问题描述

我有 scrypt,它创建元素。它有效,但是当我尝试使用“product__btn”类或 ID 捕获产品 btns 时,我做不到。那么我怎样才能捕捉到创建的元素以及为什么我不能捕捉到它们呢?

function createProductsList(categoryName, productList) {

    const categoryBlock = document.querySelector('.category');
    const listTitle = document.createElement('p');
    
    listTitle.innerHTML = `<p class="category__name">${categoryName}</p>`;
    if(listTitle.classList.contains('category__name__remove')){
        listTitle.classList.remove('category__name__remove');
    }
    categoryBlock.prepend(listTitle);

    const productItems = productList.map(element => {
        const elem = document.createElement("div");
        elem.setAttribute("class", "product");
        elem.innerHTML = `
            <img class="product__image" src="${element.photo}" alt="">
            <p class="product__name">
                ${element.title.split("")
                               .map((titleStr, index) => titleStr = (index === 0) ? 
                                        titleStr.toUpperCase() : 
                                        titleStr.toLowerCase()).join("")}
            </p>
            <p class="product__description">
            ${element.composition.map((descriptionStr, index) => descriptionStr = (index === 0) ? 
                    descriptionStr = descriptionStr[0].toUpperCase() + descriptionStr.slice(1).toLowerCase() : 
                    descriptionStr = descriptionStr.toLowerCase()).join( ", " )}
            </p>
            <p class="product__price">${element.price}$</p>
            <button class="product__btn" id="${element.id}"><i class="fas fa-plus"></i></button>
            `;
        return elem;
    });

    const productListBlock = document.querySelector(".product-list");
    for (let product of productItems) {
        productListBlock.appendChild(product);
    }
}
//this code is in other file after calling function createProductsList
let test = document.getElementsByClassName('product__btn');
test.forEach(el=> console.log(el));
console.log(test, test[0]);

标签: javascript

解决方案


你不能使用 forEach 的原因是 getElementsByClassName 返回一个 HTMLCollection——而不是一个数组(因此没有原型方法)。

要解决此问题,您可以使用将集合中的每个节点添加到实际数组中[].slice.call(document.getElementsByClassName('xxx'))

笔记!因为 forEach 将函数作为参数,您可以简单地传递 console.log 以使用元素自动调用...test.forEach(console.log)test.forEach(el => console.log(el))

PS。我冒昧地更改了代码:-)

createProductList('Category', [{
    photo: '//unsplash.it/160/160?random=1',
    title: 'Product one',
    price: 1000,
    id: 'A',
    composition: ['foo', 'bar']
  },
  {
    photo: '//unsplash.it/160/160?random=2',
    title: 'Product Two',
    price: 500,
    id: 'B',
    composition: ['baz', 'qux']
  }
]);



function createProductList(categoryName, productList) {

  const categoryElm = document.querySelector('.category');
  const productsElm = document.querySelector('.product-list');


  categoryElm.innerHTML = `<p class="category__name">${ categoryName }</p>`;

  productList.reduce((list, product) => {
    list.innerHTML += `
      <div class="product">
        <img class="product__image" src="${ product.photo }" alt="">
        <p class="product__name">
        ${	
        product.title.split("")
          .map((title, index) => index ? 
            title.toLowerCase() : 
            title.toUpperCase()
          ).join("") 
        }
        </p>
        <p class="product__description">
        ${
        product.composition
          .map((descr, index) => index ? 
            descr.toLowerCase() :
            descr[0].toUpperCase() + descr.slice(1).toLowerCase()
          ).join( ", " )
        }
        </p>
        <p class="product__price">${ product.price }$</p>
        <button class="product__btn" id="${ product.id }">
          <i class="fas fa-plus"></i>
        </button>
      </div>
		`
    return list;
  }, productsElm)
}


//this code is in other file after calling function createProductsList
let test = [].slice.call(document.getElementsByClassName('product__btn'));
test.forEach(console.log);
console.log(test[0], test[1])
* {
  box-sizing: border-box;
}

.category {
  font-size: 1.5em;
  color: orangered;
}

.product-list,
.product {
  border: 1px solid #ccc;
  padding: .5rem;
  margin: .5rem;
}
<div class="category"></div>
<div class="product-list"></div>


推荐阅读