如何使用JavaScript中的事件监听器在HTML中显示文本到特定句子?

huangapple go评论64阅读模式
英文:

How do i display texts to a particular sentence in the HTML using event-listener in javascript?

问题

以下是您要翻译的内容:

"我在处理一个特定项目的DOM时遇到了困难。
我的目标是在单击时获取每张卡片的标题,并显示在下方的摘要空白处:“订单摘要”。

遇到的问题:

  • 前三张卡片是唯一正常工作的,而其余卡片在尝试使用console.log时一直抛出类型错误,我无法找到问题所在,因为控制台在每次单击时都显示了每个卡片的详细信息。但当我尝试显示除前三张卡片之外的特定卡片的innerText时,它会在单击这些卡片时抛出错误,但在前三张卡片上却正常工作,我不知道这是如何可能的,因为前三张卡片之后都没有任何类。

我将在下面提供代码,我已经稍微进行了一些样式设置,以便您可以在CodePen上复制并粘贴进行测试。非常感谢。

以下是HTML代码:

<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  
    <div class="steps__wrapper">
         <div class="steps__track plans__option">
          <div class="steps__title">
            <h1>How do you drink your coffee?</h1>
            <img src="images/icon-arrow.20551347.svg" alt="arrow icon" class="arrow-icon">
          </div>
         <div class="plan-option-container">
          <div class="plan-wrapper">
            <div class="product__plan">
             <h2  class="product__plan--title brewed-type">Capsule</h2>
             <p  class="product__plan--description">Compatible with Nespresso systems and similar brewers</p>
            </div>
            <div class="product__plan">
             <h2  class="product__plan--title brewed-type">Filter</h2>
             <p  class="product__plan--description">For pour over or drip methods like Aeropress, Chemex, and V60</p>
            </div>
            <!-- 还有更多卡片 -->
           </div>
         </div>
         </div>
         <!-- 其他步骤和卡片 -->
         <div class="summary">
            <h1 class="summary__title">ORDER SUMMARY</h1>
          <p>
            “我会喝&lt;span class=&quot;drink-style style&quot;&gt;_____&lt;/span&gt;,用&lt;span class=&quot;type style&quot;&gt;_____&lt;/span&gt; 类别
            的咖啡豆。&lt;span class=&quot;quantity style&quot;&gt;_____&lt;/span&gt; 磨成&lt;span class=&quot;grind style&quot;&gt;_____&lt;/span&gt;,寄给我&lt;span class=&quot;delivery  style&quot;&gt;_____&lt;/span&gt;。”&lt;/span&gt;
          </p>
          </div>
         </div>
          </div>
</body>
</html>

我对CSS进行了一些快速样式设置,以帮助您更快地解决问题:

.plan-wrapper {
  display: flex;
  justify-content: space-between;
}
.product__plan {
  border: 1em solid red;
  background: red;
  margin: 1em;
}

JavaScript代码如下:

let planCards = document.getElementsByClassName("product__plan");
let brewedTypes = document.getElementsByClassName("brewed-type");
let coffeeTypes = document.querySelectorAll(".coffee-type");
let coffeeQuantity = document.getElementsByClassName("coffee-quantity");
let coffeeProcess = document.getElementsByClassName("coffee-process");
let coffeeDelivery = document.getElementsByClassName("coffee-delivery");

for (let i = 0; i < planCards.length; i++) {
  planCards[i].addEventListener("click", () => {
    // 获取元素的innerText并显示在订单摘要中
    let brewedTypesEl = brewedTypes[i].innerText;
    document.querySelector(".drink-style").innerText = brewedTypesEl;
    let coffeeTypesEl = coffeeTypes[i].innerText;
    document.querySelector(".type").innerText = coffeeTypesEl;
    let coffeeQuantityEl = coffeeQuantity[i].innerText;
    document.querySelector(".quantity").innerText = coffeeQuantityEl;
    let coffeeProcessEl = coffeeProcess[i].innerText;
    document.querySelector(".grind").innerText = coffeeProcessEl;
    let coffeeDeliveryEl = coffeeDelivery[i].innerText;
    document.querySelector(".delivery").innerText = coffeeDeliveryEl;
  });
}

希望这可以帮助您解决问题。

英文:

I am having difficulty working with DOM for a paticular project that i am working on.
My goal is to get the header name of each cards when clicked and displaying in the blank space of the summary below it "Order Summary.

Problem Encoutered:

  • The first three cards are the only ones working right while the rest keeps throwing type error when i tried using console.log and i couldn't find what the issue is cause console showed me each individual details for the cards at each click but when i try to display the innertext of a particular cards aside the first three cards, it throws error when i click on the those cards but works fine with the first three cards which i do not know how that was even possible since the first three cards do not own any of the classes after them.

I will be providing the code below of which i have given a little style in case you want to copy and paste on code pen to test. Thank you so much.

Here is the HTML CODE

&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
&lt;meta charset=&quot;UTF-8&quot;&gt;
&lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
&lt;title&gt;Document&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class=&quot;steps__wrapper&quot;&gt;
&lt;div class=&quot;steps__track plans__option&quot;&gt;
&lt;div class=&quot;steps__title&quot;&gt;
&lt;h1&gt;How do you drink your coffee?&lt;/h1&gt;
&lt;img src=&quot;images/icon-arrow.20551347.svg&quot; alt=&quot;arow icon&quot; class=&quot;arrow-icon&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;plan-option-container&quot;&gt;
&lt;div class=&quot;plan-wrapper&quot;&gt;
&lt;!--I ADDED EVENT LISTENER TO THE CARD--&gt;
&lt;!--THERE ARE 15 CARDS IN TOTAL--&gt;
&lt;div class=&quot;product__plan&quot;&gt;
&lt;!--H2 HERE IS THE TITLE CLASS I WANT TO EXTRACT--&gt;
&lt;h2  class=&quot;product__plan--title brewed-type&quot;&gt;Capsule&lt;/h2&gt;
&lt;p  class=&quot;product__plan--description&quot;&gt;Compatible with Nespresso systems and similae brewers&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;product__plan&quot;&gt;
&lt;h2  class=&quot;product__plan--title  brewed-type&quot;&gt;Filter&lt;/h2&gt;
&lt;p  class=&quot;product__plan--description&quot;&gt;For pour over or drip methods like Aeropress, Chemex, and V60&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;product__plan&quot;&gt;
&lt;h2  class=&quot;product__plan--title brewed-type&quot;&gt;Espresso&lt;/h2&gt;
&lt;p  class=&quot;product__plan--description&quot;&gt;Dense and finely ground beans for an intense, flavoful experience&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;steps__track plans__option&quot;&gt;
&lt;div class=&quot;steps__title&quot;&gt;
&lt;h1&gt;What type of coffee?&lt;/h1&gt;
&lt;img src=&quot;images/icon-arrow.20551347.svg&quot; alt=&quot;arow icon&quot; class=&quot;arrow-icon&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;plan-option-container&quot;&gt;
&lt;div class=&quot;plan-wrapper&quot;&gt;
&lt;div class=&quot;product__plan&quot;&gt;
&lt;h2  class=&quot;product__plan--title coffee-type&quot; &gt;Single Origin&lt;/h2&gt;
&lt;p  class=&quot;product__plan--description&quot;&gt;Distinct, high quality coffee from a specific family-owned farm.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;product__plan&quot;&gt;
&lt;h2  class=&quot;product__plan--title coffee-type&quot; &gt;Decaf&lt;/h2&gt;
&lt;p  class=&quot;product__plan--description&quot;&gt;Just like regular coffee, except the caffeine has been removed&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;product__plan&quot;&gt;
&lt;h2  class=&quot;product__plan--title coffee-type&quot; &gt;Blended&lt;/h2&gt;
&lt;p  class=&quot;product__plan--description&quot;&gt;Combination of two or three dark roasted beans of organic coffees&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;steps__track plans__option&quot;&gt;
&lt;div class=&quot;steps__title&quot;&gt;
&lt;h1&gt;How much would you like&lt;/h1&gt;
&lt;img src=&quot;images/icon-arrow.20551347.svg&quot; alt=&quot;arow icon&quot; class=&quot;arrow-icon&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;plan-option-container&quot;&gt;
&lt;div class=&quot;plan-wrapper&quot;&gt;
&lt;div class=&quot;product__plan &quot;&gt;
&lt;h2  class=&quot;product__plan--title coffee-quantity&quot;&gt;250g&lt;/h2&gt;
&lt;p  class=&quot;product__plan--description&quot;&gt;Perfect for the solo drinker. Yield about 12 delicious cups.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;product__plan &quot;&gt;
&lt;h2  class=&quot;product__plan--title coffee-quantity&quot;&gt;500g&lt;/h2&gt;
&lt;p  class=&quot;product__plan--description&quot;&gt;Perfect option for a couple. Yields about 40 delectable cups.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;product__plan &quot;&gt;
&lt;h2  class=&quot;product__plan--title coffee-quantity&quot;&gt;1000g&lt;/h2&gt;
&lt;p  class=&quot;product__plan--description&quot;&gt;Perfect for offices and events. Yield about 90 delightful cups.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;steps__track plans__option grinding&quot;&gt;
&lt;div class=&quot;steps__title&quot;&gt;
&lt;h1&gt;Want us to grind them?&lt;/h1&gt;
&lt;img src=&quot;images/icon-arrow.20551347.svg&quot; alt=&quot;arow icon&quot; class=&quot;arrow-icon&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;plan-option-container&quot;&gt;
&lt;div class=&quot;plan-wrapper&quot;&gt;
&lt;div class=&quot;product__plan&quot;&gt;
&lt;h2  class=&quot;product__plan--title coffee-process&quot;&gt;Wholebean&lt;/h2&gt;
&lt;p  class=&quot;product__plan--description&quot;&gt;Best choice if you cherish the full sensory experience&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;product__plan&quot;&gt;
&lt;h2  class=&quot;product__plan--title coffee-process&quot;&gt;Filter&lt;/h2&gt;
&lt;p  class=&quot;product__plan--description&quot;&gt;For drip or pour-over coffee methods such as V60 or Aeropresso&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;product__plan&quot;&gt;
&lt;h2  class=&quot;product__plan--title coffee-process&quot; &gt;
Cafeti&#233;re&lt;/h2&gt;
&lt;p  class=&quot;product__plan--description&quot;&gt;Course ground beans specially suited for french press coffee&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;steps__track plans__option&quot;&gt;
&lt;div class=&quot;steps__title&quot;&gt;
&lt;h1&gt;How often do we deliver?&lt;/h1&gt;
&lt;img src=&quot;images/icon-arrow.20551347.svg&quot; alt=&quot;arow icon&quot; class=&quot;arrow-icon&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;plan-option-container&quot;&gt;
&lt;div class=&quot;plan-wrapper&quot;&gt;
&lt;div class=&quot;product__plan &quot;&gt;
&lt;h2  class=&quot;product__plan--title coffee-delivery&quot;&gt;Every week&lt;/h2&gt;
&lt;p  class=&quot;product__plan--description price-plan&quot;&gt;&lt;span class=&quot;price&quot;&gt;$7.20&lt;/span&gt; per shipment. Includes free first-class shipping&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;product__plan &quot;&gt;
&lt;h2  class=&quot;product__plan--title coffee-delivery&quot;&gt;Every 2 week&lt;/h2&gt;
&lt;p class=&quot;product__plan--description price-plan&quot;&gt;&lt;span id=&quot;price&quot;&gt;$9.60&lt;/span&gt; per shipment. Includes free priority shipping.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;product__plan &quot;&gt;
&lt;h2 class=&quot;product__plan--title coffee-delivery&quot;&gt;Every month&lt;/h2&gt;
&lt;p class=&quot;product__plan--description price-plan&quot;&gt;&lt;span id=&quot;price&quot;&gt;$12.00&lt;/span&gt; per shipment includes free priority shipping&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;summary&quot;&gt;
&lt;!--ORDER SUMMARY WHERE I WANT TO DISPLAY THE INNERTEXT TAKEN FROM THE TITLE--&gt;
&lt;h1 class=&quot;summary__title&quot;&gt;ORDER SUMMARY&lt;/h1&gt;
&lt;p&gt;
“I drink my coffee as &lt;span class=&quot;drink-style style&quot;&gt;_____&lt;/span&gt;, with a &lt;span class=&quot;type style&quot;&gt; _____&lt;/span&gt; type
of bean. &lt;span class=&quot;quantity style&quot;&gt;_____&lt;/span&gt;  ground ala &lt;span class=&quot;grind style&quot;&gt;_____&lt;/span&gt; , sent to me&lt;span class=&quot;delivery  style&quot;&gt;_____&lt;/span&gt;.”&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;

"

I gave the CSS a little quick styling to help you help me figure my problem out faster

.plan-wrapper{
display:flex;
justify-content:space-between;
}
.product__plan{
border.1em solid red;
background:red;
margin:1em ;
}

The javscript code:

let planCards=document.getElementsByClassName(&quot;product__plan&quot;)
let brewedTypes=document.getElementsByClassName(&quot;brewed-type&quot;)
let coffeeTypes=document.querySelectorAll(&quot;.coffee-type&quot;)
let coffeeQuantity=document.getElementsByClassName(&quot;coffee-quantity&quot;)
let coffeeProcess=document.getElementsByClassName(&quot;coffee-process&quot;)
let coffeeDelivery=document.getElementsByClassName(&quot;coffee-delivery&quot;)
for(let i=0;i&lt;planCards.length;i++){
planCards[i].addEventListener(&quot;click&quot;,()=&gt;{
//GET THE INNERTEXT OF THE ELEMENT AND DISPLAY IT THE ORDER SUMMARY
let brewedTypesEl=brewedTypes[i].innerText
document.querySelector(&quot;.drink-style&quot;).innerText=brewedTypesEl
let coffeeTypesEl=coffeeTypes[i].innerText
document.querySelector(&quot;.type&quot;).innerText=coffeeTypesEl
let coffeeQuantityEl=coffeeQuantity[i].innerText
document.querySelector(&quot;.quantity&quot;).innerText=coffeeQuantityEl
let coffeeProcessEl=coffeeProcess[i].innerText
document.querySelector(&quot;.grind&quot;).innerText=coffeeProcessEl
let coffeeDeliveryEl=coffeeDelivery[i].innerText
document.querySelector(&quot;.delivery&quot;).innerText=coffeeDeliveryEl
})
}```
</details>
# 答案1
**得分**: 0
你的代码问题在于你尝试使用相同的索引访问不同数组的元素。在你的情况下,brewedTypes、coffeeTypes、coffeeQuantity、coffeeProcess 和 coffeeDelivery 数组的长度不同,但你尝试在事件监听回调函数中使用相同的索引访问它们的元素。
数组 planCards 由所有 .product__plan 元素组成,总共有 15 张卡片,而其他数组 brewedTypes、coffeeTypes、coffeeQuantity、coffeeProcess 和 coffeeDelivery 的长度不等于 15。因此,在这些数组的长度之外的索引处,你会得到一个错误。
一个解决方案是确保每个卡片只监听点击事件,以更新订单摘要的相应部分。
像这样:
```javascript
let planCards = document.getElementsByClassName("product__plan")
// 获取卡片标题的函数
const getTitle = (element) => {
return element.querySelector('.product__plan--title').innerText;
}
for (let i = 0; i < planCards.length; i++) {
planCards[i].addEventListener("click", () => {
let title = getTitle(planCards[i]);
// 根据标题的类别将标题分配到摘要的正确部分
if (planCards[i].querySelector('.product__plan--title').classList.contains('brewed-type')) {
document.querySelector(".drink-style").innerText = title;
} else if (planCards[i].querySelector('.product__plan--title').classList.contains('coffee-type')) {
document.querySelector(".type").innerText = title;
} else if (planCards[i].querySelector('.product__plan--title').classList.contains('coffee-quantity')) {
document.querySelector(".quantity").innerText = title;
} else if (planCards[i].querySelector('.product__plan--title').classList.contains('coffee-process')) {
document.querySelector(".grind").innerText = title;
} else if (planCards[i].querySelector('.product__plan--title').classList.contains('coffee-delivery')) {
document.querySelector(".delivery").innerText = title;
}
})
}

每当点击卡片时,都会调用 getTitle 函数以获取卡片标题的文本。然后,它检查标题包含的类别,然后更新订单摘要的相应部分。这个解决方案确保只有在点击卡片时才更新订单摘要的适当部分。

英文:

The issue with your code is that you are trying to access elements from different arrays with the same index. In your case, the brewedTypes, coffeeTypes, coffeeQuantity, coffeeProcess, and coffeeDelivery arrays have different lengths, yet you're trying to access their elements using the same index within the event listener callback function.

The array planCards is composed of all the .product__plan elements which sum up to 15 cards while the other arrays: brewedTypes, coffeeTypes, coffeeQuantity, coffeeProcess, and coffeeDelivery have lengths that are not equal to 15. Thus, for indices beyond the length of these arrays, you get an error.

A solution would be to ensure that each card only listens for the click event to update the appropriate part of the order summary.

Like so:

let planCards = document.getElementsByClassName(&quot;product__plan&quot;)
//Function to get the title of a card
const getTitle = (element) =&gt; {
return element.querySelector(&#39;.product__plan--title&#39;).innerText;
}
for (let i = 0; i &lt; planCards.length; i++) {
planCards[i].addEventListener(&quot;click&quot;, () =&gt; {
let title = getTitle(planCards[i]);
//Assign the title to the correct part of the summary based on the class of the title
if (planCards[i].querySelector(&#39;.product__plan--title&#39;).classList.contains(&#39;brewed-type&#39;)) {
document.querySelector(&quot;.drink-style&quot;).innerText = title;
} else if (planCards[i].querySelector(&#39;.product__plan--title&#39;).classList.contains(&#39;coffee-type&#39;)) {
document.querySelector(&quot;.type&quot;).innerText = title;
} else if (planCards[i].querySelector(&#39;.product__plan--title&#39;).classList.contains(&#39;coffee-quantity&#39;)) {
document.querySelector(&quot;.quantity&quot;).innerText = title;
} else if (planCards[i].querySelector(&#39;.product__plan--title&#39;).classList.contains(&#39;coffee-process&#39;)) {
document.querySelector(&quot;.grind&quot;).innerText = title;
} else if (planCards[i].querySelector(&#39;.product__plan--title&#39;).classList.contains(&#39;coffee-delivery&#39;)) {
document.querySelector(&quot;.delivery&quot;).innerText = title;
}
})
}

When each card is clicked, the function getTitle is called to get the inner text of the title of the card. It then checks which class the title contains and then updates the appropriate part of the order summary. This solution ensures that only the appropriate part of the order summary is updated when a card is clicked.

huangapple
  • 本文由 发表于 2023年5月31日 23:40:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76375217.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定