How to implement a nested a tags?

The requirements

I wanted to put some buttons on each of the blog posts.

  • When clicking on the buttons (#2 in the screenshot), it goes to the tagging URL
  • When clicking on everywhere else (#1 in the screenshot), it goes to the blog post URL

First Attempt

I first try to implement this using nested <a> tags. Pseudocode:

<a href="https://google.com">
  <div>
   <h1>Title</h1>
    <a href="https://google.com/1">Feature 1</a>
    <a href="https://google.com/2">Feature 2</a>
    <p>Date</p>
  </div>
</a>

This doesn't seem to work as intended. The reason is that nested <a> tags are illegal in HTML standards.  

Browsers such as Chrome will force the code above into something like below.

<div><a href="https://google.com">
  <h1>Title</h1>
  </a>
  <a href="https://google.com/1">Feature 1</a>
  <a href="https://google.com/2">Feature 2</a>
  <p>Description</p>
</div>

I have to click on the h1 title to go to the blog page, not everywhere as per my requirement.

Second Attempt

I then remove all <a> tags and bind "click" events to the respective DOMs.

  <div data-url="https://google.com" class="post">
    <h1>Title</h1>
    <span data-url="https://google.com/1" class="tag">Feature 1</span>
    <span data-url="https://google.com/2" class="tag">Feature 2</span>
    <p>Description</p>
  </div>
viewPost(e) {
    window.location.href = e.currentTarget.dataset.url
}

viewTag(e) {
    window.location.href = e.currentTarget.dataset.url
}

Both the buttons and the entire card are clickable. But I have one problem. When I click on the tag buttons, it triggers both URLs, and I will end up on the wrong page.

The reason is, that the click event on the tag buttons got propagated to its parent, which is listening to the same event.

Third Attempt

To prevent this, we need to stop the propagation.

viewPost(e) {
    window.location.href = e.currentTarget.dataset.url
}

viewTag(e) {
    e.stopPropagation()
    window.location.href = e.currentTarget.dataset.url
}

It is now working as per our requirements.


Stimulus equivalent

If you are using stimulus, this can be done by adding a "stop" option in your action. Example:

<span data-action="click->posts#viewTag:stop"></span>

AI Summary
gpt-4o-2024-05-13 2024-07-29 10:28:21
The blog post, "How to implement nested a tags," discusses how to make different parts of a blog post clickable with distinct URLs. After unsuccessful attempts with nested anchor tags and DOM click events, the solution involved using JavaScript to stop event propagation for precise click handling. Stimulus framework usage is also touched upon.
Chrome On-device AI 2025-02-08 10:34:00

Share Article