简体   繁体   English

遍历多个元素并计算每个元素的价格折扣

[英]Looping through multiple elements and calculating price discount for each

I am trying to find the percentage difference between the old and new price of each individual <div> .我试图找到每个<div>的旧价格和新价格之间的百分比差异。 At the minute, my code is only pulling through the percentage difference of the first <div> and looping the same percentage difference to the rest of the <div> s.目前,我的代码只是提取第一个<div>的百分比差异,并将相同的百分比差异循环到<div>的 rest。 Does anyone know how I can update this to target each individual <div> rather than just looping through the first one?有谁知道我如何更新它以针对每个<div>而不是只循环第一个? I would like to do this in pure JavaScript;我想在纯 JavaScript 中执行此操作; no jQuery please.没有 jQuery 请。

 const priceDifference = () => { const regPrice = document.querySelector('.old').innerText; const salePrice = document.querySelector('.new').innerText; const priceNumReg = parseFloat(regPrice.substring(1)); const priceNumSale = parseFloat(salePrice.substring(1)); const finalPrice = priceNumReg - priceNumSale; const percentage = document.querySelectorAll('.percentage'); const percent = (finalPrice / priceNumReg) * 100; for (i = 0; i < percentage.length; i++) { if (percentage[i].textContent.trim() === '') { percentage[i].textContent += ' (' + percent.toFixed(0) + '% OFF)'; } } }; priceDifference();
 <div class="price"> <div class="old">$14.00</div> <div class="new">$6.00</div> <div class="percentage"></div> </div> <div class="price"> <div class="old">$12.00</div> <div class="new">$5.00</div> <div class="percentage"></div> </div> <div class="price"> <div class="old">$18.00</div> <div class="new">$3.00</div> <div class="percentage"></div> </div>

You have to loop through each .price element, not each .percentage , since each individual calculation you're trying to perform is based on the scope of a single <div class="price"> .您必须遍历每个.price元素,而不是每个.percentage ,因为您尝试执行的每个单独计算都基于单个<div class="price">的 scope。 Do all the calculations inside the loop, say for the current priceElement (which is one of your <div class="price"> elements).在循环进行所有计算,例如当前的priceElement (这是您的<div class="price">元素之一)。 Now you can use priceElement.querySelector , instead of document.querySelector .现在您可以使用priceElement.querySelector代替document.querySelector document.querySelector finds the first matching element in the entire document, whereas priceElement.querySelector will find the first matching element inside that scope: priceElement . document.querySelector查找整个文档中的第一个匹配元素,而priceElement.querySelector将查找 scope: priceElement中的第一个匹配元素。

So the function would look more like this:所以 function 看起来更像这样:

const priceDifference = () => {
  const price = document.querySelectorAll(".price");

  for (i = 0; i < price.length; i++) {
    const priceElement = price[i];

    const regPrice = priceElement.querySelector(".old").innerText;
    const salePrice = priceElement.querySelector(".new").innerText;
    const percentage = priceElement.querySelector(".percentage");

    const priceNumReg = parseFloat(regPrice.substring(1));
    const priceNumSale = parseFloat(salePrice.substring(1));

    const finalPrice = priceNumReg - priceNumSale;
    const percent = (finalPrice / priceNumReg) * 100;
    
    if (percentage.textContent.trim() === '') {
      percentage.textContent += ' (' + percent.toFixed(0) + '% OFF)';
    }
  }
};

This code works , but there's still a bit of work that needs to be done, eg the missing declaration for i and innerText vs. textContent , but this code can also be shortened like this:这段代码有效,但还有一些工作需要完成,例如缺少iinnerTexttextContent的声明,但这段代码也可以像这样缩短:

 const parseCurrencyValue = ({ textContent }) => Number.parseFloat(textContent.replace(/^[^-+0-9.]*/u, "")), priceDifference = () => Array.from(document.querySelectorAll(".price")).forEach((priceElement) => { const [ regularPrice, salePrice ] = [ ".old", ".new" ].map((selector) => parseCurrencyValue(priceElement.querySelector(selector))), discount = 1 - (salePrice / regularPrice), percentageElement = priceElement.querySelector(".percentage"); if (percentageElement.textContent.trim() === "") { percentageElement.insertAdjacentText("beforeend", ` (${Math.round(discount * 100)} % off)`); } }); priceDifference();
 .percentage { text-transform: uppercase; }
 <div class="price"> <div class="old">$14.00</div> <div class="new">$6.00</div> <div class="percentage"></div> </div> <div class="price"> <div class="old">$12.00</div> <div class="new">$5.00</div> <div class="percentage"></div> </div> <div class="price"> <div class="old">$18.00</div> <div class="new">$3.00</div> <div class="percentage"></div> </div>

I've grouped the const s, used some destructuring and template literals , and avoided some code repetition.我对const进行了分组,使用了一些解构模板文字,并避免了一些代码重复。 I've used a map over the selectors .new and .old since they need to be treated identically;我在选择器.new.old上使用了map ,因为它们需要被同等对待; this is how you would generally avoid code repetition: put everything that is the same into its own set of functions, and iterate only over the stuff that changes, passing it as arguments to the function. The discount calculation can also be simplified.这是通常避免代码重复的方法:将相同的所有内容放入其自己的一组函数中,并仅迭代更改的内容,将其作为 arguments 传递给 function。折扣计算也可以简化。

But most importantly:但最重要的是:

You should use Array.from( some NodeList ).forEach to iterate over the result of querySelectorAll .您应该使用Array.from( some NodeList ).forEach来迭代querySelectorAll的结果。 This is a bit more robust since you don't need to mess around with for loop syntax anymore;这会更健壮一些,因为您不再需要弄乱for循环语法; the syntax is more expressive this way.这种语法更具表现力。

You should split the process of parsing text as a price into its own function;您应该将解析文本作为价格的过程拆分为它自己的 function; that's parseCurrencyValue in my example.在我的例子中是parseCurrencyValue I've also used a more robust regular expression that'll work for strings like "$ 12.99" , "USD 12.99" , "12.99 $" , etc., by removing anything that isn't part of a number from the start, then using Number.parseFloat .我还使用了一个更强大的正则表达式,它适用于"$ 12.99""USD 12.99""12.99 $"等字符串,方法是从一开始就删除不属于数字的任何内容,然后使用Number.parseFloat

You should not put “OFF” literally into a string.您不应将“OFF”字面意思放入字符串中。 You're trying to communicate that something is 50 percent off , so the correct spelling would be “off”.您正试图传达某物有50% off的意思,因此正确的拼写应该是“off”。 Transforming this into all-caps should be done in CSS;将其转换为全部大写应该在 CSS 中完成; this way it's more accessible and screen readers don't get confused by what “ OFF ” might be.这样它更容易访问,屏幕阅读器不会对“ OFF ”可能是什么感到困惑。

There might also be some semantic HTML improvements, but this requires a bit more context.可能还有一些语义 HTML 改进,但这需要更多的上下文。 Ideally, the data is structured in a table, not in some arbitrary <div> s.理想情况下,数据在表格中进行结构化,而不是在一些任意的<div>中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM