Let's say that menu has the following structure:
<li class="parent-of-all">Parent
<ul class="sub-menu level-0">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4
<ul class="sub-menu level-1">
<li>Item 1.1</li>
<li>Item 1.2</li>
<li>Item 1.3
<ul class="sub-menu level-2">
<li>Item 2.1</li>
<li>Item 2.2
<ul class="sub-menu level-3">
<li>Item 3.1</li>
<li>Item 3.2</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
And this is how it looks like when styled (please note that nested sub-menus are position: absolute; left: 100%;).
Now the questions is - can I avoid it being pushed off the screen? I'm looking for a solution that Windows7 menus use (they never go off the screen). Is there some simple Javascript check? I think that doing just left: -100%; would work but under what conditions? I just need some idea and I can code that in Javascript :)
As far as i know, there is no way to do this check with CSS only. You will have to use javascript. The most straight forward approach would be binding mouseover/mouseout (or hover if you use jquery) to the items, then comparing the elements x-offset + width with window width.
With a pure CSS solution you could always alternate the position of the submenus. When the first was left positioned to appear right to its parent, the following (third) submenu could be positioned on the left and so on. Maybe you could even use the :nth-child-selector to do so.
Afterwards you can create exceptions for wider screens, just alternating the left position starting off the nth child submenu (using CSS media queries).
No, you need to use JavaScript in order to calculate positions
Related
I may possible have a requirement where i have to link the parent menu to a link rather than showing sub menu. Right now i am using Slick Menu http://slicknav.com/
Logically parent menu should not be linked as it should show child menu on mobile device. while desktop version we can counter this with hover effect can show sub-menus and click on the parent menu can open link also but on small screen we can either open link or show submenu.
my question right now is that in fiddle example (http://jsfiddle.net/y1dLdd1f/1/) i am linking Parent 1 meny to google.com, but script is blocking this. How can i unblock it and when user click on it it opens the page rather than showing the sub menu if parent menu has a proper link
<ul id="menu">
<li>Parent 1
<ul>
<li>item 3</li>
<li>Parent 3
<ul>
<li>item 8</li>
<li>item 9</li>
<li>item 10</li>
</ul>
</li>
<li>item 4</li>
</ul>
</li>
<li>item 1</li>
<li>non-link item</li>
<li>Parent 2
<ul>
<li>item 5</li>
<li>item 6</li>
<li>item 7</li>
</ul>
</li>
</ul>
Slick menu has a number of available options including "allowParentLinks", all you need should be,...
$(document).ready(function(){
$('#menu').slicknav({
allowParentLinks:"true"
});
});
But to show this working in JSFiddle you would need to add target="_blank" to you <a> tag.
I am trying to create a menu formated by jQuery. The appearance and functionality of level one items is correct, but the subsquent levels are not correctly formatting as a submenu that appears with mouse over. Rather it simply appears, and does not highlight the items as the level one items do with mouse over or hover (neither function appears in my code).
HTML CODE
<div style="width: 25%">
<ul id="menu">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3
<ul>
<li>Item 3-1</li>
<li>Item 3-2</li>
<li>Item 3-3</li>
<li>Item 3-4</li>
<li>Item 3-5</li>
</ul>
</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
</div>
jQuery or JavaScript
$(document).ready(function() {
$('#menu').menu({menus: "div"});
});
JS Fiddle
I figured it out. It is a matter of simply deleting in the JavaScript the following from line 6:
{menus: div}
I am using css3 columns to display an unordered list in 3 columns. The list items contain lists as well that can be shown or hidden by clicking on the title using jQuery.
The html looks like (with class names to describe the layout and interactions):
<ul class="i-display-in-3-columns">
<li>
<h3 class="slide-toggle-sibling-list-on-click">column title 1</h3>
<ul class="i-am-initially-hidden">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
</ul>
</li>
<li>
<h3 class="slide-toggle-sibling-list-on-click">column title 2.</h3>
<p>This can be very long with perhaps an additional paragraph as well.</p>
<ul class="i-am-initially-hidden">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
</ul>
</li>
/* some more items */
</ul>
This works, but every time a sub-list is opened or closed, the columns get redrawn.
I would like to freeze the columns after they have initially been drawn to avoid this reflow so that every item stays in the column it is initially drawn in.
I can of course write a masonry-like solution in javascript to convert my list in 3 lists that are displayed next to each other, but I was hoping that there was an easier solution, preferably in just css or in javascript that keeps my list as a list.
Is that possible or would I just have to rewrite the DOM?
I don't think you can achieve that with CSS columns. There is the option to toggle visibility instead of display of the child lists, but I'm assuming you don't want that.
Another possible CSS solution is using the flexbox module (and deal with the browser support issues). For example, I believe this might be what you want (working on Chrome 29):
.i-display-in-3-columns {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.i-display-in-3-columns>li {
flex: 1 1 200px; /* 200px is the column width */
}
Demo
The great Google and SO didn't render search results regarding this. Some were similar but didn't quite get me there.
I am in need of making a classless submenu that will attach a style attribute to each individual <li> in the sub <ul> in order to set a min-width property based on the number of sub list items.
The HTML
<nav>
<ul>
<li>HOME</li>
<li>ABOUT COMPANY</li>
<li>
ABOUT PRODUCT
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</li>
<li>GETTING STARTED</li>
<li>
PATIENT SUPPORT
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</li>
<li>CONTACT</li>
<li>eUPDATES</li>
</ul>
</nav>
The JavaScript
$('.sub').text(function() {
var count = $(this).next().find('li').length;
var totalwidth = count * 115;
$(this).next().find('li').parent('ul').attr('style','min-width:'+totalwidth+'px');
});
I need to be able to do this without searching based off the class "sub". I've tried a few times, but none of it seems as powerful as the code I'm currently using. The backend developer I'm working with is requiring it to all be simple <ul><li></li></ul> structure with no classes.
If anyone can help point me in the right direction on this, I'd greatly appreciate your time and help!
Target all LI items that contain UL's, find the number of LI's in those UL's, and multiply for width :
$('ul', 'li').css('min-width', function() {
return ( $(this).find('li').length * 115 ) + 'px';
});
This is such a basic question but I am having trouble finding the answer - How do I implement the action taken when a list item in an Html menu is clicked?
I’m using an list in my code as a menu, say:
<ul >
<li id="link1">Link 1</li>
<li>Link 2
<ul class="level2">
<li>Link 2a</li>
<li>Link 2b</li>
<li>Link 2c</li>
</ul></li>
</ul>
I tried giving the menu an id, id="myMenu", and an onclick event, and the js was called, but I couldn’t see a way to identify which item was clicked, just that an line item was clicked in myMenu.
<ul id="myMenu" onclick="gothere(id)">
<li>Link 1</li>
<li>Link 2
<ul class="level2">
<li>Link 2a</li>
<li>Link 2b</li>
<li>Link 2c</li>
</ul></li>
</ul>
<script type="text/javascript">
function gothere(id)
{
alert("got here "+id) ;
}
</script>
I tried adding an id on a child element, id="link1", and that worked, but the js was called for the child and then for the parent.
<ul id="myMenu" onclick="gothere(id)">
<li id="link1" onclick="gothere(id)">Link 1</li>
<li>Link 2
<ul class="level2">
<li>Link 2a</li>
<li>Link 2b</li>
<li>Link 2c</li>
</ul></li>
</ul>
I can use this approach to get what I need but is there a better way?
I am looking for something which sends the least amount of html over the wire (the reason I am redoing this menu from it's former implementation).
You shouldn't attach the events inline. Attach them with javascript.
<ul id="myMenu">
<li id="link1">Link 1</li>
<li>Link 2
<ul class="level2">
<li>Link 2a</li>
<li>Link 2b</li>
<li>Link 2c</li>
</ul></li>
</ul>
Note that I'm using jQuery for simplicity here:
$("#myMenu").click(function(e){
console.log(e.target);
});
http://jsfiddle.net/2rjgd/
With vanilla javascript the concept is the same, use the target property of the event object to find out where the click event originated from.
http://jsfiddle.net/2rjgd/1/ shows how this would be implemented with vanilla js. (in non IE browsers)
document.getElementById("myMenu").addEventListener("click", function(e){
console.log(e.target);
});
Identify the element target or srcElement in your handler, do not pass an argument:
document.getElementById("myMenu").onclick=goThere;
function goThere(e){
e= e || window.event;
var who=e.target || e.srcElement;
if(who.tagName=='LI'){
//handle the clicked list item
}
}
One way or another, you need a way to identify the element being clicked. Shmiddty gave you method for finding the target of the element that was clicked by name. You could then write an if/then statement to open windows or follow links based on specific names.
That may be more difficult/complicated for you to do than just assigning IDs to the elements and checking them. You can do this in vanilla js, using a statement like this:
var myLink1 = document.getElementById("link1");
myLink1.onclick=window.open("http://www.webaddresshere.com","_self");
My recommendation is to use JQuery if you can. It lets you do things like this:
$('li[id^=link1]').click(window.open("http://www.webaddresshere.com","_self"));