I'm sorry, I speak a little English.
My HTML:
<div class="widgetcontent">
<ul>
<li class="cat-item cat-item-526">
A test
</li>
<li class="cat-item cat-item-527">
B test
<ul class='children'>
<li class="cat-item cat-item-528">
Test B1
</li>
<li class="cat-item cat-item-529">
Test B2
</li>
</ul>
</li>
</ul>
</div>
I would like:
If there is ul.children, modify with JavaScript and add the div.dropdown:
<li class="cat-item cat-item-527">
B test
<div class="dropdown" onclick="myFunction('cat-item-527')">â–¾</div><!-- ADD -->
<ul class='children'>
<li class="cat-item cat-item-528">
Test B1
</li>
<li class="cat-item cat-item-529">
Test B2
</li>
</ul>
</li>
How to? Without jQuery or another JS framework. Native JS please.
Thank you very much.
You can do this by finding all li elements and then determining if there is a ul inside it. If so just add an element using insertBefore
In this example I have coloured the element red just to indicate its added in the correct place.
[...document.querySelectorAll("ul li.cat-item")].forEach(li => {
const ul = li.querySelector("ul.children");
if(ul){
const div = document.createElement("div");
div.classList.add("dropdown");
div.addEventListener("click",() => console.log("Clicked new div", li.className))
li.insertBefore(div,ul)
}
});
.dropdown{
height:10px;
background-color:red
}
<div class="widgetcontent">
<ul>
<li class="cat-item cat-item-526">
A test
</li>
<li class="cat-item cat-item-527">
B test
<ul class='children'>
<li class="cat-item cat-item-528">
Test B1
</li>
<li class="cat-item cat-item-529">
Test B2
</li>
</ul>
</li>
</ul>
</div>
Related
I have a menu populating from MySQL table and PHP up to some nested sub levels.
my menu like this:
A
B
C
If click on A first time it is showing all the child elements and again I click child elements of A it displaying child elements also fine.
But the problem is when I click on the B after open all the levels items of A it shows B sub elements fine. But again if I click A it showing all the elements except child child elements also.
I used jQuery for this.
So I want to bring back to the original state? ( only expand the top child elements, not the sub child elements ),
how to do that?
//this is my jquery code for elements clickable in menu.
$(document).ready(function() {
$(".lichild").parent().hide();
$(".limain").click(function() {
$(this).children('ul').show();
$(this).siblings(".limain").children('ul').hide();
});
$(".lichild").click(function() {
$(this).children('ul').show();
$(this).siblings().children('ul').hide()
});
});
<!-- This is the html I am generating using a PHP function -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="limain">A
<ul>
<li class="lichild">A1
<ul>
<li class="lichild">a2</li>
<li class="lichild">a1
<ul>
<li class="lichild">aaaaaa</li>
<li class="lichild">abbbbbb</li>
</ul>
</li>
</ul>
</li>
<li class="lichild">A2</li>
<li class="lichild">A3</li>
<li class="lichild">A4</li>
<li class="lichild">A5</li>
</ul>
<li class="limain">B
<ul>
<li class="lichild">B1</li>
<li class="lichild">B2</li>
</ul>
</li>
<li class="limain">C
<ul>
<li class="lichild">C1</li>
<li class="lichild">C2</li>
<li class="lichild">C3</li>
<li class="lichild">A6
<ul>
<li class="lichild">A8
<ul>
<li class="lichild">A10
<ul>
<li class="lichild">A13
</li>
<li class="lichild">A14
</li>
</ul>
</li>
<li class="lichild">A11
</li>
</ul>
</li>
<li class="lichild">A9
</li>
</ul>
</li>
<li class="lichild">A7
</li>
</ul>
</li>
<li class="limain">D
<ul>
<li class="lichild">D1</li>
<li class="lichild">D2
</li>
</ul>
</li>
</ul>
Use find inside siblings and hide it.
$(".lichild").parent().hide();
$(".limain").click(function() {
$(this).children('ul').show();
$(this).siblings(".limain").find('ul').hide(); // Change in this line
});
$(".lichild").click(function() {
$(this).children('ul').show();
$(this).siblings().children('ul').hide()
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<ul>
<li class="limain">
A
<ul>
<li class="lichild">
A1
<ul>
<li class="lichild">a2</li>
<li class="lichild">
a1
<ul>
<li class="lichild">aaaaaa</li <li class="lichild">abbbbbb</li>
</ul>
</li>
</ul>
</li>
<li class="lichild">A2</li>
<li class="lichild">A3</li>
<li class="lichild">A4</li>
<li class="lichild">A5</li>
</ul>
<li class="limain">
B
<ul>
<li class="lichild">B1</li>
<li class="lichild">B2</li>
</ul>
</li>
<li class="limain">
C
<ul>
<li class="lichild">C1</li>
<li class="lichild">C2</li>
<li class="lichild">C3</li>
<li class="lichild">
A6
<ul>
<li class="lichild">
A8
<ul>
<li class="lichild">
A10
<ul>
<li class="lichild">A13
</li>
<li class="lichild">A14
</li>
</ul>
</li>
<li class="lichild">A11
</li>
</ul>
</li>
<li class="lichild">A9
</li>
</ul>
</li>
<li class="lichild">A7
</li>
</ul>
</li>
<li class="limain">
D
<ul>
<li class="lichild">D1</li>
<li class="lichild">D2
</li>
</ul>
</li>
</ul>
$(document).ready(function () {
$(".lichild").parent().hide();
$(".limain").click(function () {
$(this).children('ul').show();
$(this).siblings().find('ul').hide();
});
$(".lichild").click(function () {
$(this).children('ul').show();
$(this).siblings('li').find('ul').hide()
});
});
I've this code
$('.item_has_children a').first().css("color","red");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<ul>
<li class="item_has_children">
Category 1
<ul class="submenu">
<li class="menu_item">
Hello
</li>
<li class="menu_item">
Hello
</li>
</ul>
</li>
<li class="item_has_children">
Category 2
<ul class="submenu">
<li class="menu_item">
Hello
</li>
<li class="menu_item">
Hello
</li>
</ul>
</li>
</ul>
I want to color the first links : "category 1" and "category 2".
I try but only the first link is coloring red.
Thanks for your help !
You can use immediate child selector > to target immediate anchor elements both using CSS and jquery.
Using CSS:
.item_has_children > a{color:red;}
Working Demo using CSS:
.item_has_children>a {
color: red
}
<ul>
<li class="item_has_children">
Category 1
<ul class="submenu">
<li class="menu_item">
Hello
</li>
<li class="menu_item">
Hello
</li>
</ul>
</li>
<li class="item_has_children">
Category 2
<ul class="submenu">
<li class="menu_item">
Hello
</li>
<li class="menu_item">
Hello
</li>
</ul>
</li>
</ul>
Using Jquery:
$('.item_has_children > a').css("color","red");
Working Demo using Jquery:
$('.item_has_children > a').css("color","red")
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="item_has_children">
Category 1
<ul class="submenu">
<li class="menu_item">
Hello
</li>
<li class="menu_item">
Hello
</li>
</ul>
</li>
<li class="item_has_children">
Category 2
<ul class="submenu">
<li class="menu_item">
Hello
</li>
<li class="menu_item">
Hello
</li>
</ul>
</li>
</ul>
No need to use javascript for this, you can use CSS.(Better Performance and User Experience)
.item_has_children > a {
color: red;
}
> here will select direct children of .item_has_children element.
Demo:
.item_has_children>a {
color: red;
}
<ul>
<li class="item_has_children"> Category 1
<ul class="submenu">
<li class="menu_item"> Hello
</li>
<li class="menu_item"> Hello
</li>
</ul>
</li>
<li class="item_has_children"> Category 2
<ul class="submenu">
<li class="menu_item"> Hello
</li>
<li class="menu_item"> Hello
</li>
</ul>
</li>
</ul>
operator > is used for select immediate started DOM element of selector.
$("li.item_has_children > a").css("color","red");
I am trying to write a function that will combine two children ul#level_2and append them to their parent li#level_1 within a dropdown #navigation.
I currently have the following which does the job, but it means I have to manually target each category. I'm sure there is a far shorter way to produce the same results with very little code.
$('li#furniture ul.level_2').children('li').appendTo('li#furniture ul.level_2:first');
$('li#furniture ul.level_2').children('li').not(':first').remove();
Here is a shortened version of my current html structure & below is the desired result:
Simple Current HTML
<div id="navigation">
<ul id="level_1">
<li class="level_1">
<div class="subnav_wrapper">
<ul class="level_2">
<li class="level_2">
Link A
</li>
</ul>
<ul class="level_2">
<li class="level_2">
Link B
</li>
</ul>
</div>
</li>
</ul>
</div>
Desire HTML
<div id="navigation">
<ul id="level_1">
<li class="level_1">
<ul class="level_2">
<li class="level_2">
Link A
</li>
<li class="level_2">
Link B
</li>
</ul>
</li>
</ul>
</div>
Full Detailed HTML
<div id="navigation">
<ul id="level_1">
<li class="level_1 furniture">
Furniture
<div class="subnav_wrapper">
<ul class="level_2">
<li class="level_2 sofa">
Sofa
</li>
</ul>
<ul class="level_2">
<li class="level_2 bed">
Bed
</li>
</ul>
</div>
</li>
<li class="level_1 bathroom">
Bathroom
<div class="subnav_wrapper">
<ul class="level_2">
<li class="level_2 shower">
<a href="#">Shower/a>
</li>
</ul>
<ul class="level_2">
<li class="level_2 bath">
Bath
</li>
</ul>
</div>
</li>
</ul>
</div>
This should do what you need.
var wrapper = $(".subnav_wrapper").contents();
$(".subnav_wrapper").replaceWith(wrapper );
$('ul.level_2').children('li').appendTo('ul.level_2:first');
$('ul.level_2').not(':first').remove();
JSFIDDLE DEMO
I would like to add that class "last-item" every last li.
Im trying this but without sucess:
<script>
$(".cbp-tm-submenu .product-categories li .children li:last-child").addClass("last-item");
<script>
I tried put on header and on footer.
HTML:
<ul class="cbp-tm-submenu">
<img class="backgroundtooltiptop" alt="background tooltip" src="http://localhost:8888/era420/wp-content/themes/era420/images/tooltipbackgroundtop.png">
<li id="woocommerce_product_categories-4" class="widget woocommerce widget_product_categories">
<ul class="product-categories">
<li class="cat-item cat-item-16 current-cat cat-parent">
Lançamentos
<ul class="children">
<li class="cat-item cat-item-17">
teste
</li>
<li class="cat-item cat-item-18">...</li>
<li class="cat-item cat-item-19">...</li>
</ul>
</li>
</ul>
</li>
<img class="backgroundtooltipbot" alt="background tooltip bot" src="http://localhost:8888/era420/wp-content/themes/era420/images/tooltipbackgroundbot.png">
</ul>
This is enough:
$(".cbp-tm-submenu li:last-child").addClass("last-item");
i have menuin wordpress like this :-
<div id="my_custom_class">
<ul class="my_custom_class">
<li class="page_item">page_item
<ul class='children'>
<li class="page_item child">children</li>
</ul>
</li>
<li class="current_page_item">current_page</li>
<li class="current_page_item">current_page</li>
<li class="current_page_item">current_page</li>
</ul>
</div>
this menu will be create wheni use this :-
<? wp_nav_menu('menu=header'); ?>
so i need when any li have child, add <span></span> tag befor tag like this
<div id="my_custom_class">
<ul class="my_custom_class">
<li class="page_item"><span></span>page_item
<ul class='sub-menu'>
<li class="page_item child">children</li>
</ul>
</li>
<li class="current_page_item">current_page</li>
<li class="current_page_item">current_page</li>
<li class="current_page_item">current_page</li>
</ul>
</div>
how can i do that. by jquery
Use .prepend()
$('ul.my_custom_class li a').closest('li').prepend('<span></span>');
Live DEMO
Live DEMO
$('ul.my_custom_class li:has(ul)').prepend('<span></span>');
By jQuery? Ok:
$('<span></span>').prependTo('ul.my_custom_class li:has(ul)');
See http://api.jquery.com/prependTo/
If you aren't willing to dig in to wordpress' functionality, you can inject the <span> elements with regex:
(<li.*class="[^\"]*page_item[^\"]*"[^>]*>)(<a.*</a>[^<]+<ul)
Result:
<div id="my_custom_class">
<ul class="my_custom_class">
<li class="page_item"><span></span>page_item
<ul class='children'>
<li class="page_item child">children</li>
</ul>
</li>
<li class="current_page_item">current_page</li>
<li class="current_page_item">current_page</li>
<li class="current_page_item">current_page</li>
</ul>
</div>
$1 = <li class="page_item">
$2 = page_item<ul
And so you just preg_replace with \1<span></span>\2 (you will need to add a backslash to the </a>)
Example on php fiddle (assuming I generated the link correctly lol)