jQuery on mouseout do nothing? - javascript

I have some effects in my menu, which works fine, but these effects shouldn't trigger on a menupoint which belongs to class "active". How should I do that? Using eval or similar things?
To sum it up: I want to deny an effect if the trigger has a special class.

In each of your mouse events, use .hasClass() in an if() statement:
$('.selector').mouseout(function() {
if($(this).hasClass('active'))
{
return;
}
// The rest of your code.
});
Here, the if() checks to see whether the element the event was fired on has the class active. If it does, the function returns, not executing any more code inside it.
You haven't given any code or HTML to work with, so this is a general solution. Please update your question with more detail so I can give you a better answer.

In the trigger function, just wrap your code with
if ($(this).not('.active')) {
...
}

JamWaffles and Cito's way works and are the most effective but just as an alternative you could also do it like this, first fetch the class value:
var className = $('.myclass').attr('class');
Then you want to check the value
if (className != 'whatever') {
// animate and stuff etc
}
But like I said, the other methods are better so you might as well use the built in features of jQuery such as hasClass - just showing theres more than one way to tackle problems :)

bind to (not) active like this:
$('.menuitem:not(.active)').live('mouseout',function(){});

Related

jQuery if data-id element hasClass not working

I don't know if the function i am trying to create is missing an element or if I am missing something but my function isn't working at all. Not sure if am missing something or if i am not adding something. let me know I provided jQuery and screenshot of the code i am trying to get to work. Basically what i am trying to do is if a certain element that has a data-id has a certain class then hide certain list-items.
$(function($){
if( $('.chbs-vehicle[data-id="313"] a').hasClass('chbs-state-selected') ){
$('ul.chbs-list-reset li(1)').hide();
}
});
li(1) isn't a valid expression and you should use a different evaluator:
$('ul.chbs-list-reset li:eq(0)')
$('ul.chbs-list-reset li:first-child')
$('ul.chbs-list-reset li').eq(0)
Take a look at this Demo
If your condition is met on page load, it works just fine. However, if the chbs-state-selected class is added dynamically, you need to listen for that change with an event handler. Your script as you have it doesn't constantly poll the document to see if Vehicle 313's a has the class.
Based on your comment, it sounds like you need to listen for that same click event that adds the chbs-state-selected class. Check out this rudimentary Demo.
Given this, you don't necessarily need to check for the class, just attach the hide/show functions to the same event. However, if necessary you can add the hasClass check to it.
Regardless, it should be inside that same handler that adds the chbs-state-selected in the first place
You can use eq: jquery function
$(function($){
if( $('.chbs-vehicle[data-id="313"] a').hasClass('chbs-state-selected') ){
$('ul.chbs-list-reset li:eq(0)').hide();
}
});

Checking if currently clicked element is equal to a specific div 'id' in JQuery

I have researched on the web and tested for a solution for quite a while, but have not been able to make this work. So I have decided to create a post here, even though its probably low-skilled and I'll get downvoted for it I have put a lot of effort and I hope someone can help out.
My code at the moment uses .click() function from JQuery and my goal is to use it on a button so that when I click that button, it checks whether the id of the button clicked on matches a variable that I set in the .js file. In other words, check if the thing I clicked on's id is equal to my "target".
This is the part of the code with the problem:
var target = '#vig_but_inc';
$(this).click(function() {
if(this.id == target) {
vigor.incStat(); // increase stats once
console.log("hi"); // test if code fires
$('#vig_res').html(vigor.current);
}
});
Please note I have checked if the code works without matching the id, without the if-statement - in that situation if I click on a specific, preset button's id I managed to increase the value of #vig_res which is my goal.
However with the if involved, as explained prior, I am trying to match what is being clicked on with my target, which is the id name I wish it to match to. I'm using this to check my click, which has worked in other areas but doesn't seem to work in this context.
I have made the variable target global scope as explained here in the comments: Check if the clicked div id matches with variable. It still doesn't work.
I know and have tested $(this).click(.., where it would fire off the code inside of whatever div I clicked. So I believe the problem lies afterwards, maybe in the this.id, but I've also used .is() like suggested elsewhere but it won't work that way either.
I hope someone can give me some insight into how to tackle this problem, thank you.
The answer is a little more complicated, in the anonymous function which is called when the click is triggered, this is not the clicked element, it is a jQuery object. You should accept as first parameter event and use event.target. Plus, target should not contain the #, because the .id returns only the name.
So, your code should look like this:
var target = 'vig_but_inc';
$(this).click(function(event) {
console.log(event.target);
if(event.target.id == target) {
vigor.incStat(); // increase stats once
console.log("hi"); // test if code fires
$('#vig_res').html(vigor.current);
}
});
Working Fiddle: https://jsfiddle.net/e8np0g9j/3/
Use the id and class selected before calling the click function like
$('.class').click(function() {});

jQuery Waypoints add class when element is scrolled into view

I'm using the Waypoints plugin to check if an element is scrolled into view. I have multiple divs with class item as the user scrolls down the page, I want to add a class "viewed" to each.
$(".item").waypoint(function(){
$(this).addClass("viewed");
console.log("yey");
});
The console.log works, but the .addClass doesn't. Does the plugin not support $(this)?
I finally got it working.
$(".item").waypoint(function(){
$(this[0,'element']).addClass("viewed");
});
The this wasn't pointed at the element, so I needed to target it.
You have to be careful when calling these callback functions, and what this really means. In this instance, its probably referring to your function.
Doesn't the event trigger pass the target in the function as an argument? Try using that. If you want to know what your nested this really is, console.log it.
$(".item").waypoint(function(thing){
$(thing).addClass("viewed");
console.log("yey");
});
The checked answer caused loads of errors in newer version of this plugin.
This is what works for me:
$(".item").waypoint(function() {
$(this.element).addClass("viewed");
});

Can I rewrite Javascript without using 'this'?

I'm very new to JS and I'm having trouble getting this to work.
Here is my code
jQuery('ul.menu li').each(function() {
jQuery(this).removeClass('current-menu-item');
jQuery(this).removeClass('current_page_item');
});
jQuery(this).parents('li').addClass('current_page_item');
jQuery(this).parents('li').addClass('current-menu-item');
Now what this should be doing is remove the highlight from one link on a navigation menu, and highlighting the one thats been clicked (I have an AJAX implementation).
For some reason it isn't doing anything. I have a feeling it is due to 'this' is there another way of structuring this code so I can work out if the code is wrong, which I don't believe it to be, or because of 'this'?
EDIT:
Apologies, it seems I haven't given enough information. I'm using the Twenty Fourteen wordpress theme but I'm serving the pages with AJAX.
http://twentyfourteendemo.wordpress.com/
I have the code being applied globally (I have other code in the same place to toggle the navigation once clicked (on mobile) and that works fine)
I have the menu at the top (without any dropdowns, just links). I can't give a link as it's not external currently. Should my code be working to change this?
As a few people have commented "What is 'this'" I feel I've completely missed something.
You don't need loop each item to do a remove class one by one, this is more easy :
jQuery('ul.menu li').removeClass('current-menu-item').removeClass('current_page_item');
Or (it's the same) :
jQuery('ul.menu li').removeClass('current-menu-item current_page_item');
But I don't understand what is this 'this' :
jQuery(this).parents('li').addClass('current_page_item');
jQuery(this).parents('li').addClass('current-menu-item');
Do you mean :
jQuery('ul.menu li').addClass('current_page_item current-menu-item');
Or if you are on an event listener (like click, as #Daniel Sanchez feel on comment) you just need to do :
jQuery('ul.menu li').click(function(){
// Remove class on each item
jQuery('ul.menu li').removeClass('current-menu-item current_page_item');
// Add class for this one
jQuery(this).addClass('current_page_item current-menu-item');
})
It's not entirely clear what you are trying to do but the code can be simplified somewhat:
jQuery("ul.menu li a").click(function(){
jQuery('ul.menu li').removeClass('current-menu-item current_page_item');
jQuery(this).parent('li').addClass('current_page_item current-menu-item');
});
http://jsfiddle.net/re3hjzyf/
Yes, by replacing this with 'ul.menu li'.
So the code would be like this
jQuery('ul.menu li').each(function() {
jQuery('ul.menu li').removeClass('current-menu-item')
.removeClass('current_page_item');
});
// not sure what the following code is referencing too
// it is outside the bounds of .each() function.
jQuery(this).parents('li').addClass('current_page_item');
jQuery(this).parents('li').addClass('current-menu-item');
what is this
When working with JavaScript and many Object Oriented programming languages the this keyword is used to refer to the current context that the programmer is working with. You're currently referencing to the ul.menu li element so by using this you make a call to the element that is selected in the .each() function.
You can replace it by using the element selector that you used in the each() function.
jQuery('.current-menu-item').removeClass('current-menu-item');
jQuery('.current_page_item').removeClass('current_page_item');
Here I am making the assumption that only one item will ever have those classes as it would denote which menu item is currently selected. The best way to select it is then to search for the class you want to remove. (If those classes always go together, you could also remove both on the same line, although then you might want to consider whether you actually need both.
jQuery('ul.menu li').on("click", function() {
jQuery(this).addClass('current_page_item').addClass('current-menu-item');
}
You can only use "this" as an argument for the selector when "this" has a value (i.e : inside an each loop or inside on.
In this case I am using the on() function to apply the function which adds the class to any of the list items which gets clicked on.
Merging the two you would then end up with :
jQuery('ul.menu li').on("click", function() {
jQuery('.current-menu-item').removeClass('current-menu-item');
jQuery('.current_page_item').removeClass('current_page_item');
jQuery(this).addClass('current_page_item').addClass('current-menu-item');
}

onclick event not firing javascript

EDIT #2:
Made a JS Fiddle... http://jsfiddle.net/N2p6G/ (I hardcoded some stuff that I'm certain works correctly, but the problem is still there)
Original:
So, I have written tens of thousands of lines of javascript, and used code that look like this a hundreds of times and I don't understand what's going on.
blacklistitembutton.onclick = function() {
console.log("clicked.");
}
The above code does not seem to be working... and I can't figure out why
In fact, I use the same method earlier in the same file... and it works fine!
settings.onclick = function() {
settings_popup.toggle();
}
EDIT:
Might it have something to do with the fact that it's being executed in a for loop?
Here is the code...
var blacklistButton = document.createElement('input');
blacklistButton.type = 'button';
blacklistButton.value = "Add Current Site to Blacklist";
blacklistButton.onclick = function() {
console.log('blacklistButton clicked');
}
for (var i=0;i<blacklist.length;i++) {
var blacklistitembutton = document.createElement('div');
blacklistitembutton.type = 'button';
blacklistitembutton.blacklistValue = blacklist[i];
blacklistitembutton.value = "X";
blacklistitembutton.onclick = function() {
console.log("clicked.");
}
}
Then both blacklistButton and all of the blacklistitembuttons are put into the document through element.appendChild (and they all show up successfully!)
The blacklistButton onclick fires just fine, and the blacklistitembutton onclick does not.
document.addEventListener('click', function(){
console.log('clicked');
}, false);
Edit:
Here is a re-write of your code in a fiddle: http://jsfiddle.net/N2p6G/1/
There are a lot of things in your code that worry me. Hopefully from my re-write you can see there are better ways to handle some things.
1) I'm not sure why you are using document.write() at the beginning. That has very little purpose.
2) You are modifying the DOM way too much. Some of the DOM elements you are creating in code are better-served as just being target locations in html. Only the dynamically-created input button elements need to be done in javascript. Remember, modifying the DOM should be done as little as possible.
3) Don't assign events using the onclick, onsubmit, onhover, etc syntax. Events should only be bound to DOM elements using addEventListener. The other benefit of doing it the proper way is that you can assign multiple events of the same type, if need be, to the same element. Also, with some extra state code that I haven't included, you can selectively remove particular events later if you need to.
4) There was a debate several years ago about whether using innerHTML and string templates was faster/better than using DOM creation methods. For a while, the best solution was to use documentFragments and a combination of the two methods. These days, it doesn't really matter anymore since all browsers are pretty damn fast, so for simplicity's sake is good to just go with innerHTML.
This also goes back to the rule of "don't touch the DOM too much". If you look at my code, you can see that I'm assembling the final html simply as an array of elements that gets joined as a single string at the end. Its then rendered to the DOM with a single innerHTML statement. I'm only touching the DOM one time, instead of multiple times.
5) The last bit goes into events again. At the beginning and end of the code you can see where and how I've added the events for the DOM elements. Indeed, the addEventListener at the beginning could be moved to the end to group all the event declarations together, but it doesn't really matter. I left it at the top to help you understand what's going on better.
Hope this helps.
For unlimited event bindings, either use addEventListener or attachEvent method. You cannot add more than one event of the same type using that traditional method.
I don't know if it's a typo in what you put here, but in the loop you are creating a "div" and then assigning it a type of "button". Does that work or is it throwing an error? If it is then that explains why the event handler is not getting the function. Try making it an "input" and see if it now works.
Fixed it!
blacklistitem.innerHTML += blacklist[i];
^ was messing it up, at this point in the code blacklistitem is still a javascript item, not yet appended to its to-be parent element in the document
So I just stuck blacklist[i] into a span tag and appended as a child and now it works fine :)

Categories