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...
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'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) );
});
Trying to delete specific Node of HTML.
First HTML:
There many List in .widget-content want to delete all .list without First Li. Means keep first-child.
<div class="wrapper delete">
<div class="widget-content">
<ul>
<li class="lists">
Content
</li>
<li class="lists"> <!-- Delete this-->
Content
</li>
<li class="lists"> <!-- Delete this-->
Content
</li>
</ul>
</div>
</div>
Second HTML:
Want to delete ul of .widget-content ul if .wrapper has class delete. Condition need.
<div class="wrapper delete">
<div class="widget-content">
<ul> <!-- Delete This -->
<li class="lists">
Content
</li>
<li class="lists">
Content
</li>
<li class="lists">
Content
</li>
</ul>
</div>
</div>
How to do this by JS/jquery? Fiddle example would be helpful.
$(document).ready(function () {
$('.widget-content li').not(':first-child').remove();
if ($(".wrapper").hasClass('delete')) {
$('.widget-content ul').remove();
}
});
slice can be used to select elements with a start and end.
$('.widget-content li.lists').slice(1).remove();
$('.wrapper.delete ul').remove();
I am using jQuery for multiple toggling menus on my site. However, if I change it's initial loading from .show to .hide it will not work.
My js file is:
jQuery(document).ready(function($) {
$('div ul.menu').hide();
$('h2.trigger').click(function() {
$(this).toggleClass("active").next().slideToggle('slow');
return false;
});
});
And my html for my multiple menus is like so:
<aside class="widget">
<h2 class="trigger">Portfolio</h2>
<div>
<ul class="menu">
<li></li>
</ul>
</aside>
<aside class="widget">
<h2 class="trigger">Portfolio</h2>
<div>
<ul class="menu">
<li></li>
</ul>
</aside>
<aside class="widget">
<h2 class="trigger">Portfolio</h2>
<div>
<ul class="menu">
<li></li>
</ul>
</aside>
Any ideas why this will not work?
Simply get rid of your extra div tag. Your next() is picking that instead of the ul.menu you are trying to target. Like so:
<aside class="widget">
<h2 class="trigger">Portfolio</h2>
<ul class="menu">
<li>Test</li>
</ul>
</aside>
<aside class="widget">
<h2 class="trigger">Portfolio</h2>
<ul class="menu">
<li>Test</li>
</ul>
</aside>
<aside class="widget">
<h2 class="trigger">Portfolio</h2>
<ul class="menu">
<li>Test</li>
</ul>
</aside>
You will also need to modify the following line
$('div ul.menu').hide();
to leave out the div
$('ul.menu').hide();
Note: the reason that this appears to work with .show() is that your div is shown by default so the fact that the .show() is being called on the wrong item goes unnoticed.