jQuery ul li trees - slideToggle only li with ul child - html

I know there are a lot of similar solutions.. This one almost works :)
I have an unsorted list:
<ul id="Tree" class="sub-menu">
<li class="folder">First level
<ul class="sub-menu">
<li>File 1.1</li>
<li class="folder">Second level
<ul class="sub-menu">
<li>File 2.1</li>
<li>File 2.2</li>
<li class="folder">Tretji nivo
<ul class="sub-menu">
<li>File 3.1</li>
<li>File 3.2</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
And the jQuery:
$('.folder').click(function(event) {
event.stopPropagation();
$(this).find('>.sub-menu').slideToggle();
});
Click on .folder works as desired. The problem is that the slideToggle is triggered on all li elements. So if I click on a li > a element the file is downloaded but the ul is toggled also. I want to prevent toggle when I click on an element that has no direct ul child.

You could add the folder class to the level text instead of the whole li tag :
$('.folder').click(function(event) {
event.stopPropagation();
$(this).next('.sub-menu').slideToggle();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="Tree" class="sub-menu">
<li><span class="folder">First level</span>
<ul class="sub-menu">
<li>File 1.1</li>
<li><span class="folder">Second level</span>
<ul class="sub-menu">
<li>File 2.1</li>
<li>File 2.2</li>
<li><span class="folder">Tretji nivo</span>
<ul class="sub-menu">
<li>File 3.1</li>
<li>File 3.2</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>

Related

Nested nav toggle closing parent

I have a simple nav structure for a nav that has toggles to open and close sub-menus. However, when I click on a nested menu the toggle works, but also closes the parent sub-menu. How can I set it so that the parent doesn't close on the click of the nested menu?
jQuery(document).ready(function($) {
//Toggle sub-menus
$('#menu .has-children').on('click', function(event) {
event.preventDefault();
$(this).children('.sub-menu').slideToggle(500);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="menu">
<li>item 1</li>
<li class="has-children">item 2
<ul class="sub-menu">
<li>sub-item 1</li>
</ul>
</li>
<li class="has-children">item 3
<ul class="sub-menu">
<li>sub-item 1</li>
<li class="has-children">sub-item 2
<ul class="sub-menu">
<li>sub-sub-item 1</li>
</ul>
</li>
</ul>
</li>
</ul>
event.preventDefault(); doesn't stop the event from traveling up the tree, you need to use event.stopPropagation(); to stop the click from also triggering the click event listeners on parent elements.
(You could also add this to li inside sub menus without .has-children, to prevent them from closing parent menus, though that's unnecessary if those nav items link to other pages)
jQuery(document).ready(function($) {
//Toggle sub-menus
$('#menu .has-children').on('click', function(event) {
event.preventDefault();
event.stopPropagation();
$(this).children('.sub-menu').slideToggle(500);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="menu">
<li>item 1</li>
<li class="has-children">item 2
<ul class="sub-menu">
<li>sub-item 1</li>
</ul>
</li>
<li class="has-children">item 3
<ul class="sub-menu">
<li>sub-item 1</li>
<li class="has-children">sub-item 2
<ul class="sub-menu">
<li>sub-sub-item 1</li>
</ul>
</li>
</ul>
</li>
</ul>

add space between ul and li tag css inline

I've the following code with nested list items as shown below:
<ul style={{padding-top: '15px'}}>
<li style={{margin-left: '20px'}}>First Services</li>
<ul style={{margin-left: '30px'}}>
<li>get1</li>
</ul>
<ul style={{margin-left: '30px'}}>
<li>get2</li>
</ul>
<ul style={{margin-left: '30px'}}>
<li>get3</li>
</ul>
<ul style={{margin-left: '30px'}}>
<li>get4</li>
</ul>
<ul style={{margin-left: '30px'}}>
<li>get5</li>
</ul>
<li style={{margin-left: '20px'}}>Second Services</li>
<ul style={{margin-left: '30px'}}>
<li>get6</li>
</ul>
<ul style={{margin-left: '30px'}}>
<li>get7</li>
</ul>
<ul style={{margin-left: '30px'}}>
<li>get8</li>
</ul>
<ul style={{margin-left: '30px'}}>
<li>get9</li>
</ul>
<ul style={{margin-left: '30px'}}>
<li>get10</li>
</ul>
<ul style={{margin-left: '30px'}}>
<li>get11</li>
</ul>
<ul style={{margin-left: '30px'}}>
<li>get12</li>
</ul>
<ul style={{margin-left: '30px'}}>
<li>get13 </li>
</ul>
<li style={{margin-left: '20px'}}>Workflows</li>
<ul style={{margin-left: '30px'}}>
<li>Workflow for someone </li>
</ul>
</ul>
My Goal:
I want some space between the following:
1) First Services and get1
2) get5 and Second Services
3) Second Services and get6
4) get13 and Workflows
5)Workflows and Workflow for someone
How should I go about it? Is adding an empty paragraph tag <p></p> a good idea between each of the above 5 things?
if you mean horizontal space (white space), use: &nbsp ;
if you mean vertical space, try: (CSS property) line-height, padding
or margin.
you might want to remove this from being inline and use your linked stylesheet instead as it might cause issues with your styling.
You should use classes for this. Right now, the simplest way is to wrap a div around your whole list, apply a class to it (in my example I used parent_class) and use this selector: div.parent_class > ul >li It only selects the li elements of the first level ul:
div.parent_class > ul >li {
margin-top: 10px;
margin-bottom: 10px;
}
<div class="parent_class">
<ul style="padding-top:15px;">
<li style="margin-left:20px">First Services</li>
<ul style="margin-left:30px">
<li>get1</li>
</ul>
<ul style="margin-left:30px">
<li>get2</li>
</ul>
<ul style="margin-left:30px">
<li>get3</li>
</ul>
<ul style="margin-left:30px">
<li>get4</li>
</ul>
<ul style="margin-left:30px">
<li>get5</li>
</ul>
<li style="margin-left:20px">Second Services</li>
<ul style="margin-left:30px">
<li>get6</li>
</ul>
<ul style="margin-left:30px">
<li>get7</li>
</ul>
<ul style="margin-left:30px">
<li>get8</li>
</ul>
<ul style="margin-left:30px">
<li>get9</li>
</ul>
<ul style="margin-left:30px">
<li>get10</li>
</ul>
<ul style="margin-left:30px">
<li>get11</li>
</ul>
<ul style="margin-left:30px">
<li>get12</li>
</ul>
<ul style="margin-left:30px">
<li>get13 </li>
</ul>
<li style="margin-left:20px">Workflows</li>
<ul style="margin-left:30px">
<li>Workflow for someone </li>
</ul>
</ul>
</div>
.example-list {
margin:0px;
}
.example-list > li {
margin: 30px 0px;
}
<ul class="example-list">
<li>First Services</li>
<ul>
<li>get1</li>
</ul>
<ul style={{margin-left: '30px'}}>
<li>get2</li>
</ul>
<ul style={{margin-left: '30px'}}>
<li>get3</li>
</ul>
<ul>
<li>get4</li>
</ul>
<ul>
<li>get5</li>
</ul>
<li style={{margin-left: '20px'}}>Second Services</li>
<ul>
<li>get6</li>
</ul>
<ul>
<li>get7</li>
</ul>
<ul>
<li>get8</li>
</ul>
<ul>
<li>get9</li>
</ul>
<ul>
<li>get10</li>
</ul>
<ul>
<li>get11</li>
</ul>
<ul>
<li>get12</li>
</ul>
<ul>
<li>get13 </li>
</ul>
<li style={{margin-left: '20px'}}>Workflows</li>
<ul>
<li>Workflow for someone </li>
</ul>
</ul>
I would do the following (or something similar - keep in mind it's not good practice to have <ul> as a child of another <ul> - you can validate here: http://validator.w3.org/). Remove the inline styles, you'll deal with A LOT of headaches later if you write you CSS as you have. Set classnames for the bits you want extra space for (you can edit the {{20px}} below for how much space you want (or if you want left/right margins, you can edit the whole rule).
<style>
.title {
margin-left: 20px;
}
.top-list {
padding-top: 15px;
}
.top-list .spacer-top {
margin-top: {{20px}};
}
.top-list > li > ul {
margin-left: 30px;
}
</style>
<ul class="top-list">
<li class="title">First Services</li>
<li class="spacer-top">
<ul>
<li>get1</li>
</ul>
</li>
<li>
<ul>
<li>get2</li>
</ul>
</li>
<li>
<ul>
<li>get3</li>
</ul>
</li>
<li>
<ul>
<li>get4</li>
</ul>
</li>
<li>
<ul>
<li>get5</li>
</ul>
</li>
<li class="title" class="spacer-top">Second Services</li>
<li class="spacer-top">
<ul>
<li>get6</li>
</ul>
</li>
<li>
<ul>
<li>get7</li>
</ul>
</li>
<li>
<ul>
<li>get8</li>
</ul>
</li>
<li>
<ul>
<li>get9</li>
</ul>
</li>
<li>
<ul>
<li>get10</li>
</ul>
</li>
<li>
<ul>
<li>get11</li>
</ul>
</li>
<li>
<ul>
<li>get12</li>
</ul>
</li>
<li>
<ul>
<li>get13 </li>
</ul>
</li>
<li class="title spacer-top">Workflows</li>
<li class="spacer-top">
<ul>
<li>Workflow for someone </li>
</ul>
</li>
</ul>

Stop event.preventDefault being applied to all links

I have a CSS menu hover that isn't working on iPad. Looking around I found this answer on Stack Overflow. To trigger the hover I have set up an event.preventDefault on the top level links which is working great. However this being applied to all links under the menu which means you cant navigate around the website.
I have created a jsFiddle.
How can I make it so that anything with a class .menu-item-has-children the event is prevented but for any other <a></a> under that class is works.
Unfortunately/annoyingly its not possible to edit the HTML markup
Here is my code:
HTML
<nav id="top-menu">
<ul>
<li class="menu-item-has-children"><a>Link 1</a>
<ul>
<li>Google</li>
<li class="menu-item-has-children">Google
<ul>
<li>Google 1</li>
<li>Google 1</li>
<li>Google 1</li>
<li>Google 1</li>
</ul>
</li>
<li>Google</li>
<li>Google</li>
</ul>
</li>
<li class="menu-item-has-children"><a>Link 2</a>
<ul>
<li>Google</li>
<li>Google</li>
<li>Google</li>
<li>Google</li>
</ul>
</li>
<li class="menu-item-has-children"><a>Link 3</a>
<ul>
<li>Google</li>
<li>Google</li>
<li>Google</li>
<li>Google</li>
</ul>
</li>
<li class="menu-item-has-children"><a>Link 4</a>
<ul>
<li>Google</li>
<li>Google</li>
<li>Google</li>
<li>Google</li>
</ul>
</li>
</ul>
jQuery:
$("#top-menu .menu-item-has-children a").click(function( event ) {
event.preventDefault();
console.log('clicked');
});
Add a > (CSS Direct Descendant Selector):
$("#top-menu .menu-item-has-children > a").click(function( event ) {
event.preventDefault();
console.log('clicked');
});
That selects only<a/> tags that are a direct descendant of menu-item-has-children.
So for example, in this code block, it selects the 'Link 2' anchor, but not any 'Google' anchor:
<li class="menu-item-has-children"><a>Link 2</a>
<ul>
<li>Google</li>
<li>Google</li>
<li>Google</li>
<li>Google</li>
</ul>
</li>

Not able to write article after vertical menu in HTML

I am trying to write my article beside my vertical menu, but all my article going inside that menu. I want my menu to be fixed on that page on the left side and all my new articles or any pictures should come on after menu.
MY HTML
<nav id="wrapper-250">
<ul class="accordion">
<li id="one" class="files">
Health Beat
<ul class="sub-menu">
<li><em>01</em>Sub Menu 1
<ul class="sub-sub-menu">
<li><em>a</em>Sub Menu 2</li>
<li><em>b</em>Sub Menu 2</li>
<li><em>c</em>Sub Menu 2</li>
<li><em>d</em>Sub Menu 2</li>
<li><em>e</em>Sub Menu 2</li>
</ul>
</li>
<li><em>02</em>Sub Menu 1</li>
<li><em>03</em>Sub Menu 1</li>
<li><em>04</em>Sub Menu 1</li>
<li><em>05</em>Sub Menu 1</li>
</ul>
</li>
<li id="two" class="mail">
Mail
<ul class="sub-menu">
<li><em>01</em>Hotmail</li>
<li><em>02</em>Yahoo</li>
</ul>
</li>
<li id="three" class="cloud">
Cloud
<ul class="sub-menu">
<li><em>01</em>Connect</li>
<li><em>02</em>Profiles</li>
<li><em>03</em>Options</li>
<li><em>04</em>Connect</li>
<li><em>05</em>Profiles</li>
<li><em>06</em>Options</li>
</ul>
</li>
<li id="four" class="sign">
Sign Out
<ul class="sub-menu">
<li><em>01</em>Log Out</li>
<li><em>02</em>Delete Account</li>
<li><em>03</em>Freeze Account</li>
</ul>
</li>
</ul>
</nav>
<div id="body-part">
<p>
</P>
</div>
http://codepen.io/anon/pen/XbXbqQ
Add a big padding-left to your #body-part:
padding-left: 500px; /* example */
Demo here: http://jsfiddle.net/baLq1d1k/
Or you can do it using jquery if the width of your #wrapper-250 changes:
$("#body-part").css("padding-left", ($("#wrapper-250").width() + 10));

Center DropDown Menu inside itself

This is my scenario
(JsFiddle Link at the end of page)
I want to center the buttons "Home", "Categories", "Work", ecc ecc inside the same bar.
In other words, now is on left side; I want to center it.
<nav id="menu-wrap">
<ul id="menu">
<li>Home</li>
<li>
Categories
<ul>
<li>
CSS
<ul>
<li>Item 11</li>
<li>Item 12</li>
<li>Item 13</li>
<li>Item 14</li>
</ul>
</li>
<li>
Graphic design
<ul>
<li>Item 21</li>
<li>Item 22</li>
<li>Item 23</li>
<li>Item 24</li>
</ul>
</li>
<li>
Development tools
<ul>
<li>Item 31</li>
<li>Item 32</li>
<li>Item 33</li>
<li>Item 34</li>
</ul>
</li>
<li>
Web design
<ul>
<li>Item 41</li>
<li>Item 42</li>
<li>Item 43</li>
<li>Item 44</li>
</ul>
</li>
</ul>
</li>
<li>
Work
<ul>
<li>
Work 1
<ul>
<li>
Work 11
<ul>
<li>Work 111</li>
<li>Work 112</li>
<li>Work 113</li>
</ul>
</li>
<li>
Work 12
<ul>
<li>Work 121</li>
<li>Work 122</li>
<li>Work 123</li>
</ul>
</li>
<li>
Work 13
<ul>
<li>Work 131</li>
<li>Work 132</li>
<li>Work 133</li>
</ul>
</li>
</ul>
</li>
<li>
Work 2
<ul>
<li>
Work 21
<ul>
<li>Work 211</li>
<li>Work 212</li>
<li>Work 213</li>
</ul>
</li>
<li>
Work 22
<ul>
<li>Work 221</li>
<li>Work 222</li>
<li>Work 223</li>
</ul>
</li>
<li>
Work 23
<ul>
<li>Work 231</li>
<li>Work 232</li>
<li>Work 233</li>
</ul>
</li>
</ul>
</li>
<li>
Work 3
<ul>
<li>
Work 31
<ul>
<li>Work 311</li>
<li>Work 312</li>
<li>Work 313</li>
</ul>
</li>
<li>
Work 32
<ul>
<li>Work 321</li>
<li>Work 322</li>
<li>Work 323</li>
</ul>
</li>
<li>
Work 33
<ul>
<li>Work 331</li>
<li>Work 332</li>
<li>Work 333</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>About</li>
<li>Contact</li>
</ul>
</nav>
http://jsfiddle.net/uHuHE/
Just assign text-align: center; to #menu ul a
Demo
Side Note: If you want to be over specific with the nested level text alignment, you can always use > selector so say for example you want to align the text in 1st drop down level, than you can simply use
ul#menu > li {
/* Targets main menu items */
}
ul#menu > li > ul > li > a {
/* Targets 1st level dropdown */
}
And so on...
As you commented, you wanted to center the main menu items, than use #menu-wrap in the place of #menu {} declaration, assign some fixed width to your #menu and than use margin: auto;
Demo 2