How would one go about executing a function if an objects siblings do not have the pseudo class ":active" using jQuery? The reason for this question is that I would like to execute that function when the cursor is hovering the certain object and NONE of its siblings are ":active" (basic meaning: I want it to execute when the mouse is hovering the object and is not clicking down on any sibling).
To get the idea:
HTML:
<div class="tobehovered">...</div>
<div class="sibling">...</div>
...
JQuery:
function theOneToBeExecutedOnHover(){...}
$(".tobehovered").mouseenter(function(){
if( ... /* calculation???-ish */) theOneToBeExecutedOnHover();
}
The jQuery doesn't have to be formatted exactly that way. My example is just for principle.
From your hovered element $(this), find the siblings .siblings(), filter the active ones .filter(':active'), and check if you have none left .length === 0
That can be shortened like this:
if ($(this).siblings(':active').length === 0) {
Try this one
$(".tobehovered").mouseenter(function(event){
if(event.target.className == 'active'){
return;
}
//here execute function
}
Related
Trying to run a Javascript function only if click outside div1 AND div2. If clicked inside div1 or div2, nothing should happen. Any idea how I could achieve that? Example: I would need div2 to be set display: noneand additionally add styles to div1 when clicked outside the divs.
var x = document.getElementById("mega-menu");
document.addEventListener('mouseup', function(e) {
if (!(x.contains(e.target) || document.getElementById("menu-item-136").contains(e.target))) {
x.style.display = 'none';
var elem = document.querySelectorAll("#menu-item-136");
elem.forEach((elem) => {
elem.style.backgroundColor = "red";
});
}
});
This is the furthest I could get. But at the moment, div2 (mega-menu) also gets hidden when clicked on the menu item... Hope you understand what I mean...
Thanks
Can you complete your sample code above? I've added elements to your snippet, but can't duplicate your problem. It seems to be working for me.
Also a couple of off-topic best practices:
the HTML standard doesn't allow for elements with duplicate IDs. If you have more than one element with id #menu-item-136, you should be using a class instead of an ID.
Get both elements outside the event listener...more efficient (like you're already doing with #mega-menu)
Instead of having an if statement with a nested block, do an if...return instead. That way your code is less indented.
var x = document.getElementById('mega-menu');
var y = document.getElementById('menu-item-136');
document.addEventListener('mouseup', function(e) {
if (x.contains(e.target) || y.contains(e.target)) return;
x.style.display = 'none';
y.style.backgroundColor = 'red';
});
div { border: 1px solid black; }
<div id='mega-menu'>mega menu</div>
<div id='menu-item-136'>menu 136</div>
Looks like from this code,
document.querySelectorAll("#menu-item-136");
There are multiple elements with id "menu-item-136" as you are looping through the result.
First of all If there are multiple elements with same Id, It is not a valid HTML.
Thats why
document.getElementById("menu-item-136").contains(e.target)
this results in false, as it may have selected wrong element other that what you have clicked.
Even if you use class to get the elements, it may still fail as querySelector based on class will still results in returning multiple elements.
Instead of checking if your target element is contained in the div's - use a check to see if the element parent hierarchy have class name that you add for menu-item div.
if( e.target.closest(".container-class"))
So now you are just checking if current target have any parent with menu-item's class.
I am trying to select a certain element on a page. All the elements have the same class same everything, with the only exception that the background image is different on some of them.
What I need to do is to ONLY apply the jquery code to only the element chosen via the if statement.
Please note I cannot edit the HTML, I need to use jquery for this.
Here is my code:
$('.repeated-element').each( function(){
if ( $(this).css('background-image').indexOf('mystringzzz') ) {
//do something
alert("works");
$(this).closest('div.someclass').addClass('aclassilike');
//stop loop
return false;
}
});
I have selected the element just fine and jquery is running. I know this because I get the alert popup which shows that part (if ( $(this).css('background-image').indexOf('mystringzzz') ) {) works.
However, the problem is that I can only get it to apply to either the first element (which is not the one that is selected) or to all of the elements.
If I use:
$(this).closest('div.someclass').addClass('aclassilike');
the result is it applies to only the very first recurrence on the page, NOT the selected one.
Alternatively if I use:
$('.repeated-element').closest('div.someclass').addClass('aclassilike');
Then the result is it applies every recurrence on the page, not only the selected ones. It is supposed to be only the selected one.
How can I ONLY apply the jquery code to only the element chosen via the if statement?
For example,
a) inside the .repeated-element,
b) ONLY which contains a background-image css in the external stylesheet which has part of the image name as mystringzzz,
c) then apply the new jquery (in this example adding another class).
d) But do not apply it to elements which do not contain the mystringzzz string in background-image.
The source of the problem was that you weren't checking if the index did not equate to -1 in your indexOf() call. If you were to write this in the original format of your question it would look like this:
$('.repeated-element').each(function() {
if ($(this).css('background-image').indexOf('mystringzzz') !== -1) {
//do something
alert("works");
$(this).closest('div.someclass').addClass('aclassilike');
//stop loop
return false;
}
});
With all that being said jQuery's methods have certain use-cases depending on the scenario. I'd highly recommend just using filter() in this case:
$('.repeated-element').filter(function() {
return $(this).css('background-image').indexOf('mystringzzz') !== -1;
}).closest('div.someclass').addClass('aclassilike');
You can use the DOM directly from any event handler, if you're interested only on selected element.
$('.repeated-element').click(function(){
if ( $(this).css('background-image').indexOf('mystringzzz') ) {
//do something
alert("works");
$(this).closest('div.someclass').addClass('aclassilike');
//stop loop
return false;
}
});
It seems you also need to remove the url from the background-image property
$('.repeated-element').each(function() {
// removing url and only getting the image
var getURL = $(this).css('background-image').replace('url(', '').replace(')', '').replace(/\"/gi, "");
if (getURL.indexOf('mystringzzz') !== -1) {
$(this).closest('div.someclass').addClass('aclassilike');
}
});
.repeated-element {
color: red
}
.aclassilike {
background: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='someclass'>
<div style='background-image:url("mystringzzz")' class='repeated-element'>1</div>
</div>
<div class='someclass'>
<div class='repeated-element'>1</div>
</div>
<div class='someclass'>
<div class='repeated-element'>1</div>
</div>
<div class='someclass'>
<div style='background-image:url("mystringzzz")' class='repeated-element'>1</div>
</div>
This is probably a simple one but I can't seem to get it to work.
I have the following code:
<ul>
<li class='jSH'>Users: <span>0</span></li>
<li class='jSH'>Cars: <span>1</span></li>
</ul>
Essentially, I am trying to write a function that hides the li if the contents of span == 0. This is the jquery code but it doesn't work for some reason:
if ($('.jSH span').text() == "0")
$(this).closest('li').hide();
alert("should hide");
So, in this case, I get one alert for the first li (because the contents of span == 0), but the li does not hide.
Is there a problem with using 'this' in this case?
Thanks!
You would want to use .each since your current code returns multiple objects and their contents - .each will seperate them into a loop-like process where each individual element will be processed.
Fiddle:http://jsfiddle.net/fEEFq/
Javascript Code:
$('.jSH span').each(function(){
if ($(this).text() == "0"){
$(this).closest('li').hide();
alert("should hide");
}
});
Your problem is in $(this) - this, in the context of jQuery, only works when within a event callback (for example mouseover or click). You should fix that line to:
$('.jSH span').closest('li').hide();
Furthermore, you don't have {} around the body of the if statement. This will cause only the first statement after the if to be executed.
You can use $.filter
$('.jSH').filter(function() {
return $('span',this).text() == "0";
}).hide();
You're referring this to a conditional statement, which will not return your desired results.
Instead:
$('.jSH span').each(function(){
if ($(this).text() == "0"){ // now `this` is referring to every span in the jQuery collection
$(this).closest('li').hide();
}
});
http://api.jquery.com/each/
i have lots of divlayers with the class named ".current". depending on what the user does some of remove the class and some will get it again. this works fine, but what i want to is fire an event if only one div layer has the class ".current". how can i detect if only one element has the class current?
for example
if ($('#div4').hasClass('.current')) {
alert("fire me something");
}
something like "is the only one" hasClass.
in your event callback, simply check the number of divs that have the current class:
if ($('#div4').hasClass('current') && $('div.current').length === 1) {
...do stuff...
}
If you're only ever using current on divs, then you could just use $('.current').length === 1.
you should be able to use the css class as the selector and then get the length:
if($(".current").length == 1 ) {
alert('fire me something');
}
I "think" you could do:
if($('.current').length == 1) { //DO }
I believe the selector will return an array of the elements.
You have error syntaxe! you should add an ")" for your condition. and dont use the calss selecotr (".") . that's will work:
if($('#div4').hasClass('current')){
alert("fire me something");
}
You could see how many instances of the class .current that there are by using length. e.g.
var mycount = $(".current").length;
alert(mycount);
Then do whatever you like with the result.
See http://api.jquery.com/size/ or http://api.jquery.com/length/
$(".current").length
$(".current").size() *deprecated as of v1.8
Either will give you the count. Anytime you adjust the class check to see the count and fire the action if its 1
I've got a slideshow that's manually controlled with previous and next buttons. It works fine, but using insertBefore and insertAfter feels sloppy, so I'd like to explore some other methods. Instead, I'm thinking "if this is the last image, go back to the first + the opposite for going backwards.
Here's my code, but I'm not getting the desired result when it hits the last image (where it should fade in the first and start all over.
Syntaxual? if (slide == $('.z:last')) looks fishy to me.
Test site: http://brantley.dhut.ch/
Thanks!
Here's my JavaScript:
$('#next').click(function() {
var slide = $('.z:visible'),
next = $('.z:visible').next();
slide.fadeOut(400, function() {
slide.removeClass('active');
if (slide == $('.z:last')) {
$('.z:first').addClass('active');
bromance();
$('.z:first').fadeIn(400);
} else {
next.addClass('active');
bromance();
next.fadeIn(400);
}
});
return false;
});
Try this:
if (slide[0] == $('.z:last')[0]) { ...
jQuery doesn't return a reference to a DOM element directly, it returns an object that is array-like, where each array element is a DOM element matching the selector you used. This means comparing the results from two selectors is comparing two different array-like objects which isn't ever going to match even if they contain the same elements. Compare the first element in each array instead (because in your case you're expecting only one element anyway).
why don't you use slide = $('.active') and try :first-child instead of :first
next = $('.z:visible').next();
check the below condition and specify the next image accordingly.
if($('.z:last')){
next = $(".z:first")
}
else{
next = $('.z:visible').next();
}
I would compare element ids for equality.
Change if (slide == $('.z:last')) to if (slide.attr('id') === $('.z:last').attr('id')).
Or, you can test to see if the last slide is visible like so:
if ($('.z:last:visible')) {
// last slide is visible
}