Remove element when it has a specified child element - javascript

How can I delete list element if it has a child link of some defined id ? So looking at the code below I'd like to find a <li> with <a> of id=link1 and delete this li.
<li class="nav-tab">
Component
</li>
I've tried the code below but it doesn't work :
$(function() {
$('.nav-tab:has(#link1)').css('display', 'none');
});

Your question and your code contradict each other, so I'll provide answers for both cases.
If you want to remove a <li class="nav-tab"> that contains a child <a href="#link1">:
$(function() {
$('a[href="#link1"]').parent('li.nav-tab').remove();
});
If you want to remove a <li class="nav-tab"> that contains a child <a id="link1">:
$(function() {
$('a#link1').parent('li.nav-tab').remove();
});

You can use an attribute-equals selector and :has() to see if it contains an element matching that...then just call .remove() on that.
$("li:has(a[href='#link1'])").remove()

$(function() {
$(".nav-tab > a[id='yourID']").css('display', 'none');
});
If by anchor :
$(function() {
$(".nav-tab > a[href='yourLink']").css('display', 'none');
});

Related

How to find the class of element in a each loop

I am trying to create a menu system where I can change the style of the active page item in the menu. I am using a separate body class on each page, then I want to cycle through the li in the menu and find a match to the body class. At that match I will add the new styling to that menu item.
Here is my code so far.
HTML
<body class="home-state">
...
<div class="menu-left">
<ul>
<li class="home-state">
Home
</li>
<li class="work-state">
Work
</li>
<li class="services-state">
Services
</li>
<li class="about-state">
About
</li>
<li class="blog-state">
Blog
</li>
<li class="shop-state">
Shop
</li>
<li class="contact-state">
<a data-toggle="modal" href="#modal-coworking">Contact</a>
</li>
<li class="project-state">
Project brief
</li>
</ul>
</div>
...
</body>
JS
var bodyClass = $("body").attr('class');
$('.menu-left ul li').each(function(){
First: I want to find the element's class here I have used $(this).attr("class"); which didn't work
var element = $(this);
Second: I want to use a if statement to check to see if the class matches the bodyClass
console.log(element);
Last: If there is a match I want to add the class .active to the element li.
});
Given that elements can have multiple classes, I'd suggesting changing your body element to use a data- attribute rather than a class to specify what the current page is:
<body data-current="home-state">
Then the JS needed to add the active class to the relevant menu item is simple:
$("li." + $("body").attr("data-current")).addClass("active")
You don't need to loop over the menu items comparing classes as mentioned in the question, because you can just directly select the required li element based on its class.
In the event that the body element doesn't have a data-current attribute then $("body").attr("data-current") would return undefined, which would mean the code above tries to select an element with $("li.undefined") and add a class to it. Probably you have no elements with such a class so that would be harmless, but if you wanted to explicitly test that the data-current attribute exists:
var current = $("body").attr("data-current")
if (current) {
$("li." + current).addClass("active")
}
You can do this in couple ways, here is the simple way to do this;
var bodyClass = $("body").attr('class');
$("li." + bodyClass).addClass("active")
You can also use a loop for this one;
var bodyClass = $("body").attr('class');
$(".menu-left li").each(function(i, classes) {
if (bodyClass === $(this).attr("class")) {
$(this).addClass("active")
}
})
both will do the job.
enter image description here
enter image description here
as the comment said,the element can have more than one class ,so you should check it one by one
You missed to bind the click event for the menu item. Follow like below
var bodyClass = $("body").attr('class');
$('.menu-left ul li').on( "click", function() {
var myClass = $(this).attr("class");
alert(myClass);
});
Tested: https://codepen.io/anon/pen/XzYjGY

Find if current class contains word, then append new class to those li's - jquery

Having some problems with jQuery methods - perhaps overcomplicating things...
What I need to find is if any of the li elements classes contain the word 'current', then if they do, append the word active to them.
I'm struggling to add the word to the end of the current class. For example:
Markup:
<div class="menu-navigation-container">
<ul>
<li class="current_page_item menu-item-8787"><span>The Magazine</span>
</li>
<li class="menu-item menu-item-type-post_type"><span>Snapped</span>
</li>
</ul>
</div>
jQuery:
$(document).ready(function () {
var classNames = $('.menu-navigation-container ul li').attr("class").match(/[\w-]*current[\w-]*/g);
$(classNames).each(function () {
$(this).addClass("active");
});
});
Running classnames; up in the console produces just the string - I want it to reference the li elemens that have the word 'current' in their class names, then append the word 'active' at the end.
Can I do this with jQuery's attribute contains selector?
Simply like this :
$(document).ready(function () {
$('.menu-navigation-container ul li[class*=current]').addClass('active');
});
Try this
$(document).ready(function () {
$('.menu-navigation-container ul li').each(function(){
if ( $(this).is(".current") )
{
$(this).addClass("active");
}
})
});

nth-child increase decrease with click

I have a set of li elements forming a menu. When the user clicks a particular li element I want to change the source of an iframe element to the URL that corresponds to the clicked item.
I've tried the function below but it didn't work. Can somebody please advise how to do this?
http://jsfiddle.net/ZnMTK/8/
$(document).ready(function(){
var source1="http://www.hurriyet.com.tr";
var source2="http://www.milliyet.com.tr";
var source3="http://www.vatan.com.tr";
var source4="http://www.ensonhaber.com";
$("#menubar ul li:nth-child(i)").click(function(){
$(this).attr('src', source(i) );
});
});
You can use an array and then use the clicked li elements index to fetch the target source from array.
$(document).ready(function(){
var sources =["http://www.hurriyet.com.tr","http://www.milliyet.com.tr","http://www.vatan.com.tr","http://www.ensonhaber.com"],
$("#menubar li").click(function(){
$('#iframe1').attr('src', sources[$(this).index()])
});
});
Demo: Fiddle
This type of functionality is what arrays are for:
$(document).ready(function(){
var sources =["http://www.hurriyet.com.tr","http://www.milliyet.com.tr","http://www.vatan.com.tr","http://www.ensonhaber.com"],
i = 0;
$("#menubar li").click(function(){
$("#iframe1").attr('src', sources[$(this).index()] );
});
});
However, specifying all of your URLs in your JavaScript and relying on the indices matching up with the order of the menu li elements is kind of fragile. I would recommend linking the values more closely, perhaps something like this:
<ul id="menubar">
<li data-src="http://www.hurriyet.com.tr">Hurriyet</li>
<li data-src="http://www.milliyet.com.tr">Milliyet</li>
<li data-src="http://www.vatan.com.tr">Vatan</li>
<li data-src="http://www.ensonhaber.com">Ensonhaber</li>
</ul>
And then with JS:
$(document).ready(function () {
$("#menubar li").click(function () {
$("#iframe1").attr('src', $(this).attr("data-src"));
});
});

Adding a Space when using addClass and variables using jQuery

I have jQuery read some text then add a class based on the value of this text. (The text read is rendered by my CMS).
The HTML Looks like this:
<ul class="zoneSubscriptions">
<li>
<ul>
<li class="zoneName">Professional</li>
<li>Never</li>
</ul>
</li>
<li>
<ul>
<li class="zoneName">RTTM</li>
<li>Never</li>
</ul>
</li>
</ul>
I want to read the text of class="zoneName"and add a class based on this.
JS to do this:
$(function() {
var zone = $( ".zoneName" ).text();
$( "#zones" ).addClass( zone );
});
This works without issue, however, I need it to add two classes, Professional and RTTM. What it adds is ProfessionalRTTM.
My question is how would I add the classes while keeping a space between the words?
In other words it should render like this: class="Professional RTTM" not class="ProfessionalRTTM"
Note: In my example there are two "zoneName"s. There could be anywhere from 1 to 5 or more when used live.
Try iterating the tags:
var $zones = $("#zones");
$(".zoneName").each(function () {
$zones.addClass( $(this).text() );
});
Also possible (if you want to reuse the list of class names)
var classes = [];
$(".zoneName").each(function () {
classes.push($(this).text());
});
$("#zones").addClass(classes.join(" "));
You're calling .text() on multiple results which is joining them together.
Why not do something like this instead:
var zone = $( ".zoneName" ).each(function(){
$("#zones").addClass($(this).text());
});
Find all your .zoneNames and then call addClass for each one.
jsFiddle example
You need to iterate across the .zoneNames, otherwise your .text() will be a one undivided string (unless you have whitespace in there)
$(".zoneName").each(function() {
$("#zones").addClass($(this).text());
});
You can use the callback function of addClass(), and use map() to get an array of the text, then simply join with a space:
$('#zones').addClass(function() {
return $('.zoneName').map(function() {
return $(this).text();
}).get().join(' ');
});
Here's a fiddle

JQuery each loop problem

I have the following code
<div>
test
<ul>
<li class="action_li">1</li>
<li class="action_li">2</li>
</ul></div> <div>
test
<ul>
<li class="action_li">3</li>
<li class="action_li">4</li>
</ul>
and I want to loop on all the <li> that are enclosed with the same <div> as the clicked <a>
$("a.clickMe").live("click", function(eve){
eve.preventDefault();
$('.action_li').each(function(index) {
console.debug(this);
});
});
but of course this will get me all the 4 <li> not the two enclosed
so I want to have something that starts with $(this) and ends with .each()
There are many ways, examples:
$(this).parent().find("li.action_li").each(function(index) {
console.debug(this);
});
or:
$(this).next("ul").children("li.action_li").each(function(index) {
console.debug(this);
});
etc.
This should work:
$("a.clickMe").live("click", function(eve){
eve.preventDefault();
$('.action_li', $(this).parent()).each(function(index) {
console.debug(this);
});
});
Second parameter next to the selector will limit the search to only part of the DOM tree, in this part to the one div which is parent for a element.
You need to get the <ul> element that is a sibling of the <a>, then get its children.
For example:
$(this).siblings('ul').children('li.action_li').each(function(index) {
//...
});
You could also call $(this).next() or $(this).nextAll('ul').
This might work:
$(this).parents('div').find('li').each(...

Categories

Resources