First of all, sorry if this is a simple question. I am new to jQuery and I want to know how can I check if an element exists and if it does, change the css property.
Here is what I mean: I have the following list:
<ul class="element-rendered">
<li class="element-choice">Item A</li>
<li class="select-inline">Item B</li>
</ul>
I want to know how can I check if the class select-inline exists inside element-rendered and if it does, how can I change the css background of element-choice to blue?
I created a fiddle to reproduce this example.
Again sorry if this is a simple question but I am new to jQuery.
You can use .length to check if the element exists in DOM.
$('.element-rendered .select-inline') will select all the elements having class select-inline inside the element with class element-rendered. .length on selector will return the number of matched elements. So, number greater that one, means the element exists. Then you can use .css to set inline styles.
Demo
if ($('.element-rendered .select-inline').length) {
$('.element-choice').css('background', 'blue');
}
.element-choice {
width: 100%;
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<ul class="element-rendered">
<li class="element-choice">Item A</li>
<li class="select-inline">Item B</li>
</ul>
I'll also recommend you to use class in CSS and add it to the element by using addClass.
Demo
var eR = $(".element-rendered");
if (eR.find(".select-inline").length > 0){
eR.find(".element-choice").css("color", "blue");
}
This would work for your specific example.
Find the select-line element which is a child of element-rendered.
The find all of the sibling elements with class element-choice and apply the css.
$('.element-rendered>.select-inline').siblings('.element-choice').css('background','blue')
http://jsfiddle.net/SeanWessell/hjpng78s/3/
To check if element exists could use .is() , or as suggested by #Tushar .length
var container = $(".element-rendered");
// alternatively `!!$(".select-inline", container).length`
$(".select-inline", container).is("*")
&& $(".element-choice", container).css("background", "blue");
jsfiddle http://jsfiddle.net/hjpng78s/6/
Demo
if($(".element-rendered .select-inline")[0])
$(".element-rendered .select-inline").css("background-color","red");
How can I check if the class select-inline exists inside element-rendered and if it does, how can I change the css background of element-choice to blue?
if ( $(".element-rendered > .select-inline").length ) {
$(".element-rendered > .element-choice").css({
'background-color': 'blue'
});
}
Docs:
Find the number of elements in the jQuery object.
Set one or more CSS properties for the matched element
Related
I have an unordered list and the index of an li tag in that list. I have to get the li element by using that index and change its background color. Is this possible without looping the entire list? I mean, is there any method that could achieve this functionality?
Here is my code, which I believe would work...
<script type="text/javascript">
var index = 3;
</script>
<ul>
<li>India</li>
<li>Indonesia</li>
<li>China</li>
<li>United States</li>
<li>United Kingdom</li>
</ul>
<script type="text/javascript">
// I want to change bgColor of selected li element
$('ul li')[index].css({'background-color':'#343434'});
// Or, I have seen a function in jQuery doc, which gives nothing to me
$('ul li').get(index).css({'background-color':'#343434'});
</script>
$(...)[index] // gives you the DOM element at index
$(...).get(index) // gives you the DOM element at index
$(...).eq(index) // gives you the jQuery object of element at index
DOM objects don't have css function, use the last...
$('ul li').eq(index).css({'background-color':'#343434'});
docs:
.get(index) Returns: Element
Description: Retrieve the DOM elements matched by the jQuery object.
See: https://api.jquery.com/get/
.eq(index) Returns: jQuery
Description: Reduce the set of matched elements to the one at the specified index.
See: https://api.jquery.com/eq/
You can use jQuery's .eq() method to get the element with a certain index.
$('ul li').eq(index).css({'background-color':'#343434'});
You can use the eq method or selector:
$('ul').find('li').eq(index).css({'background-color':'#343434'});
There is another way of getting an element by index in jQuery using CSS :nth-of-type pseudo-class:
<script>
// css selector that describes what you need:
// ul li:nth-of-type(3)
var selector = 'ul li:nth-of-type(' + index + ')';
$(selector).css({'background-color':'#343434'});
</script>
There are other selectors that you may use with jQuery to match any element that you need.
You could skip the jquery and just use CSS style tagging:
<ul>
<li>India</li>
<li>Indonesia</li>
<li style="background-color:#343434;">China</li>
<li>United States</li>
<li>United Kingdom</li>
</ul>
The title sounds strange but what I want to achieve is simple.
In a tree of uls I want to get all li children from any ul that have not the - inline - style display: none. So I found this post and I mixed with the negation function :not(). The result was:
'ul:not([style*="display: none"]) .k-item'
Where .k-item is a common class for all my li elements. That selector worked in this simple fiddle. The problem is that it doesn't works in my application. I have a screenshot of some console commands that will illustrate my scenario:
As you can see on second command, it returns some li elements that lies under an ul which haves display: none among other attributes in its inline style. Example of those unexpected li with attribute data-uid with values starting with 099d, bbca and 14d2.
I don't know what I'm doing wrong or if exists a better selector for that purpose.
I would suggest using jQuery's :visible rather than looking for something in the style string and string matching in the style string could be problematic.
$("ul:visible .k-item")
First of all get all the li and check whether its parent (ul) is visible.
jsfiddle
$('li', '#layers').each(function(){
if($(this).parent().is(":visible")){
alert($(this).text())
}
});
OR
a neat version
jsfiddle
$(".k-item:visible").each(function(){
alert($(this).text())
});
Try using
$('ul:not([style*="display: none"]) li.k-item').each(function() { alert($(this).html()) });
HTML
<ul style="display: none">
<li class="k-item">1</li>
<li class="k-item">2</li>
<li class="k-item">3</li>
</ul>
<ul>
<li class="k-item">4</li>
<li class="k-item">5</li>
<li class="k-item">6</li>
</ul>
Fiddle: http://jsfiddle.net/3M2ZM/
I have this HTML:
<ul class="how-long">
<li value="1">Any</li>
<li value="1">1 day</li>
<li value="2">Week end</li>
<li value="7">1 Week</li>
<li value="14">2 Week</li>
<li value="21">3 Week</li>
</ul>
On document ready I want to add new class to the 4th li element.
This is what I tried:
$(".how-long li").slice(3).addClass('change-color');
If I put an alert as:
alert($(".how-long li").slice(3).html());
it gives me 1 week which is right, but when I addclass the class is added to all li after 4th li.
I want to this without adding ID to each li element.
I can hard code class in li element directly but I want to do it dynamicaly using jQuery.
To do it in one selector, use nth-child or eq:
nth-child is considerably faster, see my jsPerf here: http://jsperf.com/nth-child-vs-eq
nth-child:
$(".how-long li:nth-child(4)").addClass('change-color');
eq:
$(".how-long li:eq(3)").addClass('change-color');
The fundamental difference is that nth-child will give you the 4th element of every item with that class (regardless of whether it is a child of the current item), whereas eq will give you the children on the current item.
$(".how-long li").eq(3).addClass('change-color');
slice doesn't return a jQuery object, therefore you can't use the method addClass.
The right way to do what you intend is:
by index:
$(".how-long li").eq(3).addClass('change-color');
by referencing value:
$(".how-long li[value=7]").addClass('change-color');
If you want to use slice method you need to specify end attribute which you are missing
$(".how-long li").slice(3,4).addClass('change-color');
It selects the 4th because Array index's start from 0.
You could always use $('.how-long li:nth-child(4)');
More information here: http://api.jquery.com/nth-child-selector/
You can use the nth-child selector:
$(".how-long li:nth-child(4)").addClass('change-color');
alert($(".how-long li:nth-child(4)").html());
Do it this way
$(".how-long li:nth-child(4)").attr({'class':'test'});
This will add class test to the 4th li
Hope this heps
I'm using wordpress 3.5 and create menu with submenus. It's structured like this:
<ul class="menu">
<li id="menu1">Menu 1</li>
<li id="menu2">Menu 2</li>
<li id="menu3" style="z-index:100;">
Menu 3
<ul class="submenu">
<li id="submenu1">submenu1</li>
<li id="submenu2">submenu2</li>
<li id="submenu3">submenu3</li>
</ul>
</li>
</ul>
The problem is the menu with submenus, it's automatically attached a z-index with value 100. I don't want it to be like that because it gives me trouble on adding lavalamp effect to those menus.
I tried to edit the z-index by using jquery just after the menu is created using wp_nav_menus simply like this:
jQuery(document).ready(function(){
jQuery("#menu3").css("z-index", "0");
});
But unfortunately, it doesn't work. How can I remove that inline css style?
Use the removeAttribute method, if you want to delete all the inline style you added manually with javascript.
element.removeAttribute("style")
Reset z-index to initial value
You could simply reset the z-index to it's initial value causing it to behave just like the li would without the style declaration:
$(function(){
$('#menu3').css('z-index', 'auto');
});
You can go vanilla and use plain javascript (code should run after your menu html has loaded):
// If you're going for just one item
document.querySelector('#menu3').style.zIndex = 'auto';
Remove style attr
You could use jQuery to remove the style attributes from all your list:
Note: Keep in mind this will remove all styles that have been set to your element using the style attribute.
$(function(){
$('#menu3').removeAttr('style');
});
Or vanilla:
// Vanilla
document.querySelector('#menu3').style = '';
If you want remove all inline styles, Pranay's answer is correct:
$("#elementid").removeAttr("style")
If you want to remove just one style property, say z-index, then you set it to an empty value:
$("#elementid").css("zIndex","")
From the jQuery documentation (http://api.jquery.com/css/):
Setting the value of a style property to an empty string — e.g. $('#mydiv').css('color', '') — removes that property from an element if it has already been directly applied, whether in the HTML style attribute, through jQuery's .css() method, or through direct DOM manipulation of the style property.
This is what I consider a better approach because it only removes the z-index style instead of the whole style attribute. Here is a working Fiddle.
//As commented by #DA this is enough
$("#elementid").css("zIndex","")
//this could be useful in another situation so I will leave it :)
$(document).ready(function () {
$('#menu3').attr('style', function(i, style){
return style.replace(/\z-index\b[^;]+;?/g, '');
});
});
Hope it helps.
The JQuery "has" method effectively selects all elements where they have particular descendants.
I want to select elements based on the fact they have particular ancestors. I know about parent([selector]) and parents([selector]) but these select the parents and not the children with the parents.
So is there an ancestor equivalent of "has"?
Note: I already have the context of an element further down the hierarchy and I will be selecting based on this so I can't do a "top down" query.
Update
I've obviously explained myself really badly here, so I'll try and clarify:
<ul class="x">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<ul class="y">
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
I have a jQuery object that already consists of elements 2,3,4 and 5. I want to select those elements who have a parent with the class = x.
Hope that makes more sense.
For a clean re-usable solution, consider extending the jQuery.fn object with a custom method used for determining the presence of a particular ancestor for any given element:
// Extend jQuery.fn with our new method
jQuery.extend( jQuery.fn, {
// Name of our method & one argument (the parent selector)
within: function( pSelector ) {
// Returns a subset of items using jQuery.filter
return this.filter(function(){
// Return truthy/falsey based on presence in parent
return $(this).closest( pSelector ).length;
});
}
});
This results in a new method, $.fn.within, that we can use to filter our results:
$("li").within(".x").css("background", "red");
This selects all list items on the document, and then filters to only those that have .x as an ancestor. Because this uses jQuery internally, you could pass in a more complicated selector:
$("li").within(".x, .y").css("background", "red");
This will filter the collection to items that descend from either .x or .y, or both.
Fiddle: http://jsfiddle.net/jonathansampson/6GMN5/
if ( $('.foo').parents('.parentSelector').length ) { // has parent }
If I understand your question correctly, this would do:
$.fn.hasAncestor = function(a) {
return this.filter(function() {
return !!$(this).closest(a).length;
});
};
$('.element').hasAncestor('.container').myAction();
<div class="container">
<span>
<strong class="element">strong</strong>
</span>
</div>
$('body').hasParent('html') //true
$('div#myDiv').hasParent($('body')) //true
#API:
// check if current element has parent element 'e'
$.fn.hasParent = function (e) {
return !!$(this).parents(e).length
}
You can actually use filter directly (without a function calling closest) and it will have better performance. Simply use a selector that matches elements contained within .x:
$("li").filter(".x *")
this also differs slightly from the closest solutions suggested by others in that it will not match if the element itself has the given class but only if it is within an element with that class.
If matching an element with the class is desired as well, this could be modified slightly:
$("li").filter(".x, .x *")
$("li").filter(".x *").css("background", "red");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="x"><li>1</li><li>2</li><li>3</li></ul>
<ul class="y"><li>4</li><li>5</li><li>6</li></ul>
Try this
ul.myList > li > a
This selector selects only links that are direct children of list elements, which are
in turn direct children of elements that have the class myList.
object.each(function(){
element = $(this);
if(element.parent().hasClass("x")){
//do stuff
}
});
this will affect every item in your object that has parent .x
The easy way is this:
// all children of a specific parent match
$('parentSelector').children();
// All children matching a specific pattern, one level deep
$('parentSelector > childSelector');
// or
// $('parentSelector').children('childSelector');
// All children matching a specific pattern, multiple levels deep
$('parentSelector childSelector');
// or
// $('parentSelector').find('childSelector');
or did you really need something more complicated than that?
Edit: If you already have an element, you can combine this with the parent() command, like so:
myElement.parents('parentSelector').find('childSelector'); // Will include self
I realize this is an old question, but I'm leaving this here for future visitors looking for something similar;
There is a $.contains(container, contained) method which returns a boolean.
https://api.jquery.com/jQuery.contains/
Very simple way to do it
$('.x').find('li')