简体   繁体   中英

How to display div with same ID and OnClick function - Javascript, HTML and CSS

I'm fairly new to Javascript, and i've reached an issue I can't figure out yet, so I'll explain it as best as I can.

I've got 2 divs containing a reply link with the same ID, OnClick. Only difference is the data-attribute which I thought could be used to differentiate the two. There are 2 reply divs that are styled to be hidden. The aim is once the reply link is clicked, the correct div will display below it.

The issue is, when you click any of the two Reply links, it only opens the first reply div below the first parent div. I'll created a little example to give a better understanding:

 // Opens reply div and retrieves data-attribute (reply_id) to insert into MYSQL database function replyLink(element) { document.getElementById('reply').style.display = "block"; } // Close div link, displays after opening reply box function closeLink() { document.getElementById('reply').style.display = "none"; }
 #comment{ border: 1px solid #333333; width: 500px; height: 85px; padding: 5px; margin: 10px 10px 15px 10px; } #comment #content{ border: none; padding: 15px; font-size: 12px; } #comment #link{ border: none; padding: 5px; margin-top: 5px; } #comment #link a{ border: none; text-decoration: none; font-size: 12px; color: blue; } #comment #link a:hover{ border: none; text-decoration: underline; font-size: 12px; color: blue; } #reply{ border: 1px solid red; padding: 15px; margin: 0px 0px 10px 45px; width: 400px; }
 <div id="comment"> <div id="content"> Content #1 </div> <div id="link"> <a href='javascript:void(0);' onclick="replyLink()" data-test='1'>Reply</a> </div> </div> <div id="reply" style="display: none;"> reply container 1 <a href='javascript:void(0);' onclick='closeLink()' />[Close]</a> </div> <div id="comment"> <div id="content"> Content #2 </div> <div id="link"> <a href='javascript:void(0);' onclick="replyLink()" data-test='2'>Reply</a> </div> </div> <div id="reply" style="display: none;"> reply container 2 <a href='javascript:void(0);' onclick='closeLink()' />[Close]</a> </div>

Would a java genius be able to help me out.

You can use the classes for styling and IDs with indexes to identify the unique div boxes. Here is the working example

 function replyLink(index) { document.getElementById('reply_' + index).style.display = "block"; } // Close div link, displays after opening reply box function closeLink(index) { document.getElementById('reply_' + index).style.display = "none"; }
 .comment { border: 1px solid #333333; width: 500px; height: 85px; padding: 5px; margin: 10px 10px 15px 10px; }.comment.content { border: none; padding: 15px; font-size: 12px; }.comment.link { border: none; padding: 5px; margin-top: 5px; }.comment.link a { border: none; text-decoration: none; font-size: 12px; color: blue; }.comment.link a:hover { border: none; text-decoration: underline; font-size: 12px; color: blue; }.reply { border: 1px solid red; padding: 15px; margin: 0px 0px 10px 45px; width: 400px; }
 <div class="comment"> <div class="content"> Content #1 </div> <div class="link"> <a href='javascript:void(0);' onclick="replyLink(0)" data-test='1'>Reply</a> </div> </div> <div class="reply" id="reply_0" style="display: none;"> reply container 1 <a href='javascript:void(0);' onclick='closeLink(0)'>[Close]</a> </div> <div class="comment"> <div class="content"> Content #2 </div> <div class="link"> <a href='javascript:void(0);' onclick="replyLink(1)" data-test='2'>Reply</a> </div> </div> <div class="reply" id="reply_1" style="display: none;"> reply container 2 <a href='javascript:void(0);' onclick='closeLink(1)'>[Close]</a> </div>

While the use of an id is straightforward when first working with JavaScript and HTML, it's use is discouraged as an anti-pattern. IDs make for brittle code (as you are seeing here) and don't scale well. Instead, don't use ids at all and instead use classes or a relative reference to the elements, such as this, .closest(), nextElementSibling, parentNode, etc.

Also, using hyperlinks as a "hook" to initiate some code upon a click event is semantically incorrect. Hyperlinks are for navigation and people who use screen readers will have difficulty navigating your page. Just about every visible HTML element supports a click event, so just attach a click handler directly to the element instead of wrapping the element with a hyperlink.

Lastly, there is no need for separate show and hide functions. Just add or remove a "hidden" class based on what was clicked.

You can see in my answer how much cleaner the HTML and JavaScript are without id s.

See comments inline below.

 // Set up a single event handler for any clicks to any reply or Close document.addEventListener("click", function(event){ // Check to see if the click originated at a Reply element if(event.target.classList.contains("reply")){ // Find the closest ".comment" ancestor of the clicked reply // element and then get the next element sibling to that and // unhide it. event.target.closest(".comment").nextElementSibling.classList.remove("hidden"); } else if(event.target.classList.contains("replyContainer")){ event.target.classList.add("hidden"); } });
 .hidden { display:none; }.comment{ border: 1px solid #333333; width: 500px; height: 85px; padding: 5px; margin: 10px 10px 15px 10px; }.comment.reply{ padding: 5px; margin-top: 5px; }.replyContainer{ border: 1px solid red; padding: 15px; margin: 0px 0px 10px 45px; width: 400px; }
 <div class="comment"> <div class="content">Content #1</div> <div class="reply">Reply</div> </div> <div class="hidden replyContainer">reply container 1[Close]</div> <div class="comment"> <div class="content">Content #2</div> <div class="reply">Reply</div> </div> <div class="hidden replyContainer">reply container 2[Close]</div> <div class="comment"> <div class="content">Content #3</div> <div class="reply">Reply</div> </div> <div class="hidden replyContainer">reply container 3[Close]</div>

You can use the DOM structure to your advantage. Normally you wouldn't want to rely too deeply on it though. For toggling div it's perfectly ok. By using element which was clicked we can look for closest common ancestor. That way we can find the related div .

 function replyLink(elem) { elem.closest("article").querySelector("#reply").style.display = "block"; } function closeLink(elem) { elem.closest("article").querySelector("#reply").style.display = "none"; } // just for demo: document.body.innerHTML = document.body.innerHTML + document.body.innerHTML document.body.innerHTML = document.body.innerHTML + document.body.innerHTML
 <article> <div id="comment"> <div id="content"> Content #N </div> <div id="link"> <a href='javascript:void(0);' onclick="replyLink(this)" data-test='1'>Reply</a> </div> </div> <div id="reply" style="display: none;"> reply container 1 <a href='javascript:void(0);' onclick='closeLink(this)'>[Close]</a> </div> </article>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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