How to use .not() Jquery Selector on triple selector class? - javascript

I have an issue with two buttons that share common html classes. Both buttons are part of a tutorial. As the tutorial goes through the steps the Skip button appears first. as the tutorial gets to the last step before moving on to anew tutorial page, the 3rd party JS package dynamically adds another class to the skip button and changes the inner html to Continue. My issue is below
One button is:
<a class="introjs-button introjs-skipbutton" role="button" tabindex="0">Skip</a>
The other button is
<a class="introjs-button introjs-skipbutton introjs-donebutton" role="button" tabindex="0">Continue</a>
These buttons are part of a tutorial guide with certain steps. They are not displayed at the same time. However, clicking the Skip button fires the same action as the Continue button, as displayed in the JS code below. I'd like the action to only Fire when the Skip button is clicked but it keeps firing on both and I cant figure out how to figure it out.
I'd like a certain action to fire but only fire when <a class="introjs-button introjs-skipbutton> is fired and NOT <a class="introjs-button introjs-skipbutton introjs-donebutton> is fired.
$("a.introjs-button.introjs-skipbutton").not(".introjs-donebutton").click(() => {
console.log('skipbuttontriggered')
this._app.skipTutorial = true;
})
I've tried various combinations and was hoping to get some insight on using the not() selector for triple stacked html classes.

You don't need to use :not(). You could just check it doesn't have the class.
$("a.introjs-button.introjs-skipbutton").click(() => {
if ( ! $(this).hasClass('introjs-donebutton') {
console.log('skipbuttontriggered')
this._app.skipTutorial = true;
}
})
The hasClass() documentation can be read here.

If you're adding and removing the introjs-donebutton class dynamically, you can do it with event delegation and a selector with :not().
$(document).on("click", "a.introjs-button.introjs-skipbutton:not(.introjs-donebutton)", () => {
console.log('skipbuttontriggered')
this._app.skipTutorial = true;
})

Related

jQuery click firing multiple times

Update:
Seems like the problem has nothing to do with my code. I've been running the webpage over browser-sync and that's where the problem appears. When I open the static webpage in Chrome directly, everything seems to be working fine. Thank you to everyone for your help!
I'm working on my personal website and want to make a way to filter through my list of projects using buttons.
<div class="filters">
<button class="btn btn-filter">Android</button>
<button class="btn btn-filter">iOS</button>
<button class="btn btn-filter">Web Dev</button>
<button class="btn btn-filter">Data Science</button>
</div>
I'm trying to attach event listeners to the buttons by doing this, but it seems like the event listeners are being attached multiple times:
$(".btn-filter").each(function() {
console.log(this); // #1
$(this).click(function(e) {
e.preventDefault();
e.stopPropagation();
console.log(this); // #2
})
debugger;
})
I have also tried using the class selector. It doesn't work, I switched to .each() and $(this) to be sure the elements were being assigned event handlers only once.
$('.btn-filter').click(...)
Logs show that each button is selected once to be assigned a click listener, but when I actually click the buttons, only some fire once, and some fire 3 times. I use some because it doesn't always behave the same way each time the page is run.
I have tried the solutions described in
this post(off(), unbind(), stopPropagation()), but none have worked.
Using Google Chrome's debugger tools, it seems like at the breakpoint, this refers to the HTML element twice for every iteration of each, despite some clicks firing once and some three times.
I suppose I could just assign IDs and wire each button individually, but I want to know what I'm doing wrong here. Could anyone explain?
You are running a for each loop on the class, so it will create a new event handler for each element with the class. If you want just one event handler you need to write it like this:
$(".btn-filter").click(function() {
console.log($(this).text());
});
Buttons that show or hide specific content are best described with a data value or id
Edit: after learning you had this before I will add that nothing you supplied is causing the error you are receiving.
The problem with your code is is here
$(".btn-filter")**.each**(function() {
You should simplify it by simply doing something like this
$(".btn-filter").click(function(e) {
e.preventDefault();
e.stopPropagation();
console.log(e);
debugger;
})
Since you are already selecting via the class name $(".btn-filter") the function should be added to all the elements.
Call click event using class and get clicked value using .html()
$(document).ready(function () {
$(".btn-filter").click(function() {
alert($(this).html());
})
});
JSFiddler

jQuery toggle on click out

I have a series of spans (togglers) and a series of divs (toggled). I created a make_toggle function that receives the toggler and its corresponding toggled as arguments.
Everything seems to work kind of ok up to the point where I try to implement a "toggle on click out". What I've tried is to attach to the html click event a function that checks whether the target of the click is contained within the toggled element. On toggle "back", I would then detach the handler so I am only checking when I need.
var check_if_clickingout = function(e) {
if (!toggled[0].contains(e.target)) {
toggle();
}
};
See fiddle: https://jsfiddle.net/andinse/65o211nc/11/
It doesn't even seem to work anymore but when it used to, it was triggering many more times than necessary (which was the reason for me to come here ask for help).
What am I doing wrong? What is the most effective way to go about this kind of situation where I am giving functionality to a series of independent DOM elements?
Just putting this out here that this seems to do the same thing.
$("span").click(function() {
$(this).siblings("div").toggleClass("blue");
});
Maybe I am missing something more that I am not seeing in your example.
See more: http://api.jquery.com/toggleclass/

jQuery - .on('click') not working on <li>

so I've been tasked with making a website using Wordpress and on the homepage there's a slider that if you click on the buttons below, it's displays another image, simple right? Well, I've got the slider and I've got the buttons, I've added the jQuery and it doesn't want to work.
I first tried making the buttons actually buttons:
<button type="button" class="btn btn-success" id="hideshow-healthcare">Healthcare</button>
and that worked fine when I used this:
jQuery(document).ready(function() {
jQuery('#hideshow-healthcare').on('click', function() {
jQuery('#healthcare').show();
};
};
So after having it working like that, I moved on to making the buttons in to li's instead so that I could follow the design. Upon doing this, the slider no longer works. I've tried mulitple different things including adding the ID to everything in the li to see if that would work, and sadly not. I did some research and tried to change
jQuery('#hideshow-healthcare').on('click', function() {
to
jQuery('li#hideshow-healthcare').on('click', function() {
but still, no luck. I was hoping someone would be able to provide a solution to this problem.
Also, this is the li code I'm currently using:
<li><a id="hideshow-healthcare"><h5>HEALTHCARE</h5> Lighting to create a feeling of well being</a></li>
You need to add space after li element to find its descendants #hideshow-healthcare. It should be
jQuery('li #hideshow-healthcare').on('click', function() {
#hideshow-healthcare is child of li. Use descendant selector in jquery
jQuery('li a#hideshow-healthcare').on('click', function(event) {
event.preventDefault(); // prevents default action
// your code
});
Id be unique in html you just straightly write with id
jQuery('#hideshow-healthcare').on('click', function(event) {
event.preventDefault(); // prevents default action
// your code
});

jQuery - using .prepend()

I'm using jQuery in my project, where I got some problems with .prepend(). Please go to http://qlimp.com and login using this username/password: dummy/dummy Then click the link Go to Information settings. Click the add service button -> then click facebook icon -> just click Add button
You will see the blue facebook tag. When you do that process once again, then you will see three facebook tags(prepending two tags at once) instead of two. It's like prepending twice the no. of previous tags. Why is it so?
Here is the jQuery code:
$("#facebook").click(function(){
$("#facebook-info").fadeIn("slow");
$("#facebook-button").click(function(){
a = a+1;
$("#service-sets").prepend('<div class="tag" id="'+a+'"><span class="blue-tag">Facebook<span class="delete-tag"><i class="icon-cancel-circle-1" id="facebook-del"></i></span></span></div>');
});
});
$("#service-sets").on('click', '#facebook-del', function() {
$("#facebook-tag").remove();
});
HTML
<div id="service-sets">
</div>
I just checked in jsfiddle http://jsfiddle.net/YVZH5/ with the sample code and it is working(prepending one tag at once). Could anyone tell me the mistake I've done?
Thanks!
Use only one click event. You are doing it for the parent and child element.
$("#facebook-button").click(function(){
$("#facebook-info").fadeIn("slow");
a = a+1;
$("#service-sets").prepend('<div class="tag" id="'+a+'"><span class="blue-tag">Facebook<span class="delete-tag"><i class="icon-cancel-circle-1" id="facebook-del"></i></span></span></div>');
});
And make sure, If you have the click event bounded to the parent and child div, when you click on child div you are stopping the parent events event. you may use stopPropagation to stop the bubbling event execution.

Click event listener for dynamic/moving anchors

I'm using a tutorial plugin - http://particlebits.com/code/jquery-tutorial/
which has this code attached to the number of tutorial steps you require.
<div for="tutstep4" data-target="#publishbutton" data-arrow="tc" data-location="tr" style="display: block; ">
<h1>Almost Done!</h1>
<p>
Now click "Publish" and you are done.
</p>
</div>
My question is how do I trigger a click event from the the tags that are attached to each tutorial step.
<a id="tutorial-done" class="tutorial-button" href="javascript:void(0);" style="display: block; ">Done!</a>
<a id="tutorial-cancel" class="tutorial-cancel" href="javascript:void(0);">X</a>
<a id="tutorial-next" class="tutorial-button" type="button" href="javascript:void(0);" style="display: none; ">Next</a>
<a id="tutorial-prev" class="tutorial-button" type="button" href="javascript:void(0);" style="display: block; ">Prev</a>
These tags are moved between steps with the same Id's so if I call
$('.tutorial-button').click(function(){
do something
})
the button has already been clicked and the function doesn't register.
I dont want to edit the tutorial.js file as it's used across different pages.
Is there something I can do to 'listen' to when '#tutorial-prev' is clicked and then call a function based on the div it' attached to?
i.e. if '#tutorial-prev' is clicked when the tutorial step is 3, do something ?
UPDATE:
After stepping away from it for a while I found an easier solution that simply use a monkey patch on the functions within the script and add my own personal code which consists of opening/closing the required div.
So it was like
$.fn.tutorialNext() {
// start of original next code.
//end of original code.
myfunc();
}
Not exactly pretty but a quick solution for the one page where I required something customised.
The issue I originally faced was that the anchor tags had already been removed when the Next() function was run so there was no element to perform the function on.
I'm not sure if I have clear what you are trying to achieve, but when you have the click handler:
$("'#tutorial-prev").on("click", dosomething);
In do something you can replicate the click event everywhere you want with:
$(selector).trigger("click");
with the js you posted, you bind the click event to every button with the tutorial-button class.
You could further specify a single button by using the element's id, for which you would need to bind one callback to each button.
$('#tutorial-prev').click(function(){ //go to previous step });
$('#tutorial-next').click(function(){ //go to next step });
$('#tutorial-cancel').click(function(){ //cancel actions });
...
UPDATE:
After stepping away from it for a while I found an easier solution that simply use a monkey patch on the functions within the script and add my own personal code which consists of opening/closing the required div.
So it was like
$.fn.tutorialNext() {
// start of original next code.
//end of original code.
myfunc();
}
Not exactly pretty but a quick solution for the one page where I required something customised.
The issue I originally faced was that the anchor tags had already been removed when the Next() function was run so there was no element to perform the function on.

Resources