123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- /**
- * 下拉菜单模块
- * date:2019-07-12 License By http://easyweb.vip
- */
- layui.define(['jquery'], function (exports) {
- var $ = layui.jquery;
- var openClass = 'dropdown-open';
- var disableClass = 'dropdown-disabled';
- var noScrollClass = 'dropdown-no-scroll';
- var shadeClass = 'dropdown-menu-shade';
- var dropdownClass = 'dropdown-menu';
- var dropNavClass = 'dropdown-menu-nav';
- var hoverClass = 'dropdown-hover';
- var fixedClass = 'fixed';
- var noShadeClass = 'no-shade';
- var animClass = 'layui-anim layui-anim-upbit';
- var dropDirect = ['bottom-left', 'bottom-right', 'bottom-center', 'top-left', 'top-right', 'top-center', 'left-top', 'left-bottom', 'left-center', 'right-top', 'right-bottom', 'right-center'];
- layui.link(layui.cache.base + 'dropdown/dropdown.css');
- var dropdown = {
- // 绑定事件
- init: function () {
- // 点击触发
- $(document).off('click.dropdown').on('click.dropdown', '.' + dropdownClass + '>*:first-child', function (event) {
- var $drop = $(this).parent();
- if (!$drop.hasClass(hoverClass)) {
- if ($drop.hasClass(openClass)) {
- $drop.removeClass(openClass);
- } else {
- dropdown.show($(this).parent().find('.' + dropNavClass));
- }
- }
- event.stopPropagation();
- });
- // 点击任何位置关闭所有
- $(document).off('click.dropHide').on('click.dropHide', function (event) {
- dropdown.hideAll();
- });
- // 点击下拉菜单内容部分不关闭
- $(document).off('click.dropNav').on('click.dropNav', '.' + dropNavClass, function (event) {
- event.stopPropagation();
- });
- // hover触发
- var timer, lastDrop;
- $(document).off('mouseenter.dropdown').on('mouseenter.dropdown', '.' + dropdownClass + '.' + hoverClass, function (event) {
- if (lastDrop && lastDrop == event.currentTarget) {
- clearTimeout(timer);
- }
- dropdown.show($(this).find('.' + dropNavClass));
- });
- $(document).off('mouseleave.dropdown').on('mouseleave.dropdown', '.' + dropdownClass + '.' + hoverClass, function (event) {
- lastDrop = event.currentTarget;
- timer = setTimeout(function () {
- $(event.currentTarget).removeClass(openClass);
- }, 300);
- });
- // 分离式绑定
- $(document).off('click.dropStand').on('click.dropStand', '[data-dropdown]', function (event) {
- dropdown.showFixed($(this));
- event.stopPropagation();
- });
- },
- // 点击菜单关闭
- openClickNavClose: function () {
- $(document).off('click.dropNavA').on('click.dropNavA', '.' + dropNavClass + '>li>a', function (event) {
- dropdown.hideAll();
- $(this).parentsUntil('.' + dropdownClass).parent().removeClass(openClass);
- event.stopPropagation();
- });
- },
- // 关闭所有
- hideAll: function () {
- $('.' + dropdownClass).removeClass(openClass);
- // 隐藏分离式菜单
- $('.' + dropNavClass + '.' + fixedClass).addClass('layui-hide'); // 隐藏分离式菜单
- $('.' + shadeClass).remove(); // 移除遮罩层
- $('body').removeClass(noScrollClass); // 移除禁止页面滚动
- $('.dropdown-fixParent').removeClass('dropdown-fixParent');
- $('[data-dropdown]').removeClass(openClass);
- },
- // 展开非分离式下拉菜单
- show: function ($dropNav) {
- if ($dropNav && $dropNav.length > 0 && !$dropNav.hasClass(disableClass)) {
- $dropNav.addClass(animClass);
- var position; // 获取位置
- for (var i = 0; i < dropDirect.length; i++) {
- if ($dropNav.hasClass('dropdown-' + dropDirect[i])) {
- position = dropDirect[i];
- break;
- }
- }
- if (!position) { // 没有设置位置添加默认位置
- $dropNav.addClass('dropdown-' + dropDirect[0]);
- position = dropDirect[0];
- }
- dropdown.forCenter($dropNav, position);
- $dropNav.parent('.' + dropdownClass).addClass(openClass);
- return position;
- }
- return false;
- },
- // 展开分离式菜单
- showFixed: function ($trigger) {
- var $dropNav = $($trigger.data('dropdown')), position;
- if (!$dropNav.hasClass('layui-hide')) {
- dropdown.hideAll(); // 已经展开则隐藏
- return;
- }
- position = dropdown.show($dropNav); // 获取弹出位置
- if (position) {
- $dropNav.addClass(fixedClass); // 设置为固定定位
- $dropNav.removeClass('layui-hide'); // 显示下拉菜单
- var topLeft = dropdown.getTopLeft($trigger, $dropNav, position); // 计算坐标
- topLeft = dropdown.checkPosition($dropNav, $trigger, position, topLeft); // 是否溢出屏幕
- $dropNav.css(topLeft); // 设置坐标
- $('body').addClass(noScrollClass); // 禁止页面滚动
- var hideShade = ($trigger.attr('no-shade') == 'true'); // 是否隐藏遮罩层
- $('body').append('<div class="' + (hideShade ? (shadeClass + ' ' + noShadeClass) : shadeClass) + ' layui-anim layui-anim-fadein"></div>'); // 添加遮罩层
- // 重置父元素z-index
- $trigger.parentsUntil('body').each(function () {
- var zIndex = $(this).css('z-index');
- if (/[0-9]+/.test(zIndex)) {
- $(this).addClass('dropdown-fixParent');
- }
- });
- $trigger.addClass(openClass);
- }
- },
- // 解决绝对定位因动画导致平移失效
- forCenter: function ($dropNav, position) {
- if (!$dropNav.hasClass(fixedClass)) {
- var wTrigger = $dropNav.parent().outerWidth(), hTrigger = $dropNav.parent().outerHeight();
- var wDrop = $dropNav.outerWidth(), hDrop = $dropNav.outerHeight();
- var pParts = position.split('-'), dropSide = pParts[0], dropPosition = pParts[1]; // 显示方向
- if ((dropSide == 'top' || dropSide == 'bottom') && dropPosition == 'center') {
- $dropNav.css('left', (wTrigger - wDrop) / 2);
- }
- if ((dropSide == 'left' || dropSide == 'right') && dropPosition == 'center') {
- $dropNav.css('top', (hTrigger - hDrop) / 2);
- }
- }
- },
- // 计算固定定位坐标
- getTopLeft: function ($trigger, $dropdown, position) {
- var widthTrigger = $trigger.outerWidth();
- var heightTrigger = $trigger.outerHeight();
- var widthDropdown = $dropdown.outerWidth();
- var heightDropdown = $dropdown.outerHeight();
- var topTrigger = $trigger.offset().top - $(document).scrollTop();
- var leftTrigger = $trigger.offset().left;
- var rightTrigger = leftTrigger + widthTrigger;
- var top = 0, left = 0;
- var positionParts = position.split('-');
- var anchorSide = positionParts[0]; // 箭头位置
- var anchorPosition = positionParts[1]; // 箭头方向
- if (anchorSide == 'top' || anchorSide == 'bottom') {
- heightDropdown += 8; // 加上margin距离
- switch (anchorPosition) {
- case 'left':
- left = leftTrigger;
- break;
- case 'center':
- left = leftTrigger - widthDropdown / 2 + widthTrigger / 2;
- break;
- case 'right':
- left = rightTrigger - widthDropdown;
- }
- }
- if (anchorSide == 'left' || anchorSide == 'right') {
- widthDropdown += 8; // 加上margin距离
- switch (anchorPosition) {
- case 'top':
- top = topTrigger + heightTrigger - heightDropdown;
- break;
- case 'center':
- top = topTrigger - heightDropdown / 2 + heightTrigger / 2;
- break;
- case 'bottom':
- top = topTrigger;
- }
- }
- switch (anchorSide) {
- case 'top':
- top = topTrigger - heightDropdown;
- break;
- case 'right':
- left = leftTrigger + widthTrigger;
- break;
- case 'bottom':
- top = topTrigger + heightTrigger;
- break;
- case 'left':
- left = leftTrigger - widthDropdown;
- }
- return {top: top, left: left, right: 'auto', bottom: 'auto'};
- },
- // 检查是否溢出屏幕
- checkPosition: function ($dropNav, $trigger, position, topLeft) {
- var aps = position.split('-');
- if ('bottom' == aps[0]) {
- if ((topLeft.top + $dropNav.outerHeight()) > dropdown.getPageHeight()) {
- topLeft = dropdown.getTopLeft($trigger, $dropNav, 'top-' + aps[1]);
- $dropNav.removeClass('dropdown-' + position);
- $dropNav.addClass('dropdown-top-' + aps[1]);
- }
- } else if ('top' == aps[0]) {
- if (topLeft.top < 0) {
- topLeft = dropdown.getTopLeft($trigger, $dropNav, 'bottom-' + aps[1]);
- $dropNav.removeClass('dropdown-' + position);
- $dropNav.addClass('dropdown-bottom-' + aps[1]);
- }
- }
- return topLeft;
- },
- // 获取浏览器高度
- getPageHeight: function () {
- return document.documentElement.clientHeight || document.body.clientHeight;
- },
- // 获取浏览器宽度
- getPageWidth: function () {
- return document.documentElement.clientWidth || document.body.clientWidth;
- }
- };
- dropdown.init();
- exports('dropdown', dropdown);
- });
|