Initial project files: BESCMS full source
This commit is contained in:
@@ -0,0 +1,272 @@
|
||||
/**
|
||||
* 用户中心前台脚本:侧栏(移动/桌面)、菜单折叠、回顶等
|
||||
* 依赖:jQuery(在 mheader 中先于本文件加载)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Metronic 全局 `App` 的兜底(部分模块模板内联脚本会写:
|
||||
* if (App.isAngularJsApp() === false) { ... 初始化 datepicker 等 }
|
||||
* 未引入 `app.min.js` / `layout.js` 时 `App` 不存在会抛 ReferenceError)
|
||||
*
|
||||
* 官方语义(与 Rw layout.js 一致):是否已加载 AngularJS——
|
||||
* `typeof angular !== 'undefined'` 为 true 则认为当前是 Angular 应用页;
|
||||
* 会员中心一般为 false,走 jQuery 插件初始化分支。
|
||||
*
|
||||
* `isRTL()`:与 Metronic 一致,表示是否 RTL 布局(一般看 body 的 CSS direction / dir)。
|
||||
* `getViewPort` / `getResponsiveBreakpoint`:部分插件会调用,缺省时给最小实现以免连环报错。
|
||||
*/
|
||||
(function (w) {
|
||||
var $ = w.jQuery;
|
||||
|
||||
if (typeof w.App === 'undefined') {
|
||||
w.App = {};
|
||||
}
|
||||
|
||||
if (typeof w.App.isAngularJsApp !== 'function') {
|
||||
w.App.isAngularJsApp = function () {
|
||||
return typeof w.angular !== 'undefined';
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof w.App.isRTL !== 'function') {
|
||||
w.App.isRTL = function () {
|
||||
try {
|
||||
if ($ && $.fn && $('body').length) {
|
||||
return $('body').css('direction') === 'rtl';
|
||||
}
|
||||
} catch (e) {}
|
||||
var doc = w.document;
|
||||
if (!doc) {
|
||||
return false;
|
||||
}
|
||||
var de = doc.documentElement;
|
||||
var b = doc.body;
|
||||
var dir = (de && de.getAttribute('dir')) || (b && b.getAttribute('dir')) || '';
|
||||
return String(dir).toLowerCase() === 'rtl';
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof w.App.getViewPort !== 'function') {
|
||||
w.App.getViewPort = function () {
|
||||
var e = w;
|
||||
var a = 'inner';
|
||||
if (!('innerWidth' in w)) {
|
||||
a = 'client';
|
||||
e = w.document.documentElement || w.document.body;
|
||||
}
|
||||
return {
|
||||
width: e[a + 'Width'],
|
||||
height: e[a + 'Height']
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof w.App.getResponsiveBreakpoint !== 'function') {
|
||||
w.App.getResponsiveBreakpoint = function (size) {
|
||||
var sizes = { xs: 480, sm: 768, md: 992, lg: 1200 };
|
||||
return sizes[size] ? sizes[size] : 0;
|
||||
};
|
||||
}
|
||||
})(window);
|
||||
|
||||
(function ($, window, document) {
|
||||
'use strict';
|
||||
|
||||
var NS = 'mcMember';
|
||||
var BREAKPOINT_MOBILE = 991;
|
||||
var STORAGE_NARROW = 'mc_sidebar_narrow';
|
||||
|
||||
function isMobileViewport() {
|
||||
return window.matchMedia('(max-width: ' + BREAKPOINT_MOBILE + 'px)').matches;
|
||||
}
|
||||
|
||||
function openMobileSidebar() {
|
||||
$('body').addClass('mc-sidebar-mobile-open');
|
||||
$('.page-sidebar.navbar-collapse').addClass('in');
|
||||
}
|
||||
|
||||
function closeMobileSidebar() {
|
||||
$('body').removeClass('mc-sidebar-mobile-open');
|
||||
$('.page-sidebar.navbar-collapse').removeClass('in show');
|
||||
}
|
||||
|
||||
function toggleMobileSidebar() {
|
||||
if ($('body').hasClass('mc-sidebar-mobile-open')) {
|
||||
closeMobileSidebar();
|
||||
} else {
|
||||
openMobileSidebar();
|
||||
}
|
||||
}
|
||||
|
||||
/** 顶栏「汉堡」:移动端抽屉侧栏 */
|
||||
function bindResponsiveToggler() {
|
||||
$(document).on('click.' + NS, '.responsive-toggler', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
toggleMobileSidebar();
|
||||
});
|
||||
}
|
||||
|
||||
/** 点击主区域或遮罩关闭移动端侧栏 */
|
||||
function bindOutsideClose() {
|
||||
$(document).on('click.' + NS, function (e) {
|
||||
if (!isMobileViewport()) {
|
||||
return;
|
||||
}
|
||||
if (!$('body').hasClass('mc-sidebar-mobile-open')) {
|
||||
return;
|
||||
}
|
||||
var $t = $(e.target);
|
||||
if ($t.closest('.page-sidebar-wrapper').length) {
|
||||
return;
|
||||
}
|
||||
if ($t.closest('.responsive-toggler').length) {
|
||||
return;
|
||||
}
|
||||
/* 顶栏内操作(通知、用户菜单)不关闭侧栏 */
|
||||
if ($t.closest('.page-header').length) {
|
||||
return;
|
||||
}
|
||||
closeMobileSidebar();
|
||||
});
|
||||
}
|
||||
|
||||
function bindEscape() {
|
||||
$(document).on('keydown.' + NS, function (e) {
|
||||
if (e.keyCode !== 27) {
|
||||
return;
|
||||
}
|
||||
if ($('body').hasClass('mc-sidebar-mobile-open')) {
|
||||
closeMobileSidebar();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** 窗口变大时收起移动侧栏,避免状态错乱 */
|
||||
function bindResize() {
|
||||
var mq = window.matchMedia('(max-width: ' + BREAKPOINT_MOBILE + 'px)');
|
||||
function onChange() {
|
||||
if (!mq.matches) {
|
||||
closeMobileSidebar();
|
||||
}
|
||||
}
|
||||
if (mq.addEventListener) {
|
||||
mq.addEventListener('change', onChange);
|
||||
} else if (mq.addListener) {
|
||||
mq.addListener(onChange);
|
||||
}
|
||||
}
|
||||
|
||||
/** 桌面侧栏折叠(窄栏图标模式),状态写入 localStorage */
|
||||
function bindDesktopSidebarToggler() {
|
||||
try {
|
||||
if (window.localStorage && window.localStorage.getItem(STORAGE_NARROW) === '1') {
|
||||
$('body').addClass('mc-sidebar-narrow');
|
||||
}
|
||||
} catch (err) {}
|
||||
|
||||
$(document).on('click.' + NS, '.menu-toggler.sidebar-toggler', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (isMobileViewport()) {
|
||||
return;
|
||||
}
|
||||
$('body').toggleClass('mc-sidebar-narrow');
|
||||
try {
|
||||
if (window.localStorage) {
|
||||
window.localStorage.setItem(
|
||||
STORAGE_NARROW,
|
||||
$('body').hasClass('mc-sidebar-narrow') ? '1' : '0'
|
||||
);
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 一级菜单:带 sub-menu 且链接为 javascript: 时,展开/收起
|
||||
* 同级仅保留一项展开(手风琴)
|
||||
*/
|
||||
function bindSidebarAccordion() {
|
||||
$(document).on('click.' + NS, '.page-sidebar-menu > .nav-item > .nav-link.nav-toggle', function (e) {
|
||||
var href = ($(this).attr('href') || '').trim();
|
||||
if (href.indexOf('javascript:') !== 0 && href !== '#') {
|
||||
return;
|
||||
}
|
||||
var $li = $(this).closest('.nav-item');
|
||||
var $sub = $li.children('.sub-menu');
|
||||
if (!$sub.length) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
var willOpen = !$li.hasClass('open');
|
||||
/* 与 Metronic 一致:手风琴只保留一项展开;必须同时去掉 active,
|
||||
否则「用户中心」等由服务端带上 active 的项在切换后仍保持主轨高亮 */
|
||||
$li.siblings('.nav-item').removeClass('open active');
|
||||
$li.toggleClass('open', willOpen);
|
||||
});
|
||||
}
|
||||
|
||||
/** 回顶 */
|
||||
function bindScrollToTop() {
|
||||
$(document).on('click.' + NS, '.page-footer .scroll-to-top, .scroll-to-top', function (e) {
|
||||
e.preventDefault();
|
||||
$('html, body').stop().animate({ scrollTop: 0 }, 360);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 顶栏下拉:移动端阻止冒泡,避免与 document 的 clearMenus / 侧栏遮罩抢事件;
|
||||
* 无 Bootstrap 时作为完整回退。
|
||||
*/
|
||||
function bindHeaderDropdown() {
|
||||
$(document).on('click.' + NS, '.page-header .dropdown-toggle', function (e) {
|
||||
if (isMobileViewport()) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
if (typeof $.fn.dropdown === 'function') {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var $li = $(this).closest('li.dropdown');
|
||||
var open = $li.hasClass('open');
|
||||
$('.page-header .navbar-nav > li').removeClass('open');
|
||||
if (!open) {
|
||||
$li.addClass('open');
|
||||
}
|
||||
});
|
||||
$(document).on('click.' + NS, function (e) {
|
||||
if ($(e.target).closest('.page-header .dropdown').length) {
|
||||
return;
|
||||
}
|
||||
$('.page-header .navbar-nav > li').removeClass('open');
|
||||
});
|
||||
$(document).on('click.' + NS, '.page-header .dropdown-menu', function (e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
}
|
||||
|
||||
function init() {
|
||||
bindResponsiveToggler();
|
||||
bindOutsideClose();
|
||||
bindEscape();
|
||||
bindResize();
|
||||
bindDesktopSidebarToggler();
|
||||
bindSidebarAccordion();
|
||||
bindScrollToTop();
|
||||
bindHeaderDropdown();
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
$(document).ready(init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
|
||||
window.McMemberUI = {
|
||||
closeMobileSidebar: closeMobileSidebar,
|
||||
openMobileSidebar: openMobileSidebar,
|
||||
isMobileViewport: isMobileViewport
|
||||
};
|
||||
})(jQuery, window, document);
|
||||
Reference in New Issue
Block a user