(javascript/bootstrap) How to prevent the link from triggering the collapse element?

How can I prevent the link from collapsing/expanding the collapse element? I tried attaching a click event listener to the link in order to stop propagation, or even adding a class to the link element and check which target was clicked. https://jsfiddle.net/gq824eoz/1/ I found a workaround by removing the data-bs-toggle and data-bs-target attributes: https://stackblitz.com/edit/tg6ob8rt?file=index.html However I still want to understand how to make it work without removing them. Thanks a lot in advance. ---- Bootstrap Collapse Documentation: https://getbootstrap.com/docs/5.3/components/collapse/
55 Replies
ἔρως
ἔρως2w ago
what are you trying to do? why are you trying to make a div clickable?
Silvershot
SilvershotOP2w ago
hi. it's just a collapse element from bootstrap. i want to prevent the link from collapsing/expanding the content
ἔρως
ἔρως2w ago
you're not supposed to put links inside a link or a button (the elements that should be used for toggling a dropdown) links cant be nested and buttons just shouldnt have other clickable elements inside what you are trying to do is not a good idea, and will require fugly hacks to make it work, as you found out
Silvershot
SilvershotOP2w ago
but bootstrap does it, so its fine? i mean from a javascript perspective, it should work and besides it's not a a real button. i have a div with an ancher element inside.
13eck
13eck2w ago
"Just b/c [instert idiot here] does it it's fine" is the worst kind of argument you can make. One person/place using bad practice doesn't all of the sudden make it good.
Silvershot
SilvershotOP2w ago
so bootstrap is bad practice?
13eck
13eck2w ago
Nesting buttons/links is bad practice I'm not saying BS is bad practice completely, but it sounds like their suggestions/workflow might contain bad practice
Silvershot
SilvershotOP2w ago
sure, but I get the same behavior evne when not nesting it i mean if i place a span inside the div and want to prevent the click from bubbling
13eck
13eck2w ago
Honestly, though, using BS is bad practice in my opinion. The biggest thing it brought to the table was faking a grid with flexbox. But we have grid now so you don't really need it. Just use CSS -# also if you use BS then your site will look like all the other BS sites out there, and that's boring IMO
Silvershot
SilvershotOP2w ago
it's for work. i wasnt the one to decide the framework 😄 still i would love to find out what happens in this case, to deeply understand the js behind it
13eck
13eck2w ago
The issue that I see is you're using a non-interactive element (a div) to fake interactivity. HTML doesn't know how to do that since, honestly, you're doing it wrong. If you want a drop-down like that you should use the correct element: details. Here's a minimum working prototype without any JS taht works out of the box:
<details>
<summary>Click me! <a href="https://developer.mozilla.org/">I'm a link!</a></summary>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation.
</details>
<details>
<summary>Click me! <a href="https://developer.mozilla.org/">I'm a link!</a></summary>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation.
</details>
If you click on the link, it works as a link. Click on the non-link, it opens/closes the dropdown.
ἔρως
ἔρως2w ago
the spec is not too happy about it, but, it does work and it is a lot less horrible than making a div clickable with a link inside or using the correct element (link or button) with a link inside nesting a link inside a link it's not just a bad practice but it wont work at all all child links will not be interactible
Mannix
Mannix2w ago
where do you see BS nesting links inside buttons ? https://getbootstrap.com/docs/5.3/components/collapse/#how-it-works
Collapse
Toggle the visibility of content across your project with a few classes and our JavaScript plugins.
Mannix
Mannix2w ago
they tell you to use link or a button
Silvershot
SilvershotOP2w ago
I was just trying to find out how to prevent the click event on the span triggering the collapse. I know there are easier/better practises, but it is not what I asked. I am trying to understand how to make it work as-is in my actual code, which I cant share, there's a span inside the div which has the bootstrap attributes (data-bs-target, etc.). I dont have a link at all, but it doesn't work just like the link doesnt work
ἔρως
ἔρως2w ago
well, you will have to remove all event listeners from the parent
Silvershot
SilvershotOP2w ago
is that possible?
ἔρως
ἔρως2w ago
yes, but that is the same as removing the toggling functionality the parent of the link receives the click event before the link
Silvershot
SilvershotOP2w ago
by adding attributes like data-bs-target, bootstrap parses the html and adds event listeners on the elements with attributes that it understands, correct?
ἔρως
ἔρως2w ago
yed yes sorta
Silvershot
SilvershotOP2w ago
on the capture phase?
ἔρως
ἔρως2w ago
yup because when you click on the link, you are clicking on all the parents also
Silvershot
SilvershotOP2w ago
fine, but that does not execute the handler right away, the event is captured, moving from the top down, it finds the link, sets the target to the link element and bubbles up, then executes. but if i prevent the click event from propagating/bubbling up, it should not reach the parent. or is it that by doing this, i am simply adding "another" click event listener in addition to the ones already set up by bootstrap? or is it that when the parent is clicked, bootstrap sets the capture flag on the addeventlistener to true, aka execute the handler on the way down?
ἔρως
ἔρως2w ago
when you click the button, the click bubbles up i was wrong and bootstrap doesnt use the capture phase, because of broeser support browser you have to prevent the propagation on the link
Silvershot
SilvershotOP2w ago
so bootstrap does not have the useCapture flag set to true?
ἔρως
ἔρως2w ago
it's not supposed to
Silvershot
SilvershotOP2w ago
well i tried, no luck
ἔρως
ἔρως2w ago
then try to add your event with capture now-a-days, shouldnt be an issue but still, you are trying to build an house by putting the windows first
Silvershot
SilvershotOP2w ago
when i add multiple click events handlers on an element, do they overwrite each other?
ἔρως
ἔρως2w ago
depends on how you do it
Silvershot
SilvershotOP2w ago
2 addeventlisteners in a row
ἔρως
ἔρως2w ago
no that is why that function exists
Silvershot
SilvershotOP2w ago
ok so both fire. i checked the bootstrap click event listeners attached to the link, and there are none. then i add mine to stop propagation. i do this when the document has loaded/is ready. so when i click on the link, the event shouldnt go further up. But if the bootstrap click event was added with the capture flag set to true, then its listener fires before it reaches the link?
ἔρως
ἔρως2w ago
if it was added before yours and after you checked there are none, it's possible it will execute the clicks anyways
Silvershot
SilvershotOP2w ago
let me check if the habdler has the flag set but basically thats how it works, right?
ἔρως
ἔρως2w ago
https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/Scripting/Event_bubbling <-- this should clarify the majority of your questions but keep in mind that the order in which the events are added is important
Silvershot
SilvershotOP2w ago
thanks
ἔρως
ἔρως2w ago
you have tests there as well
Silvershot
SilvershotOP2w ago
No description
Silvershot
SilvershotOP2w ago
look at that. capture is true so basically my code doesnt prevent that i guess i have answered my own question lol
ἔρως
ἔρως2w ago
why would they do that?
Silvershot
SilvershotOP2w ago
the useCapture set to true?
ἔρως
ἔρως2w ago
yes back when bootstrap 5.3 came out, browsers were more consistent with event handling, but you still had some weird beasts
Silvershot
SilvershotOP2w ago
I guess they expect people not to use any other elements inside the one having this attribute or mix functionality
ἔρως
ἔρως2w ago
as it should be
Silvershot
SilvershotOP2w ago
my nested span basically opens a tooltip, so when i clicked on it, it would collapse the content and also open the tooltip, which is not what i wanted
ἔρως
ἔρως2w ago
but it is still strange because i dont think all browsers at the time behaved exactly the same in terms of event handling
Silvershot
SilvershotOP2w ago
isnt 5.3 the latest? shoudlnt it be targeting new browsers at this point?
ἔρως
ἔρως2w ago
it's the latest back in 2018 or so
Silvershot
SilvershotOP2w ago
huh? i'm using 5.3.3 anyway at least i know what causes it thank you for your input
ἔρως
ἔρως2w ago
oh, wait, 5.3.7 is new 😮 5.3.3 is one of the old ones oh, 2024 🤔
Silvershot
SilvershotOP2w ago
not that old tho
ἔρως
ἔρως2w ago
5.3.2 is from october 2023 i was mixing 5.2 then??? 🤔 i need a nap 🤣

Did you find this page helpful?