Is it possible to attach html tag to others using Javascript?
<li> to other <li> ?
For instance, I'm creating dropdown menu.
I have div separate from the <ul> tag
<ul>
<li>menu1</li>
<li>menu2</li>
</ul>
<div id="submenu1">
<li>sub1</li>
<li>sub2</li>
</div>
When I click, say, a link, then I want sub menu to show up under menu1 so result would be like:
<ul>
<li>menu1</li>
<div id="submenu1">
<li>sub1</li>
<li>sub2</li>
</div>
</ul>
The reason why I choose <div> to be separated from beginning instead of nested in <li> tag is that if I set the <div> "hide", it hides but it occupies the space and created big space between menu1 and any content below, so my page looks weird like:
mypage
----------------------------
| menu1
|
| <------ big open space div is hiding
|
|
| hello content start here
EDIT
Thanks for the tip guys, I've solved the problem with removing div and have nested <ul> per suggestion. The elements are still being shifted when submenu shows up but used CSS position:absolute and specifying z-index helped.
This is invalid HTML. A li should be contained in either a ol or a ul element. Change
<div id="submenu1">
<li>sub1</li>
<li>sub2</li>
</div>
to
<ul id="submenu1">
<li>sub1</li>
<li>sub2</li>
</ul>
For your main problem, there is no need to put the div (or ideally ul) outside the main ul. When you hide an element by setting its visibility to hidden, it will still take up the empty space. To complete hide it and remove any space it was taking, set the display CSS property to none.
document.getElementById('submenu1').style.display = 'none';
Usually you put the submenu in another <ul> inside an <li> in your main menu (so that you get valid HTML), and hide it with display: none CSS property and show it on click.
<ul>
<li>menu item 1<ul class="submenu">
<li>sub 1</li>
</ul></li>
<li><a hrf="menu2">menu item 2</a></li>
</u>
Then in your CSS (or added using js):
ul.submenu {
display: none;
}
a:hover + ul.submenu, ul.submenu:hover {
display: block;
}
This one will work on modern browsers without any js! But you can do it with js too, of course.
This is usually done via CSS. You have the entire menu pre-created (note that nesting <div> within <ul> is invalid HTML):
<ul class="menu">
<li>menu1
<ul class="submenu">
<li>sub1</li>
<li>sub2</li>
</ul>
</li>
</ul>
and then you declare in CSS:
ul.submenu {
display: none;
}
Now you can remove or add the "submenu" CSS class from the <ul> through JavaScript, or you set the .style.display property.
Or even more elegantly (but less cross-browser compatible, if you still care for old browsers), entirely without JavaScript through pure CSS:
ul.menu > li:hover ul.submenu {
display: block;
}
ul.submenu:hover {
display: block;
}
If you use display: none in your CSS then the hidden element doesn't need any space:
HTML:
<ul>
<li>menu1
<ul id="submenu1">
<li>sub1</li>
<li>sub2</li>
</ul>
</li>
<li class="active">menu2
<ul id="submenu1">
<li>sub1</li>
<li>sub2</li>
</ul>
</ul>
CSS:
li ul {
display: none;
}
li.active {
display: block;
}
<ul>
<li>menu1</li>
<div id="submenu1" style="display: none">
<li>sub1</li>
<li>sub2</li>
</div>
<li>menu2</li>
</ul>
Try it, this will make the div take up no space. if you use visiblity: hidden then it will take up space.
Related
I am currently working on a navigation menu where any menu item doesn't fit onto available space get appended onto a hidden unordered list(ul) which can be accessed through a toggle button. What I would like to achieve is to display Group-1, Group-2...as inline-block without affecting css of child elements.I am trying to use below css;
.hidden-link{
display:inline-block;
}
However when I use this line it changes all children element's property to show in a row rather that in a table format. I have tried jquery as well but no win.
$(document).ready(function(){
$("ul.hidden-links").children().css("display","inline-block");
});
e.g
<div class="container">
<ul class='hidden-links hidden'>
<li>Group1
<ul class ="flash">
<li>item-1</li>
<li>item-1</li>
<li>item-1</li>
</ul>
</li>
<li>Group2
<ul class ="flash">
<li>item-1</li>
<li>item-1</li>
<li>item-1</li>
</ul>
</li>
<li>Group3
<ul class ="flash">
<li>item-1</li>
<li>item-1</li>
<li>item-1</li>
</ul>
</li>
</ul>
</div>
If I understand you correctly, you only need to select the direct children of the menu.
Then this is all you need.
$(document).ready(function(){
$("ul.hidden-links > li").css("display","inline-block");
});
If you want each element do be shown on a separate row, then you should be using display: block instead of `inline-block'.
More info on inline-block here http://www.w3schools.com/css/css_inline-block.asp
You can use simple css tricks to tackle this problem. Styled both ul in different css.
.hidden-links li{
display: inline-block;
}
li .flash li{
display: block;
}
I'm using Foundation v6.2.0 in my project. I am having some difficulties with getting the top bar to work as desired on small screens. On small screens I want the top level of the navigation to act as a direct link (rather than a trigger to show the sub-menu) and instead move that functionality to the caret (little down arrow) on the right of the top level item, so it now triggers the display of the sub-navigation.
$(document).foundation();
<link href="https://cdn.jsdelivr.net/foundation/6.2.0/foundation.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/foundation/6.2.0/foundation.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav class="title-bar" data-responsive-toggle="top-bar-menu" data-hide-for="medium">
<div class="title-bar-left">
</span>
</div>
<div class="title-bar-right hide-for-small">
</div>
</nav>
<nav class="top-bar main-nav" id="top-bar-menu">
<div class="row main-nav">
<div class="top-bar-left">
<ul class="vertical medium-horizontal menu menu-items" data-closing-time="0" data-responsive-menu="accordion medium-dropdown">
<li>Item 1</li>
<li>Item 2
<ul class="menu vertical">
<li>Item 2A</li>
<li>Item 2B</li>
</ul>
</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li
</ul>
</div>
<div class="top-bar-right search-bar">
</div>
</div>
</nav>
If you want (say) Item 2 to act as an <a href="go_here"> link when clicked (rather than a trigger to display Item 2A and Item 2B); I don't think there is a standard way to do this in Foundation. However you can get round it with additional links that are hidden for larger screens or JavaScript/jQuery + CSS + HTML changes:
Additional links
This option doesn't leave you needing to add hacks or additional CSS to hide unwanted menu furniture or override the way foundation menus work. What this does is add a new link that is only visible on small screens whilst leaving the original link untouched to continue acting as a trigger.
<li>Item 2
<ul>
<li class="show-for-small-only">
Item 2 "home"
</li>
<li>Item 2A</li>
<li>Item 2B</li>
</ul>
</li>
JSfiddle: https://jsfiddle.net/sons9wzr/2/
This is more usable but requires an additional click to expose the sub menu. It would also be possible to do this with JavaScript/jQuery dynamically.
JavaScript/jQuery + CSS + HTML
If the aim is to only have the relevant links for mobile and an expanded menu for desktop, you can hide the sub navigation using a similar added class as in the first example above, add the JavaScript and then hide the redundant carets with CSS.
So your HTML becomes something like:
<li><a class="forced" href="http://foundation.zurb.com/">Item 2</a>
<ul class="show-for-large-only">
<li>Item 2A</li>
<li>Item 2B</li>
</ul>
</li>
Then use JavaScript (jQuery as it is required by Foundation anyway) to force the click on certain nav items (by adding class="forced" to each <a> you want to force to go to a new location in the HTML above).
An example of JavaScript for small screens only:
//check for screen size = small
if(Foundation.utils.is_small_only()) {
$('nav').on('click','a.forced', function (e) {
e.preventDefault;
window.location.href = $(this).attr('href');
});
}
(More information on the Media Query JS utility)
This will still leave the caret on the menu item though which may be confusing for users so you can remove it (from ALL sub-nav items) with this:
.is-accordion-submenu-parent > a::after {
display: none;
}
This should give you the desired effect, though it may require additional maintenance when you update Foundation.
Example in Codepen (without code for small-screens only): http://codepen.io/tymothytym/pen/eZGEER
Edit:
OK, so based on this comment:
I want to be able to expand the menu in the mobile view by clicking on the icon at the right of the parent element as well as to be able to click on the parents element itself.
I have created a new solution. This is very much a hack, and not a wonderful solution. I would recommend either finding an alternative navigation set up or working within the framework that Foundation offers.
New HTML (forced class moved to <li> & <span> added)
<li class="forced">
<span data-item="Item 2" class="show-for-small-only"></span>
Item 2
<ul class="menu vertical">
<li>Item 2A</li>
<li>Item 2B</li>
</ul>
</li>
New CSS
This splits up the contents of the <li> and positions the new sub-element
.is-accordion-submenu-parent > a::after {
display: none;
}
#media only screen and (max-width: 40em) {
li.forced span {
content: 'Item 2';
display: inline-block;
padding: .7rem 1rem;
line-height: 1;
width: 70%;
color: #2199e8;
cursor: pointer;
}
.menu > li.forced > a {
padding: .7rem 1rem;
line-height: 1;
float: right;
}
}
New JavaScript
This changes the text of the link (you'd need to do this for small screens only as shown above... above) makes the new <span> a link, inserts text into it by way of a data attribute & changes the original link text to a caret (to preserve as much original functionality as possible).
$(document).foundation();
$('nav').on('click','.forced span', function () {
window.location.href = $(this).siblings('a').attr('href');
});
$('.forced > a').html("▼");
$('.forced > span').text($('.forced > span').data("item"));
Example here: http://codepen.io/tymothytym/pen/GZOqvO
I think this is likely to have usability issues and maintenance issues so use with caution.
I have a ul element which I need to add list item dynamically. UL element has class name res. I don't want to add class to list item. Is there anyway to add the list item dynamically without losing the style..!
<ul class="res">
<li>Home</li>
<li>About</li>
<li>Services</li>
<li>Gallery</li>
<li>Short Codes</li>
<li>Contact</li>
<li><a id="login" href="login.html">login</a></li>
<li><a id="logout">Hello Guest<span class="arrorow">▼</span></a>
<ul class="sub-menu">
<li>View Profile</li>
<li>Booking History</li>
<li>Logout</li>
</ul>
</li>
</ul>
EDIT 1:
I attached a pic here... Please see it carefully.
I added those circled ones dynamically. Please check the styling of that...!
You can use ELEMENT NAME to style it without the need of adding class to each element.
For example:
ul.res li {
color: red;
}
The above code will apply color red to all li elements inside ul with class res.
Using
$('.res').append('<li>Location</li>')
this resolved the issue...!
I have a navigation menu that works well and looks good.
The HTML for the menu is:
<div id="menubar">
<div id="welcome">
<h1>Cedars Hair <span>Academy</span></h1>
</div><!--close welcome-->
<div id="menu_items">
<ul id="menu">
<li class="current">Home</li>
<li>The Salon</li>
<li>Testimonials</li>
<li>Courses</li>
<li>The Staff</li>
<li>Contact Us</li>
</ul>
</div><!--close menu-->
</div><!--close menubar-->
But I want to change it so it is something like:
<li>The Salon
<ul>
<li>Hair Cut</li>
</ul>
</li>
So under the salon, a drop down menu would come up with 'Hair Cut'.
I know this is possible with CSS, but the problem is I have a lot of CSS with the divs shown above (menubar, welcome, menu_items etc). Do you know the most simplest way to make a simple dropdown?
The simplest way in a nutshell:
https://jsfiddle.net/svArtist/2jd9uvx0/
hide lists inside other lists
upon hovering list elements, show the child lists
ul ul {
display:none;
display:absolute;
bottom:-100%;
}
li{
position:relative;
}
li:hover>ul {
display:table;
}
<ul>
<li>The Salon
<ul>
<li>Hair Cut
</li>
</ul>
</li>
</ul>
Why don't you use Jquery UI?
https://jqueryui.com/menu/
<script>
$(function() {
$( "#menu" ).menu();
});
</script>
Added the sub menu using li:hover
Here is the fiddle - https://jsfiddle.net/gkdj6y5x/
I have been using flaunt.js ( Original Source, but have modified the initial css and html.
I have removed the class styles from ul and li so it uses just list tags.
But for some reason when I go into mobile.. it shows the 3 line menu button on my local page, but when I click it... things don't work as they do on the source.
I can't see the the menu properly.. I can't see the arrow to show there are drop down.
If someone could assist
thanks
<nav class="nav">
<ul>
<li>
Home
<ul>
<li >
Submenu item 1
</li>
<li >
Submenu item 2
</li>
<li >
Submenu item 3
</li>
<li >
Submenu item 4
</li>
</ul>
</li>
<li>
About
</li>
<li>
Services
<ul>
<li >
Submenu item 1
</li>
<li >
Submenu item 2
</li>
<li >
Submenu item 3
</li>
<li >
Submenu item 4
</li>
</ul>
</li>
<li>
Portfolio
</li>
<li >
Testimonials
</li>
<li>
Contact
</li>
</ul>
</nav>
Fiddle
You've removed necessary HTML and haven't compensated for that in the JS
Original JS:
// Append the mobile icon nav
$('.nav').append($('<div class="nav-mobile"></div>'));
// Add a <span> to every .nav-item that has a <ul> inside
$('.nav-item').has('ul').prepend('<span class="nav-click"><i class="nav-arrow"></i></span>');
Your modified JS:
// Append the mobile icon nav
$('.nav').append($('<div class="nav-mobile"></div>'));
// Add a <span> to every .nav-item that has a <ul> inside
$('.nav').has('ul').prepend('<span class="nav-click"><i class="nav-arrow"></i></span>');
See how your selector targets the .nav on both lines? This is adding the span in a place the rest of the script isn't expecting. In your JS to change the selector back to .nav-item and add the .nav-item class back to the root level <li>s.
You will also need to change:
// Dynamic binding to on 'click'
$('ul').on('click', '.nav-click', function(){
To:
// Dynamic binding to on 'click'
$('.nav-list').on('click', '.nav-click', function(){
There is more than one <ul> in your markup, so your blanket binding the click to <ul> is disrupting things too.
EDIT: Modified HTML, CSS, and JS: http://jsfiddle.net/xtt3j/. I'm not sure why you're so keen on doing everything without any classes. I'm all about reducing markup but I feel like this is going to be a harder to maintain (or to just wrap your head around). And finally, the arrow won't display in any of these Fiddles because it is an image.
I have modified your example code on http://jsfiddle.net/WdN8J/10/. In Chrome, there is initial padding offset so I put -webkit-padding-start: 0px. The conflict is that your dropdown nav has absolute position:
.nav ul > li > ul {
display:none;
position:absolute;
left:0;
width:180px;
}
So I added the following line in the click action:
$('.nav ul > li > ul').css({'position':'relative', 'width':'100%'});