(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
what are you trying to do?
why are you trying to make a div clickable?
hi. it's just a collapse element from bootstrap. i want to prevent the link from collapsing/expanding the content
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
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.
no, it's not fine
https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/button#technical_summary
quoting:
Phrasing content but there must be no Interactive content.https://developer.mozilla.org/en-US/docs/Web/HTML/Guides/Content_categories#interactive_content <-- interactive content
"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.
so bootstrap is bad practice?
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
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
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
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
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:
If you click on the link, it works as a link. Click on the non-link, it opens/closes the dropdown.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
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.
they tell you to use link or a button
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
well, you will have to remove all event listeners from the parent
is that possible?
yes, but that is the same as removing the toggling functionality
the parent of the link receives the click event before the link
by adding attributes like data-bs-target, bootstrap parses the html and adds event listeners on the elements with attributes that it understands, correct?
yed
yes
sorta
on the capture phase?
yup
because when you click on the link, you are clicking on all the parents also
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?
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
so bootstrap does not have the useCapture flag set to true?
it's not supposed to
well i tried, no luck
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
when i add multiple click events handlers on an element, do they overwrite each other?
depends on how you do it
2 addeventlisteners in a row
no
that is why that function exists
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?
if it was added before yours and after you checked there are none, it's possible it will execute the clicks anyways
let me check if the habdler has the flag set
but basically thats how it works, right?
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
thanks
you have tests there as well

look at that. capture is true
so basically my code doesnt prevent that
i guess i have answered my own question lol
why would they do that?
the useCapture set to true?
yes
back when bootstrap 5.3 came out, browsers were more consistent with event handling, but you still had some weird beasts
I guess they expect people not to use any other elements inside the one having this attribute or mix functionality
as it should be
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
but it is still strange because i dont think all browsers at the time behaved exactly the same in terms of event handling
isnt 5.3 the latest? shoudlnt it be targeting new browsers at this point?
it's the latest back in 2018 or so
huh?
i'm using 5.3.3
anyway
at least i know what causes it
thank you for your input
oh, wait, 5.3.7 is new 😮
5.3.3 is one of the old ones
oh, 2024
🤔
not that old tho
5.3.2 is from october 2023
i was mixing 5.2 then??? 🤔
i need a nap 🤣