垂直菜单
问题:
1、老师的是鼠标完全移出二级菜单才会关闭二级菜单,我是完全移出一级菜单,二级菜单就跟着关闭了。
2、一级菜单,我没有写排他操作,就是没有事先去除 current类名,但是我给li元素加上 current类名之后,鼠标移出当前li元素前往下一个li元素的时候,按理说没有排他,当前的li元素还是current选中的状态,但是很奇怪,可以跟着我鼠标进行切换。
我检查了几遍js代码,以及css的结构、盒子宽高问题。没有发现什么问题。
唯一不一样的就是,老师的事件监听都是使用的DOM0级事件,我使用了DOM二级事件,我改为0级事件之后,一切都正常了。
0级是冒泡,从里往外走
2级是捕获,从外往里走。
不明白的是为什么改为0级之后,我的这两个问题就好了,也没有动其它的东西
请老师帮忙解惑
代码如下
/**
* 垂直菜单
* 2023-7-14
* 清夏
*/
(function () {
var banner_nav_ul = document.getElementById('banner_nav_ul');
var banner_nav = document.getElementById('banner_nav');
var menus = document.querySelectorAll('.menus-box .menu');
var banner_lis = document.querySelectorAll('#banner_nav_ul li');
// 鼠标进入一级菜单,显示对应二级菜单
/* banner_nav_ul.addEventListener('mouseover', function (e) {
if (e.target.tagName.toLowerCase() == 'li') {
var t = e.target.getAttribute('data-t');
e.target.className += ' current'; //这里我只是光添加了current类,没有去除所有的current,但是鼠标移到下一个li元素的时候,当前的li元素的状态自己就取消了
var theMenu = document.querySelector('.menus-box .menu[data-t = ' + t + ']');
for (var i = 0; i < menus.length; i++) { // 去掉所有盒子的menu
menus[i].className = 'menu';
}
theMenu.className = 'menu current'; // 给当前的盒子加上menu
}
}, true); */
banner_nav_ul.onmouseover = function (e) {
if (e.target.tagName.toLowerCase() == 'li') {
var t = e.target.getAttribute('data-t');
// 用DOM0级写法这里就必须先去掉所有的current类名,才行
for (var i = 0; i < banner_lis.length; i++) {
banner_lis[i].className = banner_lis[i].getAttribute('data-t');
}
e.target.className += ' current';
var theMenu = document.querySelector('.menus-box .menu[data-t = ' + t + ']');
for (var i = 0; i < menus.length; i++) { // 去掉所有盒子的menu
menus[i].className = 'menu';
}
theMenu.className = 'menu current'; // 给当前的盒子加上menu
}
};
// 鼠标离开一级菜单,关闭二级菜单显示
/* banner_nav.addEventListener('mouseleave', function () {
for (var i = 0; i < banner_lis.length; i++) {
banner_lis[i].className = banner_lis[i].getAttribute('data-t');
menus[i].className = 'menu';
}
}, true); */
banner_nav.onmouseleave = function () {
for (var i = 0; i < banner_lis.length; i++) {
banner_lis[i].className = banner_lis[i].getAttribute('data-t');
menus[i].className = 'menu';
}
};
})();<!-- banner --> <section class="banner" id="banner"> <ul class="carousel-list" id="carousel_list"> <li> <img src="./images/banner1.jpg" alt=""> </li> <li> <img src="./images/banner2.jpg" alt=""> </li> <li> <img src="./images/banner3.jpg" alt=""> </li> <li> <img src="./images/banner4.jpg" alt=""> </li> <li> <img src="./images/banner5.jpg" alt=""> </li> </ul> <!-- 小圆点 --> <ol class="circles" id="circle_ol"> <li data-n="0" class="current"></li> <li data-n="1"></li> <li data-n="2"></li> <li data-n="3"></li> <li data-n="4"></li> </ol> <div class="center-wrap"> <a href="#" class="leftbtn btn" id="left_btn"></a> <a href="#" class="rightbtn btn" id="right_btn"></a> <nav class="banner-nav" id="banner_nav"> <ul id="banner_nav_ul"> <li class="hot" data-t="hot"> <dl> <dt>热门出发地</dt> <dd> <em>北京</em> <em>上海</em> <em>广深</em> <em>西南</em> <em>国内其他</em> </dd> </dl> </li> <li class="hk" data-t="hk"> <dl> <dt>港澳台 国内</dt> <dd> <em>香港</em> <em>澳门</em> <em>台湾</em> <em>国内其他</em> </dd> </dl> </li> <li class="jp" data-t="jp"> <dl> <dt>日本 韩国</dt> <dd> <em>东京</em> <em>大阪</em> <em>冲绳</em> <em>北海道</em> <em>福冈</em> </dd> </dl> </li> <li class="as" data-t="as"> <dl> <dt>东南亚南亚</dt> <dd> <em>泰国</em> <em>新加坡</em> <em>印尼</em> <em>马来西亚</em> <em>越南</em> </dd> </dl> </li> <li class="eu" data-t="eu"> <dl> <dt>欧洲 美洲</dt> <dd> <em>英国</em> <em>法国</em> <em>美国</em> <em>加拿大</em> </dd> </dl> </li> <li class="au" data-t="au"> <dl> <dt>澳新 中东非</dt> <dd> <em>澳大利亚</em> <em>新西兰</em> <em>迪拜</em> </dd> </dl> </li> </ul> <div class="menus-box"> <div class="menu" data-t="hot"> <dl> <dt>港澳台</dt> <dd> <a href="">香港</a> <a href="">澳门</a> <a href="">台北</a> <a href="">高雄</a> <a href="">香港迪士尼</a> <a href="">香港海洋公园</a> <a href="">交通接驳</a> <a href="">澳门</a> <a href="">塔新濠天地水舞间</a> <a href="">澳门豪华自助 台北101</a> <a href="">台湾美食</a> </dd> </dl> <dl> <dt>国内热门城市</dt> <dd> <a href="">三亚</a> <a href="">东北雪乡</a> <a href="">大理</a> <a href="">丽江</a> <a href="">昆明</a> <a href="">西双版纳</a> <a href="">拉萨</a> <a href="">成都</a> <a href="">重庆</a> <a href="">长白山</a> <a href="">厦门</a> <a href="">长沙</a> <a href="">桂林北京</a> <a href="">西安</a> <a href="">敦煌</a> <a href="">杭州</a> <a href="">上海</a> <a href="">无锡</a> <a href="">南京</a> <a href="">广州</a> <a href="">黄山</a> <a href="">莫干山</a> <a href="">新疆</a> <a href="">北海</a> <a href="">九华山</a> <a href="">太原</a> <a href="">张家口</a> </dd> </dl> <dl> <dt>热门景点</dt> <dd> <a href="">北京故宫</a> <a href="">东北滑雪</a> <a href="">恭王府</a> <a href="">长城</a> <a href="">青城山大熊猫基地</a> <a href="">峨眉山</a> <a href="">都江堰</a> <a href="">长恨歌表演</a> <a href="">兵马俑</a> <a href="">大唐芙蓉园</a> <a href="">三亚日游</a> <a href="">厦门鼓浪屿</a> <a href="">千岛湖</a> <a href="">呼伦贝尔草原</a> <a href="">希拉穆仁草原</a> <a href="">大理日游</a> <a href="">杭州</a> <a href="">重庆两江夜游船票</a> </dd> </dl> </div> <div class="menu" data-t="hk"> <dl> <dt>港澳台</dt> <dd> <a href="#">香港</a> <a href="#">澳门</a> <a href="#">台北</a> <a href="#">高雄</a> <a href="#">香港迪士尼</a> <a href="#">香港海洋公园</a> <a href="#">交通接驳</a> <a href="#">澳门塔</a> <a href="#">新濠天地水舞间</a> <a href="#">澳门豪华自助</a> <a href="#">台北101</a> <a href="#">台湾美食</a> </dd> </dl> </div> <div class="menu" data-t="jp"> <dl> <dt>日本</dt> <dd> <a href="#">东京</a> <a href="#">大阪</a> <a href="#">冲绳</a> <a href="#">北海道</a> <a href="#">札幌</a> <a href="#">京都</a> <a href="#">名古屋</a> <a href="#">福冈</a> <a href="#">长崎</a> <a href="#">鹿儿岛</a> <a href="#">JR</a> <a href="#">Pass</a> <a href="#">米其林餐厅</a> <a href="#">东京迪士尼</a> <a href="#">大阪环球影城</a> <a href="#">冲绳一日游</a> <a href="#">City</a> <a href="#">Walk</a> <a href="#">西瓜卡</a> <a href="#">京都日游</a> <a href="#">和服体验</a> <a href="#">包车服务</a> <a href="#">富士山日游</a> </dd> </dl> </div> <div class="menu" data-t="as"> <dl> <dt>泰新马</dt> <dd> <a href="#">普吉岛</a> <a href="#">清迈</a> <a href="#">曼谷</a> <a href="#">苏梅岛</a> <a href="#">甲米</a> <a href="#">芭堤雅</a> <a href="#">拜县</a> <a href="#">新加坡</a> <a href="#">马来西亚</a> <a href="#">沙巴</a> <a href="#">吉隆坡</a> <a href="#">皇帝岛</a> <a href="#">泰国人妖</a> <a href="#">泰国丛林飞跃</a> <a href="#">泰国spa按摩</a> <a href="#">清迈夜间动物园</a> <a href="#">泰拳表演清莱一日游</a> <a href="#">新加坡环球影城</a> <a href="#">新加坡日游</a> <a href="#">新加坡滨海湾花园</a> <a href="#">沙巴美人鱼岛</a> <a href="#">沙巴红树林萤火虫</a> </dd> </dl> <dl> <dt>东南亚</dt> <dd> <a href="#">巴厘岛</a> <a href="#">长滩岛</a> <a href="#">马尼拉</a> <a href="#">薄荷岛</a> <a href="#">美娜多芽庄</a> <a href="#">岘港</a> <a href="#">富国岛</a> <a href="#">柬埔寨</a> <a href="#">缅甸</a> <a href="#">老挝</a> <a href="#">文莱</a> <a href="#">蓝梦岛</a> <a href="#">巴厘岛SPA</a> <a href="#">网红漂浮下午茶</a> <a href="#">珍珠岛游乐园</a> <a href="#">富国岛浮潜海钓</a> <a href="#">吴哥窟</a> <a href="#">西哈努克</a> </dd> </dl> <dl> <dt>西亚</dt> <dd> <a href="#">马尔代夫</a> <a href="#">斯里兰卡</a> <a href="#">印度</a> <a href="#">尼泊尔</a> <a href="#">格鲁吉亚阿塞拜疆</a> <a href="#">亚美尼亚</a> </dd> </dl> </div> <div class="menu" data-t="eu"> <dl> <dt>欧洲</dt> <dd> <a href="#">法国</a> <a href="#">意大利</a> <a href="#">土耳其</a> <a href="#">俄罗斯</a> <a href="#">西班牙</a> <a href="#">瑞士</a> <a href="#">英国</a> <a href="#">希腊</a> <a href="#">荷兰</a> <a href="#">德国</a> <a href="#">捷克</a> <a href="#">葡萄牙</a> <a href="#">奥地利</a> <a href="#">瑞典</a> <a href="#">丹麦</a> <a href="#">挪威</a> <a href="#">冰岛</a> <a href="#">芬兰</a> <a href="#">罗瓦涅米</a> <a href="#">奥斯陆</a> <a href="#">雷克雅未克</a> <a href="#">因特拉肯</a> <a href="#">巴塞罗那</a> <a href="#">伦敦</a> <a href="#">巴黎</a> <a href="#">塞纳河</a> <a href="#">慕尼黑</a> <a href="#">普罗旺斯</a> <a href="#">温莎日游</a> <a href="#">巴黎迪斯尼</a> <a href="#">伊斯坦布</a> <a href="#">尔阿尔罕布拉宫</a> <a href="#">唐顿庄园</a> <a href="#">埃菲尔铁塔</a> <a href="#">凡尔赛宫</a> <a href="#">北欧破冰船</a> <a href="#">极光之旅</a> <a href="#">英国天空岛</a> </dd> </dl> <dl> <dt>美洲</dt> <dd> <a href="#">美国</a> <a href="#">加拿大</a> <a href="#">墨西哥</a> <a href="#">巴西</a> <a href="#">阿根廷</a> <a href="#">智利</a> <a href="#">秘鲁</a> <a href="#">玻利维亚</a> <a href="#">洛杉矶</a> <a href="#">纽约</a> <a href="#">拉斯维加斯</a> <a href="#">旧金山</a> <a href="#">圣地亚哥芝加哥</a> <a href="#">西雅图</a> <a href="#">华盛顿</a> <a href="#">奥兰多</a> <a href="#">夏威夷</a> <a href="#">塞班岛</a> <a href="#">关岛</a> <a href="#">环球影城</a> <a href="#">迪士尼</a> <a href="#">演出票</a> <a href="#">尼亚加拉大瀑布</a> <a href="#">帝国大厦</a> <a href="#">奥特莱斯</a> <a href="#">黄石国家公园</a> <a href="#">纽约大都会博物馆</a> <a href="#">美国大峡谷西峡</a> <a href="#">拉斯维加斯摩天轮</a> <a href="#">羚羊峡谷</a> <a href="#">马蹄湾</a> </dd> </dl> </div> <div class="menu" data-t="au"> <dl> <dt>澳新 南太平洋</dt> <dd> <a href="#">墨尔本</a> <a href="#">悉尼</a> <a href="#">黄金海岸</a> <a href="#">凯恩斯</a> <a href="#">布里斯班奥克兰</a> <a href="#">斐济</a> <a href="#">珀斯</a> <a href="#">圣灵群岛</a> <a href="#">大堡礁</a> <a href="#">墨尔本之星</a> <a href="#">悉尼热气球</a> <a href="#">水上飞机</a> <a href="#">海港大桥</a> <a href="#">皇后镇霍比特人村</a> <a href="#">怀托莫萤火虫洞</a> <a href="#">米尔福德峡湾</a> <a href="#">新西兰滑雪</a> <a href="#">瓦纳卡</a> <a href="#"></a> </dd> </dl> <dl> <dt>中东非</dt> <dd> <a href="#">迪拜</a> <a href="#">摩洛哥</a> <a href="#">毛里求斯</a> <a href="#">埃及</a> <a href="#">塞舌尔</a> <a href="#">马达加斯加</a> <a href="#">以色列</a> <a href="#">肯尼亚</a> <a href="#">南非</a> <a href="#">伊朗</a> <a href="#">约旦</a> <a href="#">突尼斯</a> <a href="#">迪拜</a> <a href="#">塔法拉利主题公园</a> <a href="#">迪拜七星帆船酒店用餐</a> <a href="#">夜游迪拜河</a> <a href="#">亚特兰蒂斯水上乐园</a> <a href="#">动物大迁徙</a> <a href="#">撒哈拉沙漠</a> <a href="#">金字塔</a> <a href="#">纳米比亚</a> <a href="#"></a> </dd> </dl> </div> </div> </nav> </div> </section>
/* banner */
.banner {
position: relative;
overflow: hidden;
}
.banner .carousel-list {
width: 600%;
overflow: hidden;
transition: transform .5s ease 0s;
}
.banner .carousel-list li {
float: left;
width: 16.666%;
}
.banner .carousel-list li img {
width: 100%;
vertical-align: middle;
}
.banner .center-wrap {
position: absolute;
top: 0;
width: 1152px;
left: 50%;
margin-left: -576px;
height: 100%;
/* background-color: gold; */
}
.banner .center-wrap .banner-nav {
height: 100%;
}
.banner .center-wrap .banner-nav>ul {
height: 100%;
}
.banner .center-wrap .banner-nav>ul>li {
height: 16.66%;
width: 296px;
background-color: rgba(0, 0, 0, 0.5);
border-bottom: 1px solid #9E9E9E;
box-sizing: border-box;
}
.banner .center-wrap .banner-nav>ul>li:last-child {
border-bottom: none;
}
.banner .center-wrap .btn {
position: absolute;
width: 28px;
height: 44px;
top: 50%;
margin-top: -22px;
background: url(../images/icons.png) no-repeat;
opacity: 1;
transition: opacity .2s linear 0s;
}
.banner .center-wrap .leftbtn {
left: -38px;
background-position: -21px -94px;
}
.banner .center-wrap .rightbtn {
right: -38px;
background-position: -21px -29px;
}
.banner .center-wrap .leftbtn:hover,
.banner .center-wrap .rightbtn:hover {
opacity: .5;
}
.banner .center-wrap .banner-nav {
width: 652px;
height: 100%;
position: relative;
}
.banner .center-wrap .banner-nav>ul>li {
position: relative;
}
.banner .center-wrap .banner-nav>ul>li>dl {
position: absolute;
height: 48px;
top: 50%;
left: 42px;
margin-top: -24px;
color: #fff;
}
.banner .center-wrap .banner-nav>ul>li dl dt {
font-size: 18px;
height: 26px;
line-height: 26px;
}
.banner .center-wrap .banner-nav ul li dl dd {
font-size: 14px;
height: 22px;
line-height: 22px;
}
.banner .center-wrap .banner-nav ul li::before {
content: '';
position: absolute;
background-image: url(../images//icons.png);
top: 50%;
left: 10px;
}
.banner .center-wrap .banner-nav ul li.hot::before {
width: 22px;
height: 18px;
background-position: -29px -399px;
margin-top: -9px;
}
.banner .center-wrap .banner-nav ul li.hot::before {
width: 22px;
height: 18px;
background-position: -29px -399px;
margin-top: -9px;
}
.banner .center-wrap .banner-nav>ul>li.hk::before {
width: 18px;
height: 21px;
background-position: -28px -217px;
margin-top: -10.5px;
}
.banner .center-wrap .banner-nav>ul>li.jp::before {
width: 24px;
height: 19px;
background-position: -25px -171px;
margin-top: -9.5px;
}
.banner .center-wrap .banner-nav>ul>li.as::before {
width: 18px;
height: 19px;
background-position: -28px -262px;
margin-top: -9.5px;
}
.banner .center-wrap .banner-nav>ul>li.eu::before {
width: 20px;
height: 14px;
background-position: -29px -351px;
margin-top: -7px;
}
.banner .center-wrap .banner-nav>ul>li.au::before {
width: 18px;
height: 17px;
background-position: -28px -305px;
margin-top: -8.5px;
}
.banner .center-wrap .banner-nav>ul>li.current {
background-color: rgba(0, 0, 0, 0.6);
}
.banner .center-wrap .banner-nav .menus-box .menu {
position: absolute;
left: 296px;
top: 0;
width: 356px;
height: 100%;
background-color: rgba(0, 0, 0, 0.6);
color: #fff;
padding: 16px;
box-sizing: border-box;
display: none;
z-index: 9999;
}
.banner .center-wrap .banner-nav .menus-box .menu.current {
display: block;
}
.banner .center-wrap .banner-nav .menus-box .menu a {
color: #fff;
}
.banner .center-wrap .banner-nav .menus-box .menu dl {
margin-bottom: 20px;
}
.banner .center-wrap .banner-nav .menus-box .menu dl dt {
line-height: 30px;
font-size: 18px;
}
.banner .center-wrap .banner-nav .menus-box .menu dl dd {
line-height: 25px;
font-size: 15px;
}
.banner .circles {
position: absolute;
width: 160px;
height: 20px;
bottom: 10px;
left: 50%;
margin-left: -75px;
z-index: 999;
}
.banner .circles li {
width: 20px;
height: 20px;
float: left;
background-color: #83d8c6;
margin-right: 10px;
border-radius: 10px;
cursor: pointer;
transition: all .5s ease 0s;
}
.banner .circles li:last-child {
margin-right: 0;
}
.banner .circles li.current {
width: 40px;
background-color: #20BD9A;
}轮播图我用的也是DOM2级也没事呢
/**
* 轮播图特效
* 2023-7-14
* 清夏
*/
(function () {
var carousel_list = document.getElementById('carousel_list');
var left_btn = document.getElementById('left_btn');
var right_btn = document.getElementById('right_btn');
var circle_ol = document.getElementById('circle_ol');
var banner = document.getElementById('banner');
var circle_lis = circle_ol.getElementsByTagName('li');
var clone_li = carousel_list.firstElementChild.cloneNode(true);
carousel_list.appendChild(clone_li);
var idx = 0; //当前图片的序号
var lock = true; //节流锁
// 右按钮监听
right_btn.addEventListener('click', right_btn_handler, true);
function right_btn_handler() {
if (!lock) return;
lock = false;
carousel_list.style.transition = 'transform .5s ease 0s';
idx++;
carousel_list.style.transform = 'transLateX(' + -16.66 * idx + '%)';
if (idx > 4) {
setTimeout(function () {
carousel_list.style.transition = 'none';
carousel_list.style.transform = 'none';
idx = 0;
}, 500);
}
setCircles(); //设置小圆点
setTimeout(function () {
lock = true;
}, 500);
}
// 左按钮监听
left_btn.addEventListener('click', function () {
if (!lock) return;
lock = false;
if (idx == 0) {
carousel_list.style.transition = 'none';
carousel_list.style.transform = 'transLateX(' + -16.66 * 5 + '%)';
idx = 4;
setTimeout(function () {
carousel_list.style.transition = 'transform .5s ease 0s';
carousel_list.style.transform = 'transLateX(' + -16.66 * 4 + '%)';
}, 0);
} else {
idx--;
carousel_list.style.transform = 'transLateX(' + -16.66 * idx + '%)';
}
setCircles(); //设置小圆点
setTimeout(function () {
lock = true;
}, 500);
}, true);
// 点击按钮,小圆点能变化
function setCircles() {
for (var i = 0; i <= 4; i++) {
if (i == idx % 5) {
circle_lis[i].className = 'current';
} else {
circle_lis[i].className = '';
}
}
}
// 点击小圆点,轮播图能进行切换
circle_ol.addEventListener('click', function (e) {
if (e.target.tagName.toLowerCase() == 'li') {
var n = Number(e.target.getAttribute('data-n'));
idx = n;
carousel_list.style.transform = 'transLateX(' + -16.66 * idx + '%)';
setCircles();
}
}, true);
// 自动轮播
var timer = setInterval(right_btn_handler, 2000);
// 鼠标进入轮播暂停
banner.addEventListener('mouseenter', function () {
clearInterval(timer);
}, true);
// 鼠标离开轮播继续
banner.addEventListener('mouseleave', function () {
clearInterval(timer);
timer = setInterval(right_btn_handler, 2000);
}, true);
})();正在回答
同学你好,解答如下:
1、“0级是冒泡,从里往外走。2级是捕获,从外往里”这句话,理解有误。
dom0级的事件,也不全是冒泡。个别事件是不支持事件冒泡的,比如onmouseleave。
dom2级也不全是捕获,可以根据参数,使用捕获或者冒泡:

同学的问题,不用想的那么复杂,不用想什么冒泡、捕获,就分析代码就行。
2、按照我的理解,同学的代码中,如下写法是一对:

3、如下写法,一旦去掉了如下代码,一级菜单current类名没法切换:

是因为onmouseleave事件特殊,它只在“移出目标元素时,才会触发”。代码中,banner_nav元素绑定了该事件,那么只有鼠标移出banner_nav时,才会触发onmouseleave事件,从banner_nav的子元素移出,并不会触发该事件。
所以,鼠标从某一个一级菜单,移入另一个一级菜单,并不会触发banner_nav的onmouseleave方法,也就是说,onmouseleave中的banner_lis[i].className = banner_lis[i].getAttribute('data-t')这句代码,并不会执行,current类名无法去掉。
所以此种写法中,需要在 banner_nav_ul.onmouseover中,移除其他一级菜单的curent类名。
祝学习愉快!
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星