微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何修复嵌套 forEach

如何解决如何修复嵌套 forEach

我正在练习 DOM 操作(纯香草 JS),我需要检查所有价格,如果其中任何价格超过 3,00 英镑,则整个产品卡应将其背景颜色更改为红色。 由于某些未知原因,如果我只更改价格 div,代码运行良好,但是,当我尝试针对整张卡时,它会将所有卡更改为红色,而不仅仅是价格超过 £ 的卡3,00

我不知道我做错了什么。任何帮助将不胜感激

这里还有从控制台测试代码链接: :https://www.monoprix.fr/courses/legumes-frais-mpx_c0000400?page=3

这是我的片段:

function exercise_3() {
  var price = document.querySelectorAll(".grocery-item__normal-price");
  var block = document.querySelectorAll(".grocery-item-item");
  let changePriceColor = 300;

  block.forEach((card) => {
    price.forEach((p) => {
      var a = p.innerText.slice(0,4).replace(/,/g,"");
      if (a > changePriceColor) {
        card.style.background = "red";
      } else {
        return "";
      }
    });
  });
}

exercise_3();
<div class="grocery-item-item">
  <div class="grocery-item__description-offre">
    <a href="/courses/artichaut-blanc--2414383-p">
      <div class="grocery-item__description-wrapper">
        <div class="grocery-item__dimmer"></div>
        <div class="grocery-item__product-card-content discount">
          <div class="grocery-item__product-img">
            <img 
              data-tc='["","tc_event_20",""]' 
              data-tcdata='{"tc_event_11":0,"tc_event_20":{"ecommerceGA":"product_click","productId":2414383,"quantity":0},"tc_event_39":{"action":"cross sell | undefined","position":0}}' 
              src="https://cdn.monoprix.fr/cdn-cgi/image/width=180,quality=60,format=auto,Metadata=none/assets/images/grocery/2414383/580x580.jpg"
              width="100" 
              height="100" 
              centered="true"
            >
          </div>
          <div class="grocery-item__description">
            <div class="grocery-item-brand">
              <p></p>
            </div>
            <div class="grocery-item-range">ARTICHAUT BLANC</div>
            <div class="conditioning-description">L'unité</div>
          </div>
        </div>
      </div>
      <div class="withPromotionBand-sc-1jbwr08-0 cfLNRM grocery-item__promotions_band">
        <div class="promo_map">
          <div class="promo_band _red">
            <div class="promo_red">-50%</div>
            sur le 2ème
          </div>
          {" "}
        </div>
      </div>
    </a>
  </div>
  <div class="grocery-item__price-cart">
    <div class="grocery-item__price-wrapper">
      <div class="grocery-item__price-line-through"></div>
      <div class="grocery-item__normal-price">2,00 €</div>
      <div class="grocery-item__price-unit">
        <p>2,00 € / p</p>
      </div>
    </div>
    <div class="styledAddToCartButton-sc-15efgme-0 fNiyOV">
      <div 
        class="add-to-cart-button__add-button" 
        id="addToCartButton-2414383" 
        value="AddToCart" 
        data-tc='["tc_event_20",""]' 
        data-tcdata='{"tc_event_20":{"ecommerceGA":"product_add","tc_event_38":{"position":0,"productId":2414383}}'
      >
        <img 
          src="/contents/images/cart_icon.svg" 
          width="40" 
          height="40" 
          alt="panier" 
          class="pannel"
        >
      </div>
    </div>
  </div>
</div>
</>
</>;

解决方法

问题是,对于所有卡,您总是查看所有价格。相反,您应该只查看当前卡内的价格。这可以通过 card.querySelectorAll 完成,其中 card 是当前块。

function exercise_3() {
  const blocks = document.querySelectorAll(".grocery-item-item");
  const changePriceColor = 300;

  blocks.forEach((card) => {
    const prices = card.querySelectorAll(".grocery-item__normal-price");
    prices.forEach((p) => {
      const a = p.innerText.slice(0,4).replace(/,/g,"");
      
      if (a > changePriceColor) {
        card.style.background = "red";
      } else {
        return "";
      }
    });
  });
}

exercise_3();
.grocery-item-item {
  border: 1px solid;
}
<div class="grocery-item-item">
     <div class="grocery-item__normal-price">2,00 €</div>
     <div class="grocery-item__normal-price">2,00 €</div>
</div>

<div class="grocery-item-item">
     <div class="grocery-item__normal-price">4,00 €</div>
</div>

<div class="grocery-item-item">
     <div class="grocery-item__normal-price">1,00 €</div>
</div>

,

您构建嵌套 for 循环的方式导致您遍历每张卡的所有价格。意思是对于第一张卡,您查看所有价格,不可避免地有一张高于 300,因此它变成红色,然后转到下一张卡,再次查看所有价格,找到高于 300 的一张,然后将该卡也变成红色,就这样一直下去,直到每张牌都变红

function exercise_3() {
  var price = document.querySelectorAll(".grocery-item__normal-price");
  let changePriceColor = 300;

  // So you don't need to run a forloop over the "block",// instead you could just find the closest '.grocery-item-item' 
  // to the price that meets your condition,and change its background
  price.forEach((p) => {
    var a = p.innerText.slice(0,"");
    if (a > changePriceColor) {
      const card = p.closest('.grocery-item-item')
      card.style.background = "red";
    } else {
      return "";
    }
  });

}

exercise_3();
,

注意:.forEach() 没有 return 任何东西

您可以在一个 .forEach() 方法中运行流控制语句,因为典型的 DOM 树是简单的父/子层次结构(<table> 是例外)。

以下函数传递3个参数:

  1. limit Number 与每个值进行比较的实数浮点数或整数
  2. priceTag String 包含文本或具有价格值属性(表单控件)的元素的 CSS 选择器
  3. itemCard String 包含 priceTag
  4. 的元素的 CSS 选择器

tooExpensive()

  1. 将所有 priceTag 收集到一个 NodeList 中
    const prices = document.querySelectorAll(priceTag);
    
  2. 然后将NodeList转成数组通过.forEach()运行
    [...prices].forEach(node => {...
    
  3. 接下来它确定要提取的字符串类型以及是否存在任何一个:
    // <div>textContent</div> <!--or--> <input value="value">
    
    let text = node.textContent || node.value;
    if (text.length > 0) {...
    
  4. 当有值时,所有的逗号“,”都被点号“.”代替,然后除数字和点号外的所有字符都被去掉。
    let price = text.replaceAll(',','.').split(/[^0-9.]/).join(''); 
    
  5. 接下来,它确定 priceTag 是否有一个 itemCard 作为祖先
    let parent = node.closest(itemCard);
    
  6. 最后,如果价格大于限制itemCard(或parent)确实存在,通过添加类{{ 1}}
    .red

if (parseFloat(price) > limit && parent) {
  parent.classList.add('red');
}
const tooExpensive = (limit,priceTag,itemCard) => {
  const prices = document.querySelectorAll(priceTag);
  [...prices].forEach(node => {
    let text = node.textContent || node.value;
    if (text.length > 0) {
      let price = text.replaceAll(','.').split(/[^0-9.]/).join('');
      //console.log(price);
      let parent = node.closest(itemCard);
      if (parseFloat(price) > limit && parent) {
        parent.classList.add('red');
      }
    }
  });
};

tooExpensive(3,'.price','.item');
.item {
  width: min-content;
  padding: 5px 10px;
  margin: 5px 0;
  border: 1px black solid;
}

.red {
  background: red;
  color: white;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。