使用 javascript 添加活动 class 到主菜单
add active class to main menu using javascript
我搜索了很多使用 javascript
将活动 class 添加到父菜单的方法。
我找到了更多示例,但没有一个适用于我,下面是我的代码
HTML
<div id="menu1" class="hmenu">
<ul>
<li><a href="#">Item1</a>
<ul>
<li><a href="#">SubItem1</a>
<ul>
<li><a href="#">SubSubItem1</a></li>
<li><a href="#">SubSubItem2</a></li>
</ul>
</li>
<li><a href="#">SubItem2</a> </li>
<li><a href="#">SubItem3</a>
<ul>
<li><a href="#">SubSubItem1</a></li>
<li><a href="#">SubSubItem2</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">Item2</a></li>
<li><a href="#">Item3</a>
<ul>
<li><a href="#">SubItem1</a>
<ul>
<li><a href="#">SubSubItem1</a></li>
<li><a href="#">SubSubItem2</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<br style="clear: left" />
</div>
我的要求是当我点击 SubItem1 然后 Item1 和 SubItem1 应该是活跃。
当我点击 SubSubItem1 然后 SubSubItem1 ,SubItem1 和 Item1 应该是活动的。
意味着当点击任何 link 然后它的所有父 link 和相同的 link 应该是活跃的。
我试过这个 javascript
代码:
$(document).ready(function () {
$('.hmenu ul li ul').find('li').click(function () {
//removing the previous selected menu state
$('.hmenu').find('li.active').removeClass('active');
//adding the state for this parent menu
$(this).parents('li').addClass('active');
});
});
实际上我没有任何 javascript
编码经验,无法找出我 code
中的问题。
任何人都可以建议我这样做。
问题来自.find('li').click()
。
当您使用嵌套 <li>
时,这将导致在您单击子项 <li>
时触发该事件两次。这会导致问题。不能将 click()
添加到 <a>
元素吗?
$(document).ready(function () {
$('.hmenu a').click(function () {
//removing the previous selected menu state
$('.hmenu').find('li.active').removeClass('active');
//adding the state for this parent menu
$(this).parents("li").addClass('active');
});
});
工作正常:https://jsfiddle.net/6put8tdx/
请注意,由于 #
锚点,单击 a
选项卡时您的页面将跳到顶部。如果你想避免这种情况,你可以将事件传递给函数 .click(function (event) {...}
并在里面添加 event.preventDefault
.
试试这个:
$(function () {
$("li a")
.on("click", function () {
$(this).toggleClass("active");
$(this).closest("ul").parent().children("li a").toggleClass("active")
.parent().parent().parent().children("li a").toggleClass("active");
});
});
从点击的元素开始遍历。如果 hasclass
removeClass
...
使用 toggleClass()
来避免平凡的检查
如果您需要将点击目标作为 LI 元素(与 Delgan 的回答相反)
您可以在目标 LI 的 parents
上使用 .not()
以防止弄乱冒泡事件目标:
$(document).ready(function () {
$('.hmenu').find('li').click(function(event) {
event.preventDefault(); // Prevent page jumps due to anchors
var $par = $(event.target).parents("li"); // get list of parents
$(".hmenu .active").not( $par ).removeClass("active"); // not them
$(this).addClass('active'); // let the event propagation do the work
});
});
$(document).ready(function () {
$('.hmenu').find('li').click(function(event) {
event.preventDefault();
var $par = $(event.target).parents("li");
$(".hmenu .active").not($par).removeClass("active");
$(this).addClass('active');
});
});
.active > a{
background: gold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="menu1" class="hmenu">
<ul>
<li><a href="#">Item1</a>
<ul>
<li><a href="#">SubItem1</a>
<ul>
<li><a href="#">SubSubItem1</a></li>
<li><a href="#">SubSubItem2</a></li>
</ul>
</li>
<li><a href="#">SubItem2</a> </li>
<li><a href="#">SubItem3</a>
<ul>
<li><a href="#">SubSubItem1</a></li>
<li><a href="#">SubSubItem2</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">Item2</a></li>
<li><a href="#">Item3</a>
<ul>
<li><a href="#">SubItem1</a>
<ul>
<li><a href="#">SubSubItem1</a></li>
<li><a href="#">SubSubItem2</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<br style="clear: left" />
</div>
为了更好的理解上面的内容
下面的示例有效 out-of-the-box,单击的那个和所有 LI parents 得到 "active"
class.
为什么? 因为事件目标是 li
,意味着 .hmenu
的任何 li
- 所以点击是 附加的 到其中任何一个,然后单击 subsub LI,事件将传播到 LI
parents - 触发相同的 click
行为( 这个加class)!
$(".hmenu").on("click", "li", function(){
$(this).addClass("active"); // Wow! Event propagation rulez!!
});
但是我们需要删除现有的 .active
,这里变得很乱...
$(".hmenu").on("click", "li", function(){
$(".active").removeClass("active"); // triggered on every event bubble :(
$(this).addClass("active"); // leaving only the main parent with active class
});
这是由事件冒泡并触发 parent 元素的相同操作时发生的并发引起的。
防止并发的一种方法是使用 1
毫秒的 setTimeout
:
$(".hmenu").on("click", "li", function(){
$(".active").removeClass("active");
setTimeout(function(){ // Let the previous finish the bubbling mess
$(this).addClass("active"); // Yey! all fine! Every LI has the active class
}, 1);
});
但是这里 1ms
的超时会导致视觉 "blinking" 问题。
我搜索了很多使用 javascript
将活动 class 添加到父菜单的方法。
我找到了更多示例,但没有一个适用于我,下面是我的代码
HTML
<div id="menu1" class="hmenu">
<ul>
<li><a href="#">Item1</a>
<ul>
<li><a href="#">SubItem1</a>
<ul>
<li><a href="#">SubSubItem1</a></li>
<li><a href="#">SubSubItem2</a></li>
</ul>
</li>
<li><a href="#">SubItem2</a> </li>
<li><a href="#">SubItem3</a>
<ul>
<li><a href="#">SubSubItem1</a></li>
<li><a href="#">SubSubItem2</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">Item2</a></li>
<li><a href="#">Item3</a>
<ul>
<li><a href="#">SubItem1</a>
<ul>
<li><a href="#">SubSubItem1</a></li>
<li><a href="#">SubSubItem2</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<br style="clear: left" />
</div>
我的要求是当我点击 SubItem1 然后 Item1 和 SubItem1 应该是活跃。
当我点击 SubSubItem1 然后 SubSubItem1 ,SubItem1 和 Item1 应该是活动的。
意味着当点击任何 link 然后它的所有父 link 和相同的 link 应该是活跃的。
我试过这个 javascript
代码:
$(document).ready(function () {
$('.hmenu ul li ul').find('li').click(function () {
//removing the previous selected menu state
$('.hmenu').find('li.active').removeClass('active');
//adding the state for this parent menu
$(this).parents('li').addClass('active');
});
});
实际上我没有任何 javascript
编码经验,无法找出我 code
中的问题。
任何人都可以建议我这样做。
问题来自.find('li').click()
。
当您使用嵌套 <li>
时,这将导致在您单击子项 <li>
时触发该事件两次。这会导致问题。不能将 click()
添加到 <a>
元素吗?
$(document).ready(function () {
$('.hmenu a').click(function () {
//removing the previous selected menu state
$('.hmenu').find('li.active').removeClass('active');
//adding the state for this parent menu
$(this).parents("li").addClass('active');
});
});
工作正常:https://jsfiddle.net/6put8tdx/
请注意,由于 #
锚点,单击 a
选项卡时您的页面将跳到顶部。如果你想避免这种情况,你可以将事件传递给函数 .click(function (event) {...}
并在里面添加 event.preventDefault
.
试试这个:
$(function () {
$("li a")
.on("click", function () {
$(this).toggleClass("active");
$(this).closest("ul").parent().children("li a").toggleClass("active")
.parent().parent().parent().children("li a").toggleClass("active");
});
});
从点击的元素开始遍历。如果 hasclass
removeClass
...
toggleClass()
来避免平凡的检查
如果您需要将点击目标作为 LI 元素(与 Delgan 的回答相反)
您可以在目标 LI 的 parents
上使用 .not()
以防止弄乱冒泡事件目标:
$(document).ready(function () {
$('.hmenu').find('li').click(function(event) {
event.preventDefault(); // Prevent page jumps due to anchors
var $par = $(event.target).parents("li"); // get list of parents
$(".hmenu .active").not( $par ).removeClass("active"); // not them
$(this).addClass('active'); // let the event propagation do the work
});
});
$(document).ready(function () {
$('.hmenu').find('li').click(function(event) {
event.preventDefault();
var $par = $(event.target).parents("li");
$(".hmenu .active").not($par).removeClass("active");
$(this).addClass('active');
});
});
.active > a{
background: gold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="menu1" class="hmenu">
<ul>
<li><a href="#">Item1</a>
<ul>
<li><a href="#">SubItem1</a>
<ul>
<li><a href="#">SubSubItem1</a></li>
<li><a href="#">SubSubItem2</a></li>
</ul>
</li>
<li><a href="#">SubItem2</a> </li>
<li><a href="#">SubItem3</a>
<ul>
<li><a href="#">SubSubItem1</a></li>
<li><a href="#">SubSubItem2</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">Item2</a></li>
<li><a href="#">Item3</a>
<ul>
<li><a href="#">SubItem1</a>
<ul>
<li><a href="#">SubSubItem1</a></li>
<li><a href="#">SubSubItem2</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<br style="clear: left" />
</div>
为了更好的理解上面的内容
下面的示例有效 out-of-the-box,单击的那个和所有 LI parents 得到 "active"
class.
为什么? 因为事件目标是 li
,意味着 .hmenu
的任何 li
- 所以点击是 附加的 到其中任何一个,然后单击 subsub LI,事件将传播到 LI
parents - 触发相同的 click
行为( 这个加class)!
$(".hmenu").on("click", "li", function(){
$(this).addClass("active"); // Wow! Event propagation rulez!!
});
但是我们需要删除现有的 .active
,这里变得很乱...
$(".hmenu").on("click", "li", function(){
$(".active").removeClass("active"); // triggered on every event bubble :(
$(this).addClass("active"); // leaving only the main parent with active class
});
这是由事件冒泡并触发 parent 元素的相同操作时发生的并发引起的。
防止并发的一种方法是使用 1
毫秒的 setTimeout
:
$(".hmenu").on("click", "li", function(){
$(".active").removeClass("active");
setTimeout(function(){ // Let the previous finish the bubbling mess
$(this).addClass("active"); // Yey! all fine! Every LI has the active class
}, 1);
});
但是这里 1ms
的超时会导致视觉 "blinking" 问题。