how to remove eventhandler from bootstrap carousel indicator items - javascript

I am using bootstrap5 carousel, and I want to fire a custom event when the previous or next indicators are clicked.
I want to prevent the default bootstrap event from firing. I have tried a bunch of different techniques, but with no success.
Does anyone know how to do this?
Mtia

Check the official documentation. It has some listeners you can add to your JavaScript.
You need to make sure you add the Bootstrap CDN or the npm module with the JavaScript for it to work, though.
Bootstrap Documentation
Example
const myCarousel = document.querySelector("#myCarousel");
const carousel = new bootstrap.Carousel(myCarousel, { interval: 2500 });
myCarousel.addEventListener("slide.bs.carousel", () => { /* Do something... */ });

Have you tried e.stopPropagation() or e.stopImmediatePropagation()

I found the solution in the end. I was programatically placing bs-slide-to on the next and previous indicators, and this was causing the event handler to fire.
So, to stop the bootstrap event handler, remove the bs-slide-to and the bs-slide attributes from the next and previous indicators, and the event won't fire.
I removed that, and used a custom event handler and it works fine (I hope).

Related

Removing event listener from custom element

I have a problem removing event listener from a custom created element. The code below runs but I still get more event listeners (showed on screens below in chrome devtools).
stopPropagation(event) {
event.stopPropagation();
},
saveFileDocument() {
let elementToDownload = document.createElement("a");
// Some code to add attributes and stuff
// like "download" (i'm not sure it this is relevant)
document.body.appendChild(elementToDownload);
elementToDownload.addEventListener("click", this.stopPropagation);
elementToDownload.click();
elementToDownload.removeEventListener("click", this.stopPropagation);
document.body.removeChild(elementToDownload);
elementToDownload = null;
}
Screen from devtools (before and after click):
Before (549 listeners)
After (551 listeners)
The funny thing: when I remove the line with removing event listener the listnener count only increases by 1 on each function call.
Frontend framework I work on is Vue but I don't think it's Vue related.
This is my first question so sorry if I didn't go in too many details. I can add them when requested.
Thanks,
Paweł

jQuery toggle() not always firing

I've been making some basic mobile navigation and am using a click event to show/hide the menu.
A reduced code sample:
jQuery('.menu-button').click(function(){
jQuery('.header-nav').toggle();
console.log('clicked');
});
I've been remotely debugging on mobile and the console.log always works, but the .header-nav toggle() seems to randomly not trigger - I can't spot a pattern to it, but it always remains in the DOM (which it should), so it being somehow removed is not the reason why it is not firing.
Any ideas?
Thanks to Kevin B's comment it seems that the click event is firing multiple times. To fix this, the following was used:
$(element).off().on('click', function() {
// function body
});
Reference: jQuery click events firing multiple times

removing dynamic javascript tag does not remove attached events

i'm creating an application where a user can make a html layout and attach javascript to it.
Now i'm trying to make it so when they click a button, they go to a preview mode where they can see it in action.. so when they click i add the javascript tag ( with their javascript) in the head of the iframe.. this all works fine!
But the problem is when they leave the preview mode, i remove the javascript tag, however when i have code like this:
$('#button').click(function()
{
alert("ok");
});
it still alerts ok when i click the html button (when not in previewmode!), which shouldn't happen!
It seems that when removing the javascript tag, the listeners aren't removed.. Or am i doing it wrong?
Now my question: is there a way to make it so these added eventlisterens are removed when i remove the script tag?
AND YES: i know you can remove eventhandlers with .off(), but since i already have event handlers attached, these will be removed also, and i don't want this!
So two options i can think off:
- rebuild the whole iframe
- store the eventhandlers that were added by the user and when leaving the preview mode, removing them.
Thanks in advance
Each time you "evaluate" JavaScript, it becomes part of the browser's "image", and whether the source is present on the page no longer matters. You need to manually unbind the event, or replace the html segment to which the event was bound.
To remove events from an html element, you can use:
element.parentNode.innerHTML = element.parentNode.innerHTML
This rebuilds the DOM tree using the same HTML.
you need to unbind event.
You can do it by using jquery unbind() or off()
like this:
$("#button").unbind("click");
or
$("#button").off("click");
Demo: http://jsfiddle.net/a6NJk/664/
jquery Doc: http://api.jquery.com/off/
Another good answer: Best way to remove an event handler in jQuery?
Set the event:
var $button = $('#button');
$button.on("click", function() {
alert("ok");
});
Take off the event:
$button.off("click");
You can take off that specific function too
var $button = $('#button');
var eventFunction = function() {
alert("ok");
});
// Set event up
$button.on("click", eventFunction);
// Take event off
$button.off("click", eventFunction);
If you want to remove all events from an element you can use
$("#yourSelector").off()
Because it's not jQuery in general but also vanilla javascript, it would be too much work to keep track of javascript changes, so rebuilding the iframe would be the best option here.

jquery event added multiple times

I have a fairly large javascript class that generates an complete ajax-generated application. In one version of the ajax page there are a number of dropdown menus. These menus can get created and destroyed at various points during the life cycle of the application.
This is the behaviour I see:
User opens page version 1: no dropdowns
User goes to page version 2: dropdowns added with jQuery onchange event. Work as intended.
User returns to version 1 of page, dropdowns removed.
User returns to version 2 of page, dropdowns added again (using same element IDs)
dropdowns will now have 'double' event handling, triggering the event for each onchange.
The behaviour I'm struggling with is as follows.
On the initial page load, I add an onchange event:
function myClass(){
//Initiate once for current and future elements.
jQuery(document).on('change',".mydropdowns",
function(e){
self.submitDescriptionChange(this);
}
);
}
myClass.prototype.submitDescriptionChange = function (el){
doSomeAjaxStuff();
}
This works fine, except that each time the user goes to pages version 1 and returns to page version 2, the event gets multiplied. Very quickly you can end up with the event firing 20 times per change event, which in this case creates 20 ajax calls.
Logically, by using jQuery.off() I should be able to avoid this. But what happens instead is that the event is removed from both past and future elements, which means that when I recreate page version 2, the dropdowns won't work.
Every way I have tried this (and I've tried LOADS), I either end up with no event firing, or multiple events firing. I cannot seem to find a way to add/replace the elements whereby the event is only ever fired once.
Any ideas how I can solve this?
UPDATED
Yeah, so it turns out I misdiagnosed the problem. It actually came from repeatedly rebinding a 'hashchange' event, rather than rebinding the onchange event. Apologies for misdirection. Moving to bind() function to somewhere where it only executed once fixed the issue.
Since you do not want .off() to remove your events from other pages, I would suggest using namespaces for your events. For example, something like this:
function myClass(pageno) {
var pref_ev = 'mypage' + pageno + '.' + 'change';
$(document).off(pref_ev).on(pref_ev, ".mydropdowns", function(e) {
self.submitDescriptionChange(this);
});
}
This way, each page will have its own "change" event such as "mypage1.change". The event is still registered normally as a change event; the prefix namespace "mypage1" is used to only perform the .off() call on the right events.
I am not sure what plugin you are using for your dropdown menus but there should be a "destroy" method on that plugin. If you call that when removing the dropdowns that should work. Also, if you are only hiding the second page and not actually removing it from the DOM you dont have to re-invoke the plugin as the plugin will still be saved on the element.

Twitter Bootstrap: Remove/Toggle the active state of checkbox-like button group

With twitters Bootstrap I've created a button group with radiobox behaviour to let the user choose between the different states. This works out of the box as supposed.
I arranged a jsFiddle with the example here: http://jsfiddle.net/jpxWj/
What I tried (and want) is that the pressed state can be removed when I click the active button second time.
I tried with jQuerys removeClass() to remove the active class from the btn classes but it won't work. (I also tried removing with .on() but this just keeps the active always hidden/removed)
Here you go, quite an unknown event phenomenon, in my opinion. You can read more about it here.
Edit:
To ellaborate, the reason why a simple .removeClass doesn't work, is because there are multiple listeners, listening to the same event. So when the click event is fired, a normal .removeClass would remove the class, but then the Twitter Bootstrap handler would add it again! To prevent any other handlers from being executed after yours, you can do e.stopPropagation. However, this does not stop the handlers attached to the same element as yours, it only stops the ones further up the tree. To completely make sure no other handlers are executed after yours, you can use event.stopImmediatePropagation().
Bootstrap 3 Update:
$('body').on('click', '.btn-group .btn.active',function(e){
e.preventDefault();
e.stopImmediatePropagation();
$(this).find('input').removeAttr('checked');
$(this).removeClass('active');
});

Categories