I'm trying to select theses elements with JQuery :
<div attribute="distinct-value"> <!-- i only want links in this one, select based on the attribute -->
<div>
<div>
<div class="col1">
<ul>
<li>
<!-- i want this -->
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</li>
</ul>
<ul>
<li>
<!-- and this... -->
<ul>
<li></li>
</ul>
</li>
</ul>
</div>
<div class="col2">
<ul>
<li>
<!-- and this... -->
<ul>
<li></li>
<li></li>
</ul>
</li>
</ul>
<ul>
<li>
<!-- and this... -->
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</li>
</ul>
</div>
<!-- col3, col4, etc, etc... -->
</div>
</div>
</div>
<div attribute="another-distinct-value">
<!-- same content structure has 'distinct-value div' -->
</div>
<div attribute="another-other-distinct-value">
<!-- same content structure has 'distinct-value div' -->
</div>
I want the first link in the first li of every ul markups that are not inside a li, for every div that has a "col" class. I hope everything is clear..
Can someone help me out ?
Loop through your elements like so
$('div[attribute="distinct-value"] [class^=col] li:has(ul) > a').each(function(index) {
console.log( index + ": " + $( this ).text() );
});
console.log($('div[class^=col] > ul > li > a'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div attribute="distinct-value">
<div>
<div>
<div class="col1">
<ul>
<li>
<!-- i want this -->
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</li>
</ul>
<ul>
<li>
<!-- and this... -->
<ul>
<li></li>
</ul>
</li>
</ul>
</div>
<div class="col2">
<ul>
<li>
<!-- and this... -->
<ul>
<li></li>
<li></li>
</ul>
</li>
</ul>
<ul>
<li>
<!-- and this... -->
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</li>
</ul>
</div>
<!-- col3, col4, etc, etc... -->
</div>
</div>
</div>
You can target li that has ul in it along with immediate child selector(>) to target immediate child anchor element:
$('[class^=col] li:has(ul) > a');
You can iterate over above set of elements and perform the task. If you want to get all the hrefs of anchor element, you need to use .map() with .get():
var allhref = $('[class^=col] li:has(ul) > a').map(function(){
return $(this).attr('href');
}).get();
var allhref = $('[class^=col] li:has(ul) > a').map(function(){
return $(this).attr('href');
}).get();
alert(allhref);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div attribute="distinct-value">
<div>
<div>
<div class="col1">
<ul>
<li>
<!-- i want this -->
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</li>
</ul>
<ul>
<li>
<!-- and this... -->
<ul>
<li></li>
</ul>
</li>
</ul>
</div>
<div class="col2">
<ul>
<li>
<!-- and this... -->
<ul>
<li></li>
<li></li>
</ul>
</li>
</ul>
<ul>
<li>
<!-- and this... -->
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</li>
</ul>
</div>
<!-- col3, col4, etc, etc... -->
</div>
</div>
</div>
Try this:
$('div[class^=col] > ul > li > a').each(function() {
doSomething( $(this) );
});
Related
I have a list-menu .sidebar-menu and each li of this list has its own id. There is also a .services-info block, where blocks are located, one of which should appear when you click on one of the items in the .sidebar-menu that corresponds to this block. On the blocks in .services-info, I hung the .invisible class, which hides them and there is a .visible class with the display: block property.
Question: How to make it so that when you click on one of the .sidebar-menu items, the corresponding block appears and the unnecessary one disappears? For example, I clicked on the "Business card site" item and in .services-info (circled in red in the picture) the corresponding block appears (with the .business-card class) and the previous block disappears, or I clicked on the "Online store" item and it appears also the corresponding block (with class .market). and unnecessary disappears.
Site ct03638.tmweb.ru
Code jsfiddle.net/qhfs7jmb/
.invisible{
display: none;
}
.visible {
display: block;
}
<section class="services" id="services">
<div class="services-info-bg"></div>
<div class="wrapper">
<div class="content">
<div class="sidebar">
<h3>Наши услуги</h3>
<ul class="sidebar-menu">
<li id="business-card">Сайт-визитка</li>
<li id="landing">Landing page</li>
<li id="market">Интернет-магазин</li>
<li id="corp">Корпоративный сайт</li>
<li id="bitrix">1C Битрикс</li>
<li id="advertising">Контекстная реклама</li>
<li id="seo">SEO оптимизация</li>
<li id="promotion">Продвижение в соц. сетях</li>
<li id="marketing">Контент-маркетинг</li>
</ul>
<ul class="sidebar-nav">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
<div class="services-info">
<div class="content">
<div class="business-card invisible">Сайт-визитка</div>
<div class="landin invisible">Landing page</div>
<div class="market">
<div class="services-info-title">
Созданные экспертами «Inter-web» сайты интернет-магазинов имеют функциональность, необходимую для успешной онлайн-торговли.
</div>
<p>Что входит в нашу работу:</p>
<div class="services-info-block">
<ul>
<li>+ Подготовка технического задания</li>
<li>+ Разработка прототипа</li>
<li>+ Верстка макета</li>
<li>+ Интеграция дизайна</li>
</ul>
<ul>
<li>+ Написание уникальных текстов</li>
<li>+ Сбор семантики</li>
<li>+ Тестирование и запуск</li>
<li>+ Подключение веб-аналитики</li>
</ul>
</div>
<div class="services-info-footer">
<a class="order" href="#">Сделать заказ</a>
Узнать подробнее →
</div>
</div>
</div>
</div>
</div>
</div>
</section>
Add an event listener to the sidebar <ul> to listen for clicks on the sidebar elements.
When the user clicks on a sidebar element the event listener looks for the ID of the clicked element and uses that to construct a query selector to select the required content <div>.
Then add the invisible class and remove the 'visible' class on all the content <div>, and finally set the 'visible' class on the required content <div>
You could just search for the visible content block and change that, but past experience has taught me to hide everything I don't want, regardless.
The code you need shoud be enclosed within <script> tags and added to the foot of your page.
document.querySelector('ul.sidebar-menu').addEventListener('click',function(e){
e.preventDefault();
// The <a> element was clicked, but we need the ID from the enclosing <li> element
let clickedId = e.target.closest('li').id;
// Set all the content elements to invisible (saves trying to find the visible one)
let contentDivs = document.querySelectorAll('div.services-info>div.content>div');
contentDivs.forEach((el)=>{el.classList.remove('visible'); el.classList.add('invisible')});
// Now, using the ID from the <li>, create a query selector to find the content <div>
let targetSelector = 'div.services-info>div.content>div.'+clickedId;
// Set that element visible
document.querySelector(targetSelector).classList.add('visible');
});
.invisible{
display: none;
}
.visible {
display: block;
}
<section class="services" id="services">
<div class="services-info-bg"></div>
<div class="wrapper">
<div class="content">
<div class="sidebar">
<h3>Наши услуги</h3>
<ul class="sidebar-menu">
<li id="business-card">Сайт-визитка</li>
<li id="landing">Landing page</li>
<li id="market">Интернет-магазин</li>
<li id="corp">Корпоративный сайт</li>
<li id="bitrix">1C Битрикс</li>
<li id="advertising">Контекстная реклама</li>
<li id="seo">SEO оптимизация</li>
<li id="promotion">Продвижение в соц. сетях</li>
<li id="marketing">Контент-маркетинг</li>
</ul>
<ul class="sidebar-nav">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
<div class="services-info">
<div class="content">
<div class="business-card invisible">Сайт-визитка</div>
<div class="landing invisible">Landing page</div>
<div class="market">
<div class="services-info-title">
Созданные экспертами «Inter-web» сайты интернет-магазинов имеют функциональность, необходимую для успешной онлайн-торговли.
</div>
<p>Что входит в нашу работу:</p>
<div class="services-info-block">
<ul>
<li>+ Подготовка технического задания</li>
<li>+ Разработка прототипа</li>
<li>+ Верстка макета</li>
<li>+ Интеграция дизайна</li>
</ul>
<ul>
<li>+ Написание уникальных текстов</li>
<li>+ Сбор семантики</li>
<li>+ Тестирование и запуск</li>
<li>+ Подключение веб-аналитики</li>
</ul>
</div>
<div class="services-info-footer">
<a class="order" href="#">Сделать заказ</a>
Узнать подробнее →
</div>
</div>
</div>
</div>
</div>
</div>
</section>
One method is to set an attribute with selected menu item id on body element and in CSS show the element with the same class name.
The section that you want to show when clicked menu item must have the same class name as the id of <li> item:
const menu = document.querySelectorAll(".sidebar-menu li > a"),
onClick = e =>
{
e.preventDefault();
//get ID from <li> element and add to the body "show" attribute
document.body.setAttribute("show", e.target.parentNode.id);
};
for(let i = 0; i < menu.length; i++)
menu[i].addEventListener("click", onClick);
.services-info .content > div
{
display: none;
}
body[show="business-card"] .business-card,
body[show="landing"] .landing,
body[show="market"] .market,
body[show="corp"] .corp,
body[show="bitrix"] .bitrix,
body[show="advertising"] .advertising,
body[show="seo"] .seo,
body[show="promotion"] .promotion,
body[show="marketing"] .marketing
{
display: block;
}
<section class="services" id="services">
<div class="services-info-bg"></div>
<div class="wrapper">
<div class="content">
<div class="sidebar">
<h3>Наши услуги</h3>
<ul class="sidebar-menu">
<li id="business-card">Сайт-визитка</li>
<li id="landing">Landing page</li>
<li id="market">Интернет-магазин</li>
<li id="corp">Корпоративный сайт</li>
<li id="bitrix">1C Битрикс</li>
<li id="advertising">Контекстная реклама</li>
<li id="seo">SEO оптимизация</li>
<li id="promotion">Продвижение в соц. сетях</li>
<li id="marketing">Контент-маркетинг</li>
</ul>
<ul class="sidebar-nav">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
<div class="services-info">
<div class="content">
<div class="business-card invisible">Сайт-визитка</div>
<div class="landing invisible">Landing page</div>
<div class="market">
<div class="services-info-title">
Созданные экспертами «Inter-web» сайты интернет-магазинов имеют функциональность, необходимую для успешной онлайн-торговли.
</div>
<p>Что входит в нашу работу:</p>
<div class="services-info-block">
<ul>
<li>+ Подготовка технического задания</li>
<li>+ Разработка прототипа</li>
<li>+ Верстка макета</li>
<li>+ Интеграция дизайна</li>
</ul>
<ul>
<li>+ Написание уникальных текстов</li>
<li>+ Сбор семантики</li>
<li>+ Тестирование и запуск</li>
<li>+ Подключение веб-аналитики</li>
</ul>
</div>
<div class="services-info-footer">
<a class="order" href="#">Сделать заказ</a>
Узнать подробнее →
</div>
</div>
</div>
</div>
</div>
</div>
</section>
How to remove link from parent menu anchor if it has submenus
<ul class="sitemap-ul">
<li> Home</li>
<li> about Us <!-- Remove link-->
<ul>
<li>mission</li>
<li>vission</li>
</ul>
</li>
<li> Media <!-- Remove link-->
<ul>
<li>news</li>
</ul>
</li>
<li> Contact</li>
</ul>
You can use jQuery :has() pseudo-class selector.
$('.sitemap-ul > li:has(ul) > a').remove()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="sitemap-ul">
<li> Home</li>
<li> about Us <!-- Remove link-->
<ul>
<li>mission</li>
<li>vission</li>
</ul>
</li>
<li> Media <!-- Remove link-->
<ul>
<li>news</li>
</ul>
</li>
<li> Contact</li>
</ul>
UPDATE : In case you just want to replace a tag with text then use contents() method with unwrap() method.
$('.sitemap-ul > li:has(ul) > a')
// get children element
.contents()
// unwrap them
.unwrap()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="sitemap-ul">
<li> Home</li>
<li> about Us
<!-- Remove link-->
<ul>
<li>mission</li>
<li>vission</li>
</ul>
</li>
<li> Media
<!-- Remove link-->
<ul>
<li>news</li>
</ul>
</li>
<li> Contact</li>
</ul>
Assuming you want to remove the <a> elements themselves but leave behind their text content you can use :has() to get the relevant li with submenus, then replaceWith() on the child a elements, like this:
$('.sitemap-ul > li:has(ul) > a').replaceWith(function() {
return $(this).text();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="sitemap-ul">
<li>Home</li>
<li>
About Us
<ul>
<li>mission</li>
<li>vission</li>
</ul>
</li>
<li>
Media
<ul>
<li>news</li>
</ul>
</li>
<li>Contact</li>
</ul>
$('.sitemap-ul > li').each(function(){
if($('ul', this).length > 0){
$(this).closest("a").click(function(e){
e.preventDefault();
});
}
});
I have a solution by using vanilla js for you.
var elements = document.querySelectorAll(".sitemap-ul li")
Array.from(elements).forEach(function(el) {
if (el.children.length > 1) {
el.removeChild(el.children[0])
}
});
I have a set of li elements and I want to give all li elements below the ul container an extra class based on the .login class. The login element isn't a parent element but in the same container. Would this be possible with jQuery or vanilla js?
<ul class="submenu" id="sub0">
<li class="menugroup dcjq-parent-li">
<ul class="rightmenu login">
<li></li>
<li></li>
</ul>
</li>
<li></li> <-----new class
<li></li> <-----new class
<li></li> <-----new class
<li></li> <-----new class
<li></li> <-----new class
<li></li> <-----new class
</ul>
You can use the following code:
$("ul.login")
.parents("li")//get ancestor li element
.nextAll()//get all next li elements
.addClass("active");//add desire class
.active {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="submenu" id="sub0">
<li class="menugroup dcjq-parent-li">
<ul class="rightmenu login">
<li>
</li>
<li>
</li>
</ul>
</li>
<li>
</li>
<li>
</li>
<li>
</li>
<li>
</li>
<li>
</li>
<li>
</li>
</ul>
References
.nextAll()
.addClass()
.parents()
I'm new to jQuery and I've hit a bit of a snag.
Here is my HTML:
<div id="mainpage-tabs-area">
<ul class="nav cf">
<li class="tb-one">BTN1</li>
<li class="tb-two">BTN2</li>
<li class="tb-three">BTN3</li>
<li class="tb-four">BTN4</li>
</ul>
<div class="list-wrap">
<ul id="description">
<li>Hello, I am a description</li>
</ul>
<ul id="tabtwo" class="hide">
<li></li>
</ul>
<ul id="tabthree" class="hide">
<li></li>
</ul>
<ul id="tabfour" class="hide">
<li></li>
</ul>
</div> <!-- END List Wrap -->
</div> <!-- END Organic Tabs -->
And here is my current jQuery:
$(document).ready(function () {
var tabContent = $('ul.list-wrap').find('li').text();
if ($.trim(tabContent) === "") {
$('ul.nav li').hide();
}
});
What I want to be able to do is just the jQuery to check every li in .list-wrap and if that li is empty then remove the corresponding li in .nav as this is for a tab system where if no content is entered, they don't want it displaying.
Any suggestions for a newbie?
Nick
I'd iterate through the list items, check the length of each node's text, and hide the corresponding tab with:
$('.list-wrap li').each(function(i){
if(!$(this).text().length) $('#mainpage-tabs-area li').eq(i).hide();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="mainpage-tabs-area">
<ul class="nav cf">
<li class="tb-one">BTN1
</li>
<li class="tb-two">BTN2
</li>
<li class="tb-three">BTN3
</li>
<li class="tb-four">BTN4
</li>
</ul>
<div class="list-wrap">
<ul id="description">
<li>Hello, I am a description</li>
</ul>
<ul id="tabtwo" class="hide">
<li></li>
</ul>
<ul id="tabthree" class="hide">
<li></li>
</ul>
<ul id="tabfour" class="hide">
<li></li>
</ul>
</div>
<!-- END List Wrap -->
</div>
<!-- END Organic Tabs -->
The i in the each() function is the index of the element that the loop is on, and that allows you to target the corresponding tab element and hide it.
This should do the job:
$('.list-wrap ul li').each(function(){
var cnt = $('.list-wrap ul li').index( $(this) );
var txt = $(this).text();
if ($.trim(txt)==''){
$('.nav li').eq(cnt).hide();
}
});
jsFiddle Demo
I would suggest this If you are not making infinite lists
$('.tb-two').hide(); //if tabtwo is empty
$('.tb-hree').hide(); //if tabthree is empty
and so on...
<ul>
<li>
<ul></ul>
</li>
<li></li>
<li></li>
<li></li>
<li>
<ul></ul>
</li>
</ul>
How do I add class="parent" only for li, which has ul inside it?
You can use :has() in your selector, like this:
$("li:has(ul)").addClass("parent")