diff --git a/examples/element.nav.html b/examples/element.nav.html index 87b27563..65786c0f 100644 --- a/examples/element.nav.html +++ b/examples/element.nav.html @@ -127,103 +127,94 @@
- -
- -
- -
diff --git a/src/css/layui.css b/src/css/layui.css index a535ca55..3b083e6c 100644 --- a/src/css/layui.css +++ b/src/css/layui.css @@ -1285,7 +1285,6 @@ body .layui-table-tips .layui-layer-content{background: none; padding: 0; box-sh .layui-nav .layui-nav-more{position: absolute; top: 0; right: 3px; left: auto !important; margin-top: 0; font-size: 12px; cursor: pointer; transition: all .2s; -webkit-transition: all .2s;} .layui-nav .layui-nav-mored, -.layui-nav-expand > a .layui-nav-more, .layui-nav-itemed > a .layui-nav-more{transform: rotate(180deg);} @@ -1333,12 +1332,9 @@ body .layui-table-tips .layui-layer-content{background: none; padding: 0; box-sh /* 导航浅色背景 */ .layui-nav.layui-bg-gray .layui-nav-item a, .layui-nav-tree.layui-bg-gray a{color: #373737; color: rgba(0,0,0,.8);} -.layui-nav-tree.layui-bg-gray{padding: 6px 0;} .layui-nav-tree.layui-bg-gray .layui-nav-itemed>a{color: #000 !important;} .layui-nav.layui-bg-gray .layui-this a{color: #16b777;} .layui-nav-tree.layui-bg-gray .layui-nav-child{padding-left: 11px; background: none;} -.layui-nav-tree.layui-bg-gray .layui-nav-item>a{padding-top: 0; padding-bottom: 0;} -.layui-nav-tree.layui-bg-gray .layui-nav-item>a .layui-nav-more{padding: 0;} .layui-nav-tree.layui-bg-gray .layui-this, .layui-nav-tree.layui-bg-gray .layui-this>a, .layui-nav-tree.layui-bg-gray .layui-nav-child dd.layui-this, diff --git a/src/modules/element.js b/src/modules/element.js index f9617204..631f6752 100644 --- a/src/modules/element.js +++ b/src/modules/element.js @@ -273,45 +273,62 @@ layui.define('jquery', function(exports){ */ // 点击菜单 - a 标签触发 - ,clickThis: function(){ + ,clickThis: function() { var othis = $(this); - var parents = othis.parents(NAV_ELEM); + var parents = othis.closest(NAV_ELEM); var filter = parents.attr('lay-filter'); var parent = othis.parent() ; - var child = othis.siblings('.'+NAV_CHILD); + var child = othis.siblings('.'+ NAV_CHILD); var unselect = typeof parent.attr('lay-unselect') === 'string'; // 是否禁用选中 - if(!(othis.attr('href') !== 'javascript:;' && othis.attr('target') === '_blank') && !unselect){ - if(!child[0]){ - parents.find('.'+THIS).removeClass(THIS); + // 满足点击选中的条件 + if (!(othis.attr('href') !== 'javascript:;' && othis.attr('target') === '_blank') && !unselect) { + if (!child[0]) { + parents.find('.'+ THIS).removeClass(THIS); parent.addClass(THIS); } } // 若为垂直菜单 if (parents.hasClass(NAV_TREE)) { - var NAV_ITEMED = NAV_ITEM + 'ed'; - var NAV_EXPAND = 'layui-nav-expand'; - var needExpand = !(parent.hasClass(NAV_EXPAND) || parent.hasClass(NAV_ITEMED)); + var NAV_ITEMED = NAV_ITEM + 'ed'; // 用于标注展开状态 + var needExpand = !parent.hasClass(NAV_ITEMED); // 是否执行展开 + var ANIM_MS = 200; // 动画过渡毫秒数 + + // 动画执行完成后的操作 + var complete = function() { + $(this).css({ + "display": "" // 剔除动画生成的 style display,以适配外部样式的状态重置 + }); + // 避免导航滑块错位 + parents.children('.'+ NAV_BAR).css({ + opacity: 0 + }) + }; // 是否正处于动画中的状态 if (child.is(':animated')) return; + // 剔除可能存在的 CSS3 动画类 child.removeClass(NAV_ANIM); - // 若有子菜单,则展开 + // 若有子菜单,则对其执行展开或收缩 if (child[0]) { - child.stop().slideToggle(200, function() { - needExpand || parent.removeClass(NAV_ITEMED); - }); - parent[needExpand ? 'addClass': 'removeClass'](NAV_EXPAND); - // 手风琴 - if(typeof parents.attr('lay-accordion') === 'string' || parents.attr('lay-shrink') === 'all'){ - // 收缩兄弟项 - parent.siblings().removeClass([ - NAV_ITEMED, - NAV_EXPAND - ].join(' ')).children('.'+NAV_CHILD).stop().slideUp(200); + if (needExpand) { + // 先执行 slideDown 动画,再标注展开状态样式,避免元素 `block` 状态导致动画无效 + child.slideDown(ANIM_MS, complete); + parent.addClass(NAV_ITEMED); + } else { + // 先取消展开状态样式,再将元素临时显示,避免 `none` 状态导致 slideUp 动画无效 + parent.removeClass(NAV_ITEMED); + child.show().slideUp(ANIM_MS, complete); + } + + // 手风琴 --- 收缩兄弟展开项 + if (typeof parents.attr('lay-accordion') === 'string' || parents.attr('lay-shrink') === 'all') { + var parentSibs = parent.siblings('.'+ NAV_ITEMED); + parentSibs.removeClass(NAV_ITEMED); + parentSibs.children('.'+ NAV_CHILD).show().stop().slideUp(ANIM_MS, complete); } } } @@ -357,56 +374,65 @@ layui.define('jquery', function(exports){ call.tabAuto.call({}); } - //导航菜单 + // 导航菜单 ,nav: function(){ - var TIME = 200, timer = {}, timerMore = {}, timeEnd = {}, NAV_TITLE = 'layui-nav-title' + var TIME = 200; + var timer = {}; + var timerMore = {}; + var timeEnd = {}; + var NAV_TITLE = 'layui-nav-title'; - //滑块跟随 - ,follow = function(bar, nav, index){ - var othis = $(this), child = othis.find('.'+NAV_CHILD); - if(nav.hasClass(NAV_TREE)){ - //无子菜单时跟随 - if(!child[0]){ + // 滑块跟随 + var follow = function(bar, nav, index) { + var othis = $(this); + var child = othis.find('.'+NAV_CHILD); + + // 是否垂直导航菜单 + if (nav.hasClass(NAV_TREE)) { + // 无子菜单时跟随 + if (!child[0]) { var thisA = othis.children('.'+ NAV_TITLE); bar.css({ - top: othis.offset().top - nav.offset().top - ,height: (thisA[0] ? thisA : othis).outerHeight() - ,opacity: 1 + top: othis.offset().top - nav.offset().top, + height: (thisA[0] ? thisA : othis).outerHeight(), + opacity: 1 }); } } else { child.addClass(NAV_ANIM); - //若居中对齐 - if(child.hasClass(NAV_CHILD_C)) child.css({ - left: -(child.outerWidth() - othis.width())/2 - }); - - //滑块定位 - if(child[0]){ //若有子菜单,则滑块消失 - bar.css({ - left: bar.position().left + bar.width()/2 - ,width: 0 - ,opacity: 0 - }); - } else { //bar 跟随 - bar.css({ - left: othis.position().left + parseFloat(othis.css('marginLeft')) - ,top: othis.position().top + othis.height() - bar.height() + // 若居中对齐 + if (child.hasClass(NAV_CHILD_C)) { + child.css({ + left: -(child.outerWidth() - othis.width()) / 2 }); } - //渐显滑块并适配宽度 - timer[index] = setTimeout(function(){ + // 滑块定位 + if (child[0]) { // 若有子菜单,则滑块消失 bar.css({ - width: child[0] ? 0 : othis.width() - ,opacity: child[0] ? 0 : 1 + left: bar.position().left + bar.width() / 2, + width: 0, + opacity: 0 + }); + } else { // bar 跟随 + bar.css({ + left: othis.position().left + parseFloat(othis.css('marginLeft')), + top: othis.position().top + othis.height() - bar.height() + }); + } + + // 渐显滑块并适配宽度 + timer[index] = setTimeout(function() { + bar.css({ + width: child[0] ? 0 : othis.width(), + opacity: child[0] ? 0 : 1 }); }, device.ie && device.ie < 10 ? 0 : TIME); - //显示子菜单 + // 显示子菜单 clearTimeout(timeEnd[index]); - if(child.css('display') === 'block'){ + if (child.css('display') === 'block') { clearTimeout(timerMore[index]); } timerMore[index] = setTimeout(function(){ @@ -416,61 +442,64 @@ layui.define('jquery', function(exports){ } }; - //遍历导航 - $(NAV_ELEM + elemFilter).each(function(index){ - var othis = $(this) - ,bar = $('') - ,itemElem = othis.find('.'+NAV_ITEM); + // 遍历导航 + $(NAV_ELEM + elemFilter).each(function(index) { + var othis = $(this); + var bar = $(''); + var itemElem = othis.find('.'+NAV_ITEM); - //hover 滑动效果 - if(!othis.find('.'+NAV_BAR)[0]){ + // hover 滑动效果 + if (!othis.find('.'+NAV_BAR)[0]) { othis.append(bar); - (othis.hasClass(NAV_TREE) + ( othis.hasClass(NAV_TREE) ? itemElem.find('dd,>.'+ NAV_TITLE) - : itemElem).on('mouseenter', function(){ + : itemElem + ).on('mouseenter', function() { follow.call(this, bar, othis, index); - }).on('mouseleave', function(){ //鼠标移出 - //是否为垂直导航 - if(othis.hasClass(NAV_TREE)){ + }).on('mouseleave', function() { // 鼠标移出 + // 是否为垂直导航 + if (othis.hasClass(NAV_TREE)) { bar.css({ - height: 0 - ,opacity: 0 + height: 0, + opacity: 0 }); } else { - //隐藏子菜单 + // 隐藏子菜单 clearTimeout(timerMore[index]); timerMore[index] = setTimeout(function(){ - othis.find('.'+NAV_CHILD).removeClass(SHOW); - othis.find('.'+NAV_MORE).removeClass(NAV_MORE+'d'); + othis.find('.'+ NAV_CHILD).removeClass(SHOW); + othis.find('.'+ NAV_MORE).removeClass(NAV_MORE +'d'); }, 300); } }); - othis.on('mouseleave', function(){ + + // 鼠标离开当前菜单时 + othis.on('mouseleave', function() { clearTimeout(timer[index]) - timeEnd[index] = setTimeout(function(){ - if(!othis.hasClass(NAV_TREE)){ + timeEnd[index] = setTimeout(function() { + if (!othis.hasClass(NAV_TREE)) { bar.css({ - width: 0 - ,left: bar.position().left + bar.width()/2 - ,opacity: 0 + width: 0, + left: bar.position().left + bar.width() / 2, + opacity: 0 }); } }, TIME); }); } - //展开子菜单 - itemElem.find('a').each(function(){ - var thisA = $(this) - ,parent = thisA.parent() - ,child = thisA.siblings('.'+NAV_CHILD); + // 展开子菜单 + itemElem.find('a').each(function() { + var thisA = $(this); + var parent = thisA.parent(); + var child = thisA.siblings('.'+ NAV_CHILD); - //输出小箭头 - if(child[0] && !thisA.children('.'+NAV_MORE)[0]){ + // 输出小箭头 + if (child[0] && !thisA.children('.'+ NAV_MORE)[0]) { thisA.append(''); } - thisA.off('click', call.clickThis).on('click', call.clickThis); //点击菜单 + thisA.off('click', call.clickThis).on('click', call.clickThis); // 点击菜单 }); }); }