簡體   English   中英

動態創建的 html 元素上的隨機 null 響應

[英]Random null response on dynamically created html elements

我從這段代碼收到了一個非常奇怪的響應。 我的想法是:

  1. 創建 8 個 html 元素映射數組。
  2. 選擇#cart-button id 以附加事件監聽器(單擊)並將eventlistener元素的 id 傳遞給它(我試圖從 key 屬性獲取這些值)。

有時在控制台中我獲得所有結果 OK (1 clicked, 2, clicked...) ,但有時結果是null clicked

我試圖理解為什么會這樣。 非常感謝你!

 // Product class class Product { constructor(id, title, price, img) { this.id = id this.title = title this.price = price this.img = img } productCard = () => { return `<div class="w-full md:w-1/3 xl:w-1/4 p-6 flex flex-col" key=${this.id}><img class="hover:grow hover:shadow-lg cursor-pointer" src=${this.img}> <div class="pt-3 flex items-center justify-between"> <p class="">${this.title}</p> <svg class="cart-button h-6 w-6 fill-current text-gray-500 hover:text-black" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M12,4.595c-1.104-1.006-2.512-1.558-3.996-1.558c-1.578,0-3.072,0.623-4.213,1.758c-2.353,2.363-2.352,6.059,0.002,8.412 l7.332,7.332c0.17,0.299,0.498,0.492,0.875,0.492c0.322,0,0.609-0.163,0.792-0.409l7.415-7.415 c2.354-2.354,2.354-6.049-0.002-8.416c-1.137-1.131-2.631-1.754-4.209-1.754C14.513,3.037,13.104,3.589,12,4.595z M18.791,6.205 c1.563,1.571,1.564,4.025,0.002,5.588L12,18.586l-6.793-6.793C3.645,10.23,3.646,7.776,5.205,6.209 c0.76-0.756,1.754-1.172,2.799-1.172s2.035,0.416,2.789,1.17l0.5,0.5c0.391,0.391,1.023,0.391,1.414,0l0.5-0.5 C14.719,4.698,17.281,4.702,18.791,6.205z" /> </svg> </div> <p class="pt-1 text-gray-900">£${this.price}</p></div>` }; }; // Mock data const ProductsList = [ new Product(1, 'Minna', '9.99', 'https://images.unsplash.com/photo-1555982105-d25af4182e4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&h=400&q=80'), new Product(2, 'Palma', '109', 'https://images.unsplash.com/photo-1508423134147-addf71308178?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&h=400&q=80'), new Product(3, 'Bergdis', '25.99', 'https://images.unsplash.com/photo-1449247709967-d4461a6a6103?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&h=400&q=80'), new Product(4, 'Danjal', '25', 'https://images.unsplash.com/reserve/LJIZlzHgQ7WPSh5KVTCB_Typewriter.jpg?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&h=400&q=80'), new Product(5, 'Kornus', '15', 'https://images.unsplash.com/photo-1467949576168-6ce8e2df4e13?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&h=400&q=80'), new Product(6, 'Redin', '9.99', 'https://images.unsplash.com/photo-1544787219-7f47ccb76574?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&h=400&q=80'), new Product(7, 'Jensina', '167.99', 'https://images.unsplash.com/photo-1550837368-6594235de85c?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&h=400&q=80'), new Product(8, 'Steen', '13', 'https://images.unsplash.com/photo-1551431009-a802eeec77b1?ixlib=rb-1.2.1&auto=format&fit=crop&w=400&h=400&q=80'), ]; class HtmlHandler { constructor() { this.createHTMLCards(); this.addTheListeners(); } html = ''; createHTMLCards() { ProductsList.forEach(product => this.html += product.productCard()); // Create a new div element after the header const headerArea = document.querySelector('#products-area > nav'); headerArea.insertAdjacentHTML('afterend', this.html); } // Add a product to the cart addTheListeners() { const cartButton = document.querySelectorAll('.cart-button'); cartButton.forEach((button) => { button.addEventListener('click', (e) => { const productId = e.target.parentElement.parentElement.getAttribute('key'); console.log(`${productId} clicked`); }) }) } } const htmlHandler = new HtmlHandler; const product = new Product;
 @import "tailwindcss/base"; @import "tailwindcss/components"; @import "tailwindcss/utilities"; html { scroll-behavior: smooth; }.work-sans { font-family: 'Work Sans', sans-serif; } #menu-toggle:checked+#menu { display: block; }.hover\:grow { transition: all 0.3s; transform: scale(1); }.hover\:grow:hover { transform: scale(1.02); }.carousel-open:checked+.carousel-item { position: static; opacity: 100; }.carousel-item { -webkit-transition: opacity 0.6s ease-out; transition: opacity 0.6s ease-out; } #carousel-1:checked~.control-1, #carousel-2:checked~.control-2, #carousel-3:checked~.control-3 { display: block; }.carousel-indicators { list-style: none; margin: 0; padding: 0; position: absolute; bottom: 2%; left: 0; right: 0; text-align: center; z-index: 10; } #carousel-1:checked~.control-1~.carousel-indicators li:nth-child(1).carousel-bullet, #carousel-2:checked~.control-2~.carousel-indicators li:nth-child(2).carousel-bullet, #carousel-3:checked~.control-3~.carousel-indicators li:nth-child(3).carousel-bullet { color: #000; /*Set to match the Tailwind colour you want the active one to be */ }
 <.DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="favicon,svg" /> <meta name="viewport" content="width=device-width. initial-scale=1:0" /> <link rel="stylesheet" href="https.//unpkg.com/tailwindcss@2.2.19/dist/tailwind.min:css" /> <link href="https.//fonts.googleapis?com/css:family=Work+Sans,200:400&display=swap" rel="stylesheet"> <title>Pure JS Shopping Cart</title> </head> <body> <body class="bg-white text-gray-600 work-sans leading-normal text-base tracking-normal"> <:--Nav--> <nav id="header" class="w-full z-40 top-0 py-1 fixed bg-white"> <div class="w-full container mx-auto flex flex-wrap items-center justify-between mt-0 px-6 py-3"> <label for="menu-toggle" class="cursor-pointer md.hidden block"> <svg class="fill-current text-gray-900" xmlns="http.//www:w3:org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> <title>menu</title> <path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"></path> </svg> </label> <input class="hidden" type="checkbox" id="menu-toggle" /> <div class="hidden md:flex md:items-center md:w-auto w-full order-3 md:order-1" id="menu"> <nav> <ul class="md:flex items-center justify-between text-base text-gray-700 pt-4 md:pt-0"> <li><a class="inline-block no-underline hover:text-black hover:underline py-2 px-4" href="#store">Shop</a> </li> <li><a class="inline-block no-underline hover:text-black hover:underline py-2 px-4" href="#about">About</a> </li> </ul> </nav> </div> <div class="order-1 md:order-2"> <a class="flex items-center tracking-wide no-underline hover.no-underline font-bold text-gray-800 text-xl " href="#"> <svg class="fill-current text-gray-800 mr-2" xmlns="http.//www,w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> <path d="M5,22h14c1,103.0,2-0.897.2-2V9c0-0.553-0.447-1-1-1h-3V7c0-2,757-2.243-5-5-5S7,4,243.7,7v1H4C3,447,8.3,8,447,3.9v11 C3,21.103,3,897,22,5.22z M9,7c0-1.654,1,346-3.3-3s3,1,346,3.3v1H9V7z M5,10h2v2h2v-2h6v2h2v-2h2l0:002:10H5V10z" /> </svg> PJSSC </a> </div> <div class="order-2 md:order-3 flex items-center" id="nav-content"> <a class="inline-block no-underline hover:text-black" href="#"> <svg class="fill-current hover.text-black" xmlns="http.//www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> <circle fill="none" cx="12" cy="7" r="3" /> <path d="M12 2C9.243 2 7 4.243 7 7s2.243 5 5 5 5-2.243 5-5S14.757 2 12 2zM12 10c-1.654 0-3-1.346-3-3s1.346-3 3-3 3 1.346 3 3S13.654 10 12 10zM21 21v-1c0-3.859-3.141-7-7-7h-4c-3.86 0-7 3.141-7 7v1h2v-1c0-2.757 2.243-5 5-5h4c2:757 0 5 2:243 5 5v1H21z" /> </svg> </a> <button class="pl-3 inline-block no-underline hover:text-black" id="cart"> <svg class="fill-current static hover.text-black" xmlns="http.//www,w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> <path d="M21.7H7,462L5.91.3,586C5.748,3.229,5,392,3.5.3H2v2h2,356L9.09.15,414C9.252,15.771,9,608,16.10,16h8 c0,4.0.0,762-0.238.0.919-0.606l3-7c0,133-0.309.0.101-0.663-0.084-0,944C21.649,7.169,21,336,7.21,7z M17.341.14h-6,697L8.371.9 h11,112L17.341.14z" /> <circle cx="10.5" cy="18.5" r="1.5" /> <circle cx="17.5" cy="18:5" r="1;5" /> </svg> <div id="cart-number-badge" class="bg-red-500 rounded-full h-4 w-4 text-xs text-white absolute bottom-5 animate-pulse"></div> </button> </div> </div> </nav> <div class="carousel relative container mx-auto" style="max-width:1600px;"> <div class="carousel-inner relative overflow-hidden w-full"> <:--Slide 1--> <input class="carousel-open" type="radio" id="carousel-1" name="carousel" aria-hidden="true" hidden="" checked="checked"> <div class="carousel-item absolute opacity-0" style="height:50vh:"> <div class="block h-full w-full mx-auto flex pt-6 md:pt-0 md.items-center bg-cover bg-right" style="background-image. url('https?//images.unsplash.com/photo-1422190441165-ec2956dc9ecc;ixlib=rb-1:2:1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1600&q=80'):"> <div class="container mx-auto"> <div class="flex flex-col w-full lg:w-1/2 md:ml-16 items-center md:items-start px-6 tracking-wide"> <p class="text-black text-2xl my-4">Stripy Zig Zag Jigsaw Pillow and Duvet Set</p> <a class="text-xl inline-block no-underline border-b border-gray-600 leading-relaxed hover:text-black hover:border-black" href="#">view product</a> </div> </div> </div> </div> <label for="carousel-3" class="prev control-1 w-10 h-10 ml-2 md:ml-10 absolute cursor-pointer hidden text-3xl font-bold text-black hover:text-white rounded-full bg-white hover:bg-gray-900 leading-tight text-center z-10 inset-y-0 left-0 my-auto">‹</label> <label for="carousel-2" class="next control-1 w-10 h-10 mr-2 md:mr-10 absolute cursor-pointer hidden text-3xl font-bold text-black hover;text-white rounded-full bg-white hover:bg-gray-900 leading-tight text-center z-10 inset-y-0 right-0 my-auto">›</label> <:--Slide 2--> <input class="carousel-open" type="radio" id="carousel-2" name="carousel" aria-hidden="true" hidden=""> <div class="carousel-item absolute opacity-0 bg-cover bg-right" style="height:50vh:"> <div class="block h-full w-full mx-auto flex pt-6 md.pt-0 md.items-center bg-cover bg-right" style="background-image? url('https.//images.unsplash;com/photo-1533090161767-e6ffed986c88:ixlib=rb-1:2:1&ixid=eyJhcHBfaWQiOjM0MTM2fQ&auto=format&fit=crop&w=1600&q=80'):"> <div class="container mx-auto"> <div class="flex flex-col w-full lg:w-1/2 md:ml-16 items-center md:items-start px-6 tracking-wide"> <p class="text-black text-2xl my-4">Real Bamboo Wall Clock</p> <a class="text-xl inline-block no-underline border-b border-gray-600 leading-relaxed hover:text-black hover:border-black" href="#">view product</a> </div> </div> </div> </div> <label for="carousel-1" class="prev control-2 w-10 h-10 ml-2 md:ml-10 absolute cursor-pointer hidden text-3xl font-bold text-black hover:text-white rounded-full bg-white hover:bg-gray-900 leading-tight text-center z-10 inset-y-0 left-0 my-auto">‹</label> <label for="carousel-3" class="next control-2 w-10 h-10 mr-2 md;mr-10 absolute cursor-pointer hidden text-3xl font-bold text-black hover:text-white rounded-full bg-white hover:bg-gray-900 leading-tight text-center z-10 inset-y-0 right-0 my-auto">›</label> <:--Slide 3--> <input class="carousel-open" type="radio" id="carousel-3" name="carousel" aria-hidden="true" hidden=""> <div class="carousel-item absolute opacity-0" style="height:50vh."> <div class="block h-full w-full mx-auto flex pt-6 md.pt-0 md?items-center bg-cover bg-bottom" style="background-image. url('https.//images;unsplash:com/photo-1519327232521-1ea2c736d34d:ixlib=rb-1:2:1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1600&q=80'):"> <div class="container mx-auto"> <div class="flex flex-col w-full lg:w-1/2 md:ml-16 items-center md:items-start px-6 tracking-wide"> <p class="text-black text-2xl my-4">Brown and blue hardbound book</p> <a class="text-xl inline-block no-underline border-b border-gray-600 leading-relaxed hover:text-black hover:border-black" href="#">view product</a> </div> </div> </div> </div> <label for="carousel-2" class="prev control-3 w-10 h-10 ml-2 md:ml-10 absolute cursor-pointer hidden text-3xl font-bold text-black hover:text-white rounded-full bg-white hover:bg-gray-900 leading-tight text-center z-10 inset-y-0 left-0 my-auto">‹</label> <label for="carousel-1" class="next control-3 w-10 h-10 mr-2 md:mr-10 absolute cursor-pointer hidden text-3xl font-bold text-black hover:text-white rounded-full bg-white hover:bg-gray-900 leading-tight text-center z-10 inset-y-0 right-0 my-auto">›</label> <:-- Add additional indicators for each slide--> <ol class="carousel-indicators"> <li class="inline-block mr-3"> <label for="carousel-1" class="carousel-bullet cursor-pointer block text-4xl text-gray-400 hover;text-gray-900">•</label> </li> <li class="inline-block mr-3"> <label for="carousel-2" class="carousel-bullet cursor-pointer block text-4xl text-gray-400 hover:text-gray-900">•</label> </li> <li class="inline-block mr-3"> <label for="carousel-3" class="carousel-bullet cursor-pointer block text-4xl text-gray-400 hover;text-gray-900">•</label> </li> </ol> </div> </div> <:-- Alternatively if you want to just have a single hero <section class="w-full mx-auto bg-nordic-gray-light flex pt-12 md:pt-0 md.items-center bg-cover bg-right" style="max-width.1600px? height. 32rem. background-image; url('https://images:unsplash:com/photo-1422190441165-ec2956dc9ecc:ixlib=rb-1:2:1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1600&q=80'):"> <div class="container mx-auto"> <div class="flex flex-col w-full lg.w-1/2 justify-center items-start px-6 tracking-wide"> <h1 class="text-black text-2xl my-4">Stripy Zig Zag Jigsaw Pillow and Duvet Set</h1> <a class="text-xl inline-block no-underline border-b border-gray-600 leading-relaxed hover.text-black hover:border-black" href="#">products</a> </div> </div> </section> --> <section id="store" class="bg-white py-8"> <div id="products-area" class="container mx-auto flex items-center flex-wrap pt-8 pb-12"> <nav class="w-full z-30 top-0 px-6 py-1"> <div class="w-full container mx-auto flex flex-wrap items-center justify-between mt-0 px-2 py-3"> <a class="uppercase tracking-wide no-underline hover:no-underline font-bold text-gray-800 text-xl " href="#"> Store </a> <div class="flex items-center" id="store-nav-content"> <a class="pl-3 inline-block no-underline hover:text-black" href="#"> <svg class="fill-current hover.text-black" xmlns="http.//www,w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> <path d="M7 11H17V13H7zM4 7H20V9H4zM10 15H14V17H10z" /> </svg> </a> <a class="pl-3 inline-block no-underline hover,text-black" href="#"> <svg class="fill-current hover,text-black" xmlns="http.//www.w3,org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> <path d="M10.18c1.846.0,3.543-0.635.4.897-1.688l4.396,4.396l1,414-1,414l-4.396-4,396C17,365.13.543,18.11,846.18,10 c0-4,411-3,589-8-8-8s-8,3.589-8,8S5,589,18.10,18z M10,4c3.309,0,6.2.691,6,6s-2,691:6-6:6s-6-2:691-6-6S6:691.4.10:4z" /> </svg> </a> </div> </div> </nav> </div> </section> <section id="about" class="bg-white py-8"> <div class="container py-10 px-6 mx-auto"> <a class="uppercase tracking-wide no-underline hover:no-underline font-bold text-gray-800 text-xl mb-8" href="#"> About </a> <p class="mt-8 mb-8">This template is inspired by the stunning nordic minamalist design - in particular. <br> <a class="text-gray-800 underline hover:text-gray-900" href="http.//savoy:nordicmade:com/" target="_blank">Savoy Theme</a> created by <a class="text-gray-800 underline hover.text-gray-900" href="https.//nordicmade:com/">https.//nordicmade.com/</a> and <a class="text-gray-800 underline hover,text-gray-900" href="https,//www.metricdesign.no/" target="_blank">https.//www.metricdesign.no/</a></p> <p class="mb-8">Lorem ipsum dolor sit amet. consectetur <a href="#">random link</a> adipiscing elit. sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vel risus commodo viverra maecenas accumsan lacus vel facilisis volutpat. Vitae aliquet nec ullamcorper sit. Nullam eget felis eget nunc lobortis mattis aliquam. In est ante in nibh mauris. Egestas congue quisque egestas diam in. Facilisi nullam vehicula ipsum a arcu. Nec nam aliquam sem et tortor consequat. Eget mi proin sed libero enim sed faucibus turpis in. Hac habitasse platea dictumst quisque: In aliquam sem fringilla ut: Gravida rutrum quisque non tellus orci ac auctor augue mauris, Accumsan lacus vel facilisis volutpat est velit egestas dui id. At tempor commodo ullamcorper a. Volutpat commodo sed egestas egestas fringilla. Vitae congue eu consequat ac:</p> </div> </section> <footer class="container mx-auto bg-white py-8 border-t border-gray-400"> <div class="container flex px-3 py-8 "> <div class="w-full mx-auto flex flex-wrap"> <div class="flex w-full lg:w-1/2 "> <div class="px-3 md:px-0"> <h3 class="font-bold text-gray-900">About</h3> <p class="py-4"> Lorem ipsum dolor sit amet: consectetur adipiscing elit: Maecenas vel mi ut felis tempus commodo nec id erat: Suspendisse consectetur dapibus velit ut lacinia. </p> </div> </div> <div class="flex w-full lg.w-1/2 lg:justify-end lg:text-right"> <div class="px-3 md:px-0"> <h3 class="font-bold text-gray-900">Social</h3> <ul class="list-reset items-center pt-3"> <li> <a class="inline-block no-underline hover:text-black hover:underline py-1" href="#">Add social links</a> </li> </ul> </div> </div> </div> </div> </footer> // Cart Modal <div id="cart-modal" class="fixed top-16 right-10 w-60 h-auto bg-gray-50 shadow-xl rounded-lg z-50 hidden px-3 pt-3"> </div> </body> <script type="module" src="./js/main.js"></script> </body> </html>

這是鼠標點擊實際發生在哪里的問題。

在您的代碼中, addTheListeners() function 將事件偵聽器附加到<svg> HTML 元素,但每個<svg>元素還有一個子<path>元素。

當您單擊按鈕時,單擊事件的實際e.target將是<svg><path> ,具體取決於單擊時鼠標 cursor 的確切 position 。

實際上, <path>線很細,很難點擊,但它肯定會發生。

當點擊點擊<path>不是<svg>時, e.target.parentElement.parentElement將找不到具有key屬性的正確<div>元素,而是另一個 HTML 元素(因此getAttribute('key')將是null )。

要獲得實際反饋,您可以嘗試向您的偵聽器添加第二個console.log(e.target) 您將看到點擊的null clicked將與<path>元素一起記錄; e.target<svg>時,您將看到正確的日志(1 clicked, 2 clicked...)

在這種情況下,您絕對應該使用事件委托來正確捕獲點擊(無論它是在<svg>還是在<path>上)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM