垂直菜单
问题:
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、按照我的理解,同学的代码中,如下写法是一对:
此时,在mouseover事件中,虽然没给一级菜单去掉current类名,但是鼠标移出某个一级菜单时,会触发banner_nav的mouseleave事件。该事件处理函数中,去掉了一级菜单的current类名:所以,一级菜单能切换current类名。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 星