Reputation: 1487
I've got this menu that if the page width can't hold all of its items those remaining items are added to a more option.
The thing is, I can't open links when I click on a submenu from the more option. Here's an example which logs the link when clicked.
$(".top_menu li").click(function() {
console.log($(this).data('link'));
// Checks if there is a link
if (typeof $(this).data('link') !== 'undefined') {
//document.location.href = $(this).data('link');
}
});
$(".top_menu ul").each(function() {
alignMenu(this);
var robj = this;
$(window).resize(function() {
$(robj).append($($($(robj).children("li.hideshow")).children("ul")).html());
$(robj).children("li.hideshow").remove();
alignMenu(robj);
});
function alignMenu(obj) {
var w = 0;
var mw = $(obj).width() - 150;
var i = -1;
var menuhtml = '';
jQuery.each($(obj).children(), function() {
i++;
w += $(this).outerWidth(true);
if (mw < w) {
menuhtml += $('<div>').append($(this).clone()).html();
$(this).remove();
}
});
$(obj).append('<li class="hideshow">MORE <i class="material-icons">keyboard_arrow_down</i><ul>' + menuhtml + '</ul></li>');
$(obj).children("li.hideshow ul").css("top", $(obj).children("li.hideshow").outerHeight(true) + "px");
// Opens the menu
$(obj).children(".hideshow").click(function() {
$(this).find("ul").animate({
height: 'toggle'
}, 'fast');
});
}
});
.top_menu {
width: 100%;
}
ul.horizontal-menu,
.horizontal-menu ul {
list-style-type: none;
margin: 0;
padding: 0;
}
.horizontal-menu {
float: left;
width: 100%;
background: #616161;
}
.horizontal-menu li {
float: left;
display: block;
padding: 25px;
color: #FFFFFF;
text-decoration: none;
-webkit-transition: border-color .218s;
-moz-transition: border .218s;
-o-transition: border-color .218s;
transition: border-color .218s;
background: #616161;
cursor: pointer;
}
.horizontal-menu li .material-icons {
margin: -10px;
}
.hideshow ul li {
width: 250px;
text-align: center;
}
.horizontal-menu li:hover {
border-bottom: 3px solid rgb(246, 83, 20);
padding-bottom: 22px;
background: #484848;
}
.horizontal-menu li.hideshow ul {
position: absolute;
display: none;
left: -203px;
width: 300px;
}
.horizontal-menu li.hideshow {
position: relative;
}
.hideshow ul {
padding-bottom: 7px;
background: #616161;
border-radius: 0px 0px 4px 4px;
margin-top: 25px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Material Icons (Google) -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<div class="top_menu">
<ul class="horizontal-menu">
<li> <i class="material-icons">search</i> </li>
<li data-link="http://www.google.com">MENU 1</li>
<li data-link="http://www.google.com">MENU 2</li>
<li data-link="http://www.google.com">MENU 3</li>
<li data-link="http://www.google.com">MENU 4</li>
<li data-link="http://www.google.com">MENU 5</li>
<li data-link="http://www.google.com">MENU 6</li>
<li data-link="http://www.google.com">MENU 7</li>
<li data-link="http://www.google.com">MENU 8</li>
<li data-link="http://www.google.com">MENU 9</li>
<li data-link="http://www.google.com">MENU 10</li>
<li data-link="http://www.google.com">MENU 11</li>
<li data-link="http://www.google.com">MENU 12</li>
<li data-link="http://www.google.com">MENU 13</li>
<li data-link="http://www.google.com">MENU 14</li>
</ul>
</div>
Upvotes: 1
Views: 99
Reputation: 4150
You need to do event delegation as your li's are getting added dynamically
$(".top_menu li").click(function() {...
The above code will add event listener to li
directly which will cause problem as you are rearranging the li
in the DOM dynamically.
You have to use event delegation.
$(".top_menu").on('click','li[data-link]',function() {...
This code will add event listener to top-menu
but delegate the event to all its decedent li
with selector li[data-link]
Read about Event Delegation
Event delegation allows us to attach a single event listener, to a parent element, that will fire for all descendants matching a selector, whether those descendants exist now or are added in the future.
Check out my this answer for explanation on event delegation .
SNIPPET
$(".top_menu").on('click','li[data-link]',function() {
console.log($(this).data('link'));
// Checks if there is a link
if (typeof $(this).data('link') !== 'undefined') {
//document.location.href = $(this).data('link');
}
});
$(".top_menu ul").each(function() {
alignMenu(this);
var robj = this;
$(window).resize(function() {
$(robj).append($($($(robj).children("li.hideshow")).children("ul")).html());
$(robj).children("li.hideshow").remove();
alignMenu(robj);
});
function alignMenu(obj) {
var w = 0;
var mw = $(obj).width() - 150;
var i = -1;
var menuhtml = '';
jQuery.each($(obj).children(), function() {
i++;
w += $(this).outerWidth(true);
if (mw < w) {
menuhtml += $('<div>').append($(this).clone()).html();
$(this).remove();
}
});
$(obj).append('<li class="hideshow">MORE <i class="material-icons">keyboard_arrow_down</i><ul>' + menuhtml + '</ul></li>');
$(obj).children("li.hideshow ul").css("top", $(obj).children("li.hideshow").outerHeight(true) + "px");
// Opens the menu
$(obj).children(".hideshow").click(function() {
$(this).find("ul").animate({
height: 'toggle'
}, 'fast');
});
}
});
.top_menu {
width: 100%;
}
ul.horizontal-menu,
.horizontal-menu ul {
list-style-type: none;
margin: 0;
padding: 0;
}
.horizontal-menu {
float: left;
width: 100%;
background: #616161;
}
.horizontal-menu li {
float: left;
display: block;
padding: 25px;
color: #FFFFFF;
text-decoration: none;
-webkit-transition: border-color .218s;
-moz-transition: border .218s;
-o-transition: border-color .218s;
transition: border-color .218s;
background: #616161;
cursor: pointer;
}
.horizontal-menu li .material-icons {
margin: -10px;
}
.hideshow ul li {
width: 250px;
text-align: center;
}
.horizontal-menu li:hover {
border-bottom: 3px solid rgb(246, 83, 20);
padding-bottom: 22px;
background: #484848;
}
.horizontal-menu li.hideshow ul {
position: absolute;
display: none;
left: -203px;
width: 300px;
}
.horizontal-menu li.hideshow {
position: relative;
}
.hideshow ul {
padding-bottom: 7px;
background: #616161;
border-radius: 0px 0px 4px 4px;
margin-top: 25px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Material Icons (Google) -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<div class="top_menu">
<ul class="horizontal-menu">
<li> <i class="material-icons">search</i> </li>
<li data-link="http://www.google.com">MENU 1</li>
<li data-link="http://www.google.com">MENU 2</li>
<li data-link="http://www.google.com">MENU 3</li>
<li data-link="http://www.google.com">MENU 4</li>
<li data-link="http://www.google.com">MENU 5</li>
<li data-link="http://www.google.com">MENU 6</li>
<li data-link="http://www.google.com">MENU 7</li>
<li data-link="http://www.google.com">MENU 8</li>
<li data-link="http://www.google.com">MENU 9</li>
<li data-link="http://www.google.com">MENU 10</li>
<li data-link="http://www.google.com">MENU 11</li>
<li data-link="http://www.google.com">MENU 12</li>
<li data-link="http://www.google.com">MENU 13</li>
<li data-link="http://www.google.com">MENU 14</li>
</ul>
</div>
Upvotes: 3
Reputation: 476
The issue is that the $(".top_menu li").click(...)
function only applies to the li elements that exist at that time, and your code is removing and reattaching them to the dom later on. In order to attach to any li elements with a link that exist at that time or later, you can use the .on('click', selector, ...)
. And to avoid including the li.hideshow element you can use li[data-link]
as the selector.
$(".top_menu").on('click', 'li[data-link]', function() {
console.log($(this).data('link'));
// Checks if there is a link
if (typeof $(this).data('link') !== 'undefined') {
//document.location.href = $(this).data('link');
}
});
$(".top_menu ul").each(function() {
alignMenu(this);
var robj = this;
$(window).resize(function() {
$(robj).append($($($(robj).children("li.hideshow")).children("ul")).html());
$(robj).children("li.hideshow").remove();
alignMenu(robj);
});
function alignMenu(obj) {
var w = 0;
var mw = $(obj).width() - 150;
var i = -1;
var menuhtml = '';
jQuery.each($(obj).children(), function() {
i++;
w += $(this).outerWidth(true);
if (mw < w) {
menuhtml += $('<div>').append($(this).clone()).html();
$(this).remove();
}
});
$(obj).append('<li class="hideshow">MORE <i class="material-icons">keyboard_arrow_down</i><ul>' + menuhtml + '</ul></li>');
$(obj).children("li.hideshow ul").css("top", $(obj).children("li.hideshow").outerHeight(true) + "px");
// Opens the menu
$(obj).children(".hideshow").click(function() {
$(this).find("ul").animate({
height: 'toggle'
}, 'fast');
});
}
});
.top_menu {
width: 100%;
}
ul.horizontal-menu,
.horizontal-menu ul {
list-style-type: none;
margin: 0;
padding: 0;
}
.horizontal-menu {
float: left;
width: 100%;
background: #616161;
}
.horizontal-menu li {
float: left;
display: block;
padding: 25px;
color: #FFFFFF;
text-decoration: none;
-webkit-transition: border-color .218s;
-moz-transition: border .218s;
-o-transition: border-color .218s;
transition: border-color .218s;
background: #616161;
cursor: pointer;
}
.horizontal-menu li .material-icons {
margin: -10px;
}
.hideshow ul li {
width: 250px;
text-align: center;
}
.horizontal-menu li:hover {
border-bottom: 3px solid rgb(246, 83, 20);
padding-bottom: 22px;
background: #484848;
}
.horizontal-menu li.hideshow ul {
position: absolute;
display: none;
left: -203px;
width: 300px;
}
.horizontal-menu li.hideshow {
position: relative;
}
.hideshow ul {
padding-bottom: 7px;
background: #616161;
border-radius: 0px 0px 4px 4px;
margin-top: 25px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Material Icons (Google) -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<div class="top_menu">
<ul class="horizontal-menu">
<li> <i class="material-icons">search</i> </li>
<li data-link="http://www.google.com">MENU 1</li>
<li data-link="http://www.google.com">MENU 2</li>
<li data-link="http://www.google.com">MENU 3</li>
<li data-link="http://www.google.com">MENU 4</li>
<li data-link="http://www.google.com">MENU 5</li>
<li data-link="http://www.google.com">MENU 6</li>
<li data-link="http://www.google.com">MENU 7</li>
<li data-link="http://www.google.com">MENU 8</li>
<li data-link="http://www.google.com">MENU 9</li>
<li data-link="http://www.google.com">MENU 10</li>
<li data-link="http://www.google.com">MENU 11</li>
<li data-link="http://www.google.com">MENU 12</li>
<li data-link="http://www.google.com">MENU 13</li>
<li data-link="http://www.google.com">MENU 14</li>
</ul>
</div>
Upvotes: 0
Reputation: 15786
Your event trigger is not correct. You can change it into the below or add a class to the other ul.
$("li").click(function() {
Upvotes: -1