Đầu tiên xem blog bạn có css dưới chưa nếu có rồi thì không cần chèn thêm nữa.
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
Tiếp đến các bạn chèn đoạn css dưới:
.mdui-float-left { float: left !important; } .mdui-float-right { float: right !important; } .mdui-center { display: block !important; margin-right: auto !important; margin-left: auto !important; } .mdui-valign { display: -webkit-box !important; display: -webkit-flex !important; display: -ms-flexbox !important; display: flex !important; -webkit-box-align: center !important; -webkit-align-items: center !important; -ms-flex-align: center !important; align-items: center !important; } .mdui-text-left { text-align: left !important; } .mdui-text-center { text-align: center !important; } .mdui-text-right { text-align: right !important; } .mdui-text-lowercase { text-transform: lowercase !important; } .mdui-text-uppercase { text-transform: uppercase !important; } .mdui-text-capitalize { text-transform: capitalize !important; } .mdui-text-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .mdui-clearfix:before, .mdui-clearfix:after { display: table; content: " "; } .mdui-clearfix:after { clear: both; } .mdui-hidden, [hidden] { display: none !important; } .mdui-invisible { visibility: hidden; } @media (max-width: 599px) { .mdui-hidden-xs { display: none !important; } } @media (min-width: 600px) and (max-width: 1023px) { .mdui-hidden-sm { display: none !important; } } @media (min-width: 1024px) and (max-width: 1439px) { .mdui-hidden-md { display: none !important; } } @media (min-width: 1440px) and (max-width: 1919px) { .mdui-hidden-lg { display: none !important; } } @media (min-width: 1920px) { .mdui-hidden-xl { display: none !important; } } @media (max-width: 599px) { .mdui-hidden-xs-down { display: none !important; } } @media (max-width: 1023px) { .mdui-hidden-sm-down { display: none !important; } } @media (max-width: 1439px) { .mdui-hidden-md-down { display: none !important; } } @media (max-width: 1919px) { .mdui-hidden-lg-down { display: none !important; } } .mdui-hidden-xl-down { display: none !important; } .mdui-hidden-xs-up { display: none !important; } @media (min-width: 600px) { .mdui-hidden-sm-up { display: none !important; } } @media (min-width: 1024px) { .mdui-hidden-md-up { display: none !important; } } @media (min-width: 1440px) { .mdui-hidden-lg-up { display: none !important; } } @media (min-width: 1920px) { .mdui-hidden-xl-up { display: none !important; } } body { margin: 0; } body { font-family: Roboto, Noto, Helvetica, Arial, sans-serif; font-size: 14px; color: rgba(0, 0, 0, .87); background-color: #fff; } @media (min-width: 600px) { body { font-size: 14.5px; } } @media (min-width: 1024px) { body { font-size: 15px; } } body *::-webkit-scrollbar { width: 8px; height: 8px; background: transparent; } body *::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, .2); } body.mdui-theme-layout-dark *::-webkit-scrollbar { width: 8px; height: 8px; background: transparent; } body.mdui-theme-layout-dark *::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, .3); } * { -webkit-tap-highlight-color: transparent; } body.mdui-locked { overflow: hidden; } .mdui-overlay { position: fixed; top: -5000px; right: -5000px; bottom: -5000px; left: -5000px; z-index: 2000; visibility: hidden; background: rgba(0, 0, 0, .4); opacity: 0; transition-duration: .3s; transition-property: opacity, visibility; -webkit-backface-visibility: hidden; backface-visibility: hidden; will-change: opacity; } .mdui-overlay-show { visibility: visible; opacity: 1; } .mdui-no-transition { transition-property: none !important; } .mdui-icon, .mdui-icon::before { /* Preferred icon size */ display: inline-block; font-size: 24px; font-style: normal; font-weight: normal; line-height: 1; color: inherit; text-transform: none; letter-spacing: normal; word-wrap: normal; white-space: nowrap; vertical-align: middle; direction: ltr; } .mdui-icon1, .mdui-icon1::before { /* Preferred icon size */ display: inline-block; font-size: 24px; font-style: normal; font-weight: normal; line-height: 48px; color: inherit; text-transform: none; letter-spacing: normal; word-wrap: normal; white-space: nowrap; vertical-align: middle; direction: ltr; } .mdui-typo code { padding: 2px 6px; color: #c7254e; background-color: #f7f7f9; border-radius: 2px; } .mdui-typo pre code { padding: 0; font-size: inherit; line-height: 1.7; color: inherit; background-color: transparent; border-radius: 0; } .mdui-typo abbr[title] { text-decoration: none; cursor: help; border-bottom: 1px dotted; } .mdui-typo ins { text-decoration: none; border-bottom: 1px solid ; } .mdui-typo u { text-decoration: none; border-bottom: 1px solid; } .mdui-typo del { text-decoration: line-through; } .mdui-typo hr { height: 10px; margin-bottom: .8em; border: none; border-bottom: 1px solid rgba(0, 0, 0, .12); } .mdui-typo pre { padding: 12px 16px; overflow-x: auto; -webkit-overflow-scrolling: touch; border: 1px solid rgba(0, 0, 0, .12); border-radius: 2px; } .mdui-typo kbd { padding: 2px 6px; font-size: 90%; color: #fff; background-color: #333; border-radius: 2px; } .mdui-typo ul { padding-left: 2em; list-style: disc; } .mdui-typo ol { padding-left: 2em; list-style: decimal; } .mdui-typo li ul, .mdui-typo li ol { margin: .8em 0; } .mdui-typo li ul { list-style: circle; } .mdui-typo img { max-width: 100%; } .mdui-headroom { transition: all .3s cubic-bezier(.4, 0, .2, 1) !important; } .mdui-headroom-pinned-top { -webkit-transform: translate3d(0, 0, 0) !important; transform: translate3d(0, 0, 0) !important; } .mdui-headroom-unpinned-top { box-shadow: none !important; -webkit-transform: translate3d(0, -100%, 0) !important; transform: translate3d(0, -100%, 0) !important; } .mdui-headroom-pinned-down { -webkit-transform: translate3d(0, 0, 0) !important; transform: translate3d(0, 0, 0) !important; } .mdui-headroom-unpinned-down { box-shadow: none !important; -webkit-transform: translate3d(0, 100%, 0) !important; transform: translate3d(0, 100%, 0) !important; } .mdui-headroom-pinned-toolbar { -webkit-transform: translate3d(0, 0, 0) !important; transform: translate3d(0, 0, 0) !important; } .mdui-headroom-unpinned-toolbar { -webkit-transform: translate3d(0, -56px, 0) !important; transform: translate3d(0, -56px, 0) !important; } @media (min-width: 600px) { .mdui-headroom-unpinned-toolbar { -webkit-transform: translate3d(0, -60px, 0) !important; transform: translate3d(0, -60px, 0) !important; } } @media (min-width: 1024px) { .mdui-headroom-unpinned-toolbar { -webkit-transform: translate3d(0, -64px, 0) !important; transform: translate3d(0, -64px, 0) !important; } } /** * ============================================================================= * ************ Collapse 折å æ’件 ************ * ============================================================================= */ .mdui-collapse-item-header .mdui-collapse-item-arrow, .mdui-collapse-item-header.mdui-collapse-item-arrow { transition: -webkit-transform .3s cubic-bezier(.4, 0, .2, 1); transition: transform .3s cubic-bezier(.4, 0, .2, 1); transition: transform .3s cubic-bezier(.4, 0, .2, 1), -webkit-transform .3s cubic-bezier(.4, 0, .2, 1); -webkit-transform: rotate(0); transform: rotate(0); will-change: transform; } .mdui-collapse-item-body { height: 0; padding-top: 0; padding-bottom: 0; margin-top: 0; margin-bottom: 0; overflow: hidden; transition: all .3s cubic-bezier(.4, 0, .2, 1); will-change: height; } .mdui-collapse-item-body .mdui-list-item { padding-left: 72px; } .mdui-collapse-item-open > .mdui-collapse-item-header .mdui-collapse-item-arrow, .mdui-collapse-item-open > .mdui-collapse-item-header.mdui-collapse-item-arrow { -webkit-transform: rotate(-90deg); transform: rotate(-90deg); } .mdui-collapse-item-open > .mdui-collapse-item-body { height: auto; } /** * ============================================================================= * ************ Table è¡¨æ ¼ ************ * ============================================================================= */ .mdui-table { position: relative; width: 100%; border-spacing: 0; border-collapse: separate; background-color: #fff; border: 1px solid rgba(0, 0, 0, .12); box-shadow: 0 3px 1px -2px rgba(0, 0, 0, .2), 0 2px 2px 0 rgba(0, 0, 0, .14), 0 1px 5px 0 rgba(0, 0, 0, .12); /* 最åŽä¸€è¡Œæ²¡æœ‰ä¸‹è¾¹æ¡† */ } .mdui-table tbody tr { position: relative; transition: background-color .28s cubic-bezier(.4, 0, .2, 1); } .mdui-table th, .mdui-table td { position: relative; box-sizing: border-box; padding: 12px 28px; text-align: left; vertical-align: middle; border-bottom: 1px solid rgba(0, 0, 0, .12); } .mdui-table th:last-child, .mdui-table td:last-child { padding-right: 24px; } .mdui-table th:first-child, .mdui-table td:first-child { padding-right: 0; padding-left: 24px; } .mdui-table th:nth-child(2), .mdui-table td:nth-child(2) { padding-left: 24px; } .mdui-table tbody tr:last-child td { border-bottom: none; } .mdui-table th { overflow: hidden; font-size: 13px; font-weight: 700; line-height: 32px; color: rgba(0, 0, 0, .54); text-overflow: ellipsis; white-space: nowrap; } .mdui-table td { font-size: 14px; line-height: 24px; color: rgba(0, 0, 0, .87); } /* æ¯ä¸€è¡Œå‰é¢çš„å¤é€‰æ¡† */ .mdui-table-cell-checkbox { padding-top: 0 !important; padding-bottom: 0!important; padding-left: 24px !important; } .mdui-table-cell-checkbox .mdui-checkbox { margin-top: 7px; } .mdui-table-cell-checkbox + td, .mdui-table-cell-checkbox + th { padding-left: 6px !important; } th.mdui-table-cell-checkbox .mdui-checkbox { margin-top: 11px; } /* é¼ æ ‡æ‚¬æµ®æ—¶è¡ŒèƒŒæ™¯åŠ æ·± */ .mdui-table-hoverable tbody tr:hover { background-color: #eee; } /* è¡¨æ ¼æ”¾åˆ°è¯¥å…ƒç´ å†…ï¼Œä½¿è¡¨æ ¼äº§ç”Ÿæ»šåŠ¨æ¡æ—¶åªåœ¨è¯¥å…ƒç´ 内滚动 */ .mdui-table-fluid { width: 100%; overflow-x: auto; border: 1px solid rgba(0, 0, 0, .12); box-shadow: 0 3px 1px -2px rgba(0, 0, 0, .2), 0 2px 2px 0 rgba(0, 0, 0, .14), 0 1px 5px 0 rgba(0, 0, 0, .12); } .mdui-table-fluid .mdui-table { margin: 0; border: none; box-shadow: none; } /* æ•°å—列,å³å¯¹é½ */ .mdui-table-col-numeric { text-align: right !important; } /* 行处于选ä¸çŠ¶æ€ */ .mdui-table-row-selected { background-color: #f5f5f5; } /** * ============================================================================= * ************ Table dark ************ * ============================================================================= */ .mdui-theme-layout-dark .mdui-table { background-color: #303030; border: 1px solid rgba(255, 255, 255, .12); } .mdui-theme-layout-dark .mdui-table th, .mdui-theme-layout-dark .mdui-table td { border-bottom: 1px solid rgba(255, 255, 255, .12); } .mdui-theme-layout-dark .mdui-table th { color: rgba(255, 255, 255, .7); } .mdui-theme-layout-dark .mdui-table td { color: #fff; } .mdui-theme-layout-dark .mdui-table-hoverable tbody tr:hover { background-color: #616161; } .mdui-theme-layout-dark .mdui-table-fluid { border: 1px solid rgba(255, 255, 255, .12); } .mdui-theme-layout-dark .mdui-table-fluid .mdui-table { border: none; box-shadow: none; } .mdui-theme-layout-dark .mdui-table-row-selected { background-color: #424242; } /** * ============================================================================= * ************ Divider 分割线 ************ * ============================================================================= */ .mdui-divider, .mdui-divider-light, .mdui-divider-dark, .mdui-divider-inset, .mdui-divider-inset-light, .mdui-divider-inset-dark { height: 1px; margin: -1px 0 0 0; border: none; } .mdui-divider-inset, .mdui-divider-inset-light, .mdui-divider-inset-dark { margin-left: 72px; } .mdui-divider, .mdui-divider-inset { background-color: rgba(0, 0, 0, .12); } .mdui-theme-layout-dark .mdui-divider, .mdui-theme-layout-dark .mdui-divider-inset { background-color: rgba(255, 255, 255, .12); } .mdui-divider-light, .mdui-divider-inset-light { background-color: rgba(255, 255, 255, .12); } .mdui-divider-dark, .mdui-divider-inset-dark { background-color: rgba(0, 0, 0, .12); } .mdui-img-fluid, .mdui-video-fluid { display: block; max-width: 100%; height: auto; } /* 圆角图片 */ .mdui-img-rounded { border-radius: 2px; } /* 圆形图片 */ .mdui-img-circle { border-radius: 50%; } .mdui-video-container { position: relative; height: 0; padding-bottom: 56.25%; overflow: hidden; } .mdui-video-container iframe, .mdui-video-container object, .mdui-video-container embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } .mdui-ripple { position: relative; overflow: hidden; cursor: pointer; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } /* Ripple */ .mdui-ripple-wave { position: absolute !important; top: 0; left: 0; z-index: 1; padding: 0; margin: 0; font-size: 0; pointer-events: none; background-color: rgba(0, 0, 0, .1); border-radius: 50%; transition-duration: 1400ms; -webkit-transform: translate3d(0px, 0px, 0) scale(0); transform: translate3d(0px, 0px, 0) scale(0); } /* 有背景色的默认使用白色涟漪 */ .mdui-ripple[class*="mdui-color-"] .mdui-ripple-wave { background-color: rgba(255, 255, 255, .3); } /* 白色涟漪 */ .mdui-ripple-white .mdui-ripple-wave { background-color: rgba(255, 255, 255, .3) !important; } /* 黑色涟漪 */ .mdui-ripple-black .mdui-ripple-wave { background-color: rgba(0, 0, 0, .1) !important; } .mdui-ripple-wave-fill { opacity: .35; transition-duration: 300ms; } .mdui-ripple-wave-out { opacity: 0; transition-duration: 600ms; } .mdui-btn, .mdui-fab { position: relative; display: inline-block; min-width: 88px; height: 36px; box-sizing: border-box; padding: 0 16px; margin: 0; overflow: hidden; font-size: 14px; font-weight: 500; line-height: 36px; color: inherit; text-align: center; text-decoration: none; text-transform: uppercase; letter-spacing: .04em; white-space: nowrap; vertical-align: middle; -ms-touch-action: manipulation; touch-action: manipulation; cursor: pointer; zoom: 1; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background: transparent; border: none; border-radius: 2px; outline: none; transition: all .2s cubic-bezier(.4, 0, .2, 1), box-shadow .2s cubic-bezier(.4, 0, 1, 1); will-change: box-shadow; -webkit-user-drag: none; } .mdui-btn::-moz-focus-inner, .mdui-fab::-moz-focus-inner { border: 0; } .mdui-btn:hover, .mdui-fab:hover { background-color: rgba(0, 0, 0, .1); } .mdui-btn:not(.mdui-ripple):active, .mdui-fab:not(.mdui-ripple):active { background-color: rgba(0, 0, 0, .165); } .mdui-btn[class*="mdui-color-"]:hover, .mdui-fab[class*="mdui-color-"]:hover { opacity: .87; } .mdui-btn:not(.mdui-ripple)[class*="mdui-color-"]:active, .mdui-fab:not(.mdui-ripple)[class*="mdui-color-"]:active { opacity: .76; } /* æŒ‰é’®å†…çš„å›¾æ ‡ */ .mdui-btn .mdui-icon-left, .mdui-btn .mdui-icon-right, .mdui-btn .mdui-icon-left::before, .mdui-btn .mdui-icon-right::before { height: inherit; font-size: 1.3em; line-height: inherit; } .mdui-btn .mdui-icon-left { float: left; margin-right: .4em; } .mdui-btn .mdui-icon-right { float: right; margin-left: .4em; } input.mdui-btn[type="submit"] { -webkit-appearance: none; } /* Raised button 浮动按钮 */ .mdui-btn-raised { box-shadow: 0 3px 1px -2px rgba(0, 0, 0, .2), 0 2px 2px 0 rgba(0, 0, 0, .14), 0 1px 5px 0 rgba(0, 0, 0, .12); } .mdui-btn-raised:hover { box-shadow: 0 2px 4px -1px rgba(0, 0, 0, .2), 0 4px 5px 0 rgba(0, 0, 0, .14), 0 1px 10px 0 rgba(0, 0, 0, .12); } .mdui-btn-raised:active { box-shadow: 0 5px 5px -3px rgba(0, 0, 0, .2), 0 8px 10px 1px rgba(0, 0, 0, .14), 0 3px 14px 2px rgba(0, 0, 0, .12); } /* ç¦ç”¨æŒ‰é’® */ .mdui-btn[disabled], .mdui-fab[disabled], .mdui-btn[disabled]:hover, .mdui-fab[disabled]:hover, .mdui-btn[disabled]:active, .mdui-fab[disabled]:active, .mdui-btn[disabled]:focus, .mdui-fab[disabled]:focus { color: rgba(0, 0, 0, .26) !important; cursor: default !important; background-color: transparent !important; box-shadow: none !important; } .mdui-btn[disabled] .mdui-icon, .mdui-fab[disabled] .mdui-icon, .mdui-btn[disabled]:hover .mdui-icon, .mdui-fab[disabled]:hover .mdui-icon, .mdui-btn[disabled]:active .mdui-icon, .mdui-fab[disabled]:active .mdui-icon, .mdui-btn[disabled]:focus .mdui-icon, .mdui-fab[disabled]:focus .mdui-icon { color: rgba(0, 0, 0, .26) !important; } /* ç¦ç”¨çŠ¶æ€æµ®åŠ¨æŒ‰é’®å’Œæµ®åŠ¨æ“作按钮 */ .mdui-btn-raised[disabled], .mdui-fab[disabled], .mdui-btn-raised[disabled]:hover, .mdui-fab[disabled]:hover, .mdui-btn-raised[disabled]:active, .mdui-fab[disabled]:active, .mdui-btn-raised[disabled]:focus, .mdui-fab[disabled]:focus { background-color: rgba(0, 0, 0, .12) !important; box-shadow: 0 3px 1px -2px rgba(0, 0, 0, .2), 0 2px 2px 0 rgba(0, 0, 0, .14), 0 1px 5px 0 rgba(0, 0, 0, .12) !important; } /* åŠ ç²—æŒ‰é’®æ–‡æœ¬ */ .mdui-btn-bold { font-weight: bold; } /* å›¾æ ‡æŒ‰é’® */ .mdui-btn-icon { width: 36px; min-width: 36px; height: 36px; padding: 0; margin-right: 0; margin-left: 0; overflow: hidden; font-size: 24px; line-height: normal; border-radius: 50%; } .mdui-btn-icon .mdui-icon { position: absolute; top: 50%; left: 50%; width: 24px; line-height: 24px; -webkit-transform: translate(-12px, -12px); transform: translate(-12px, -12px); } .mdui-btn-icon.mdui-ripple { -webkit-transform: translateZ(0); transform: translateZ(0); } /* 按钮 100% 宽度 */ .mdui-btn-block { display: block; width: 100%; } /* 密集型按钮 */ .mdui-btn-dense { height: 32px; font-size: 13px; line-height: 32px; } .mdui-btn-dense.mdui-btn-icon { width: 32px; min-width: 32px; } .mdui-list { padding: 8px 0; margin: 0; list-style: none; background-color: transparent; } .mdui-list .mdui-list { padding: 0; } .mdui-list > .mdui-divider, .mdui-list > .mdui-divider-light, .mdui-list > .mdui-divider-dark, .mdui-list > .mdui-divider-inset, .mdui-list > .mdui-divider-inset-light, .mdui-list > .mdui-divider-inset-dark { margin-top: 8px; margin-bottom: 8px; } .mdui-list a { color: inherit; text-decoration: none; } .mdui-list .mdui-subheader, .mdui-list .mdui-subheader-inset { margin-top: 8px; } .mdui-list .mdui-subheader:before, .mdui-list .mdui-subheader-inset:before { position: absolute; right: 0; left: 0; display: block; height: 1px; content: ' '; background-color: rgba(0, 0, 0, .12); } .mdui-list .mdui-subheader:first-child, .mdui-list .mdui-subheader-inset:first-child { margin-top: -8px; } .mdui-list .mdui-subheader:first-child:before, .mdui-list .mdui-subheader-inset:first-child:before { background-color: transparent; } .mdui-list .mdui-subheader-inset:before { left: 72px; } /* 列表项 */ .mdui-list-item { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; min-height: 48px; box-sizing: border-box; padding: 0; text-decoration: none; cursor: pointer; transition: background-color .3s cubic-bezier(.4, 0, .2, 1); -webkit-box-align: center; -webkit-align-items: center; -ms-flex-align: center; align-items: center; } .mdui-list-item:hover { background-color: rgba(0, 0, 0, .08); } .mdui-list-item:after { height: 48px; visibility: hidden; content: ' '; } /* åˆ—è¡¨é¡¹å›¾æ ‡ */ .mdui-list-item-icon { width: 24px; min-width: 24px; height: 24px; color: rgba(0, 0, 0, .54); } /* åˆ—è¡¨é¡¹å¤´åƒ */ .mdui-list-item-avatar { min-width: 40px; max-width: 40px; height: 40px; margin-top: 8px; margin-bottom: 8px; line-height: 40px; color: #fff; text-align: center; background-color: #bdbdbd; border-radius: 50%; } .mdui-list-item-avatar img { width: 100%; height: 100%; border-radius: 50%; } /* 列表项内容 */ .mdui-list-item-content { padding-top: 14px; padding-bottom: 14px; font-size: 16px; font-weight: 400; line-height: 20px; -webkit-box-flex: 1; -webkit-flex-grow: 1; -ms-flex-positive: 1; flex-grow: 1; } /* 列表项内容的副内容 */ .mdui-list-item-text { font-size: 14px; color: rgba(0, 0, 0, .54); } .mdui-list-item-title ~ .mdui-list-item-text { margin-top: 4px; } /* 激活状æ€çš„列表项 */ .mdui-list-item-active { font-weight: 700; background-color: rgba(0, 0, 0, .08); } .mdui-list-item-active .mdui-list-item-content { font-weight: 700; } .mdui-list-item-active .mdui-list-item-text { font-weight: 400; } /* é™åˆ¶æ–‡æœ¬é«˜åº¦ */ .mdui-list-item-one-line, .mdui-list-item-two-line, .mdui-list-item-three-line { display: -webkit-box; overflow: hidden; text-overflow: ellipsis; -webkit-box-orient: vertical; } .mdui-list-item-one-line { height: 20px; -webkit-line-clamp: 1; } .mdui-list-item-two-line { height: 40px; -webkit-line-clamp: 2; } .mdui-list-item-three-line { height: 60px; -webkit-line-clamp: 3; } /* åˆ—è¡¨é¡¹å†…çš„å…ƒç´ é—´æ·»åŠ é—´è· */ .mdui-list-item-icon ~ .mdui-list-item-content { margin-left: 32px; } .mdui-checkbox ~ .mdui-list-item-content, .mdui-radio ~ .mdui-list-item-content, .mdui-switch ~ .mdui-list-item-content { margin-left: 20px; } .mdui-list-item-avatar ~ .mdui-list-item-content { margin-left: 16px; } .mdui-list-item-content ~ .mdui-list-item-icon, .mdui-list-item-content ~ .mdui-list-item-avatar, .mdui-list-item-content ~ .mdui-checkbox, .mdui-list-item-content ~ .mdui-radio, .mdui-list-item-content ~ .mdui-switch { margin-left: 16px; } .mdui-list-item-content ~ .mdui-checkbox, .mdui-list-item-content ~ .mdui-radio { padding-left: 24px; } /* 密集型列表 */ .mdui-list-dense { padding: 4px 0; font-size: 13px; } .mdui-list-dense > .mdui-divider, .mdui-list-dense > .mdui-divider-light, .mdui-list-dense > .mdui-divider-dark, .mdui-list-dense > .mdui-divider-inset, .mdui-list-dense > .mdui-divider-inset-light, .mdui-list-dense > .mdui-divider-inset-dark { margin-top: 4px; margin-bottom: 4px; } .mdui-list-dense .mdui-subheader, .mdui-list-dense .mdui-subheader-inset { height: 40px; margin-top: 4px; line-height: 40px; } .mdui-list-dense .mdui-subheader:first-child, .mdui-list-dense .mdui-subheader-inset:first-child { margin-top: -4px; } .mdui-list-dense .mdui-list-item { min-height: 40px; } .mdui-list-dense .mdui-list-item:after { height: 40px; } .mdui-list-dense .mdui-list-item-icon { width: 20px; height: 20px; font-size: 20px; } .mdui-list-dense .mdui-list-item-avatar { min-width: 36px; height: 36px; min-height: 36px; } .mdui-list-dense .mdui-list-item-content { padding-top: 11px; padding-bottom: 11px; font-size: 13px; line-height: 18px; } .mdui-list-dense .mdui-list-item-text { font-size: 13px; } .mdui-list-dense .mdui-list-item-title ~ .mdui-list-item-text { margin-top: 2px; } .mdui-list-dense .mdui-list-item-one-line { height: 18px; } .mdui-list-dense .mdui-list-item-two-line { height: 36px; } .mdui-list-dense .mdui-list-item-three-line { height: 54px; } body.mdui-loaded { transition: padding .3s cubic-bezier(0, 0, .2, 1); } body.mdui-loaded .mdui-drawer { transition: all .3s cubic-bezier(0, 0, .2, 1); } .mdui-drawer { position: fixed; top: 0; bottom: 0; left: 0; z-index: 5000; width: 240px; box-sizing: border-box; margin: 0; overflow-x: hidden; overflow-y: auto; white-space: nowrap; will-change: transform; } /* 出现在å³ä¾§çš„抽屉æ */ .mdui-drawer-right { right: 0; left: auto; } /* 手机平æ¿ä¸Šçš„æ ·å¼ */ @media (max-width: 1023px) { .mdui-drawer { /* 始终有背景和阴影 */ background-color: #fff; box-shadow: 0 8px 10px -5px rgba(0, 0, 0, .2), 0 16px 24px 2px rgba(0, 0, 0, .14), 0 6px 30px 5px rgba(0, 0, 0, .12); /* 默认éšè— */ -webkit-transform: translateX(-250px); transform: translateX(-250px); } .mdui-drawer-right { /* å³ä¾§ drawer 也默认éšè— */ -webkit-transform: translateX(250px); transform: translateX(250px); } } /* 强制éšè—抽屉æ */ .mdui-drawer-close { -webkit-transform: translateX(-250px); transform: translateX(-250px); box-shadow: none; } .mdui-drawer-close.mdui-drawer-right { -webkit-transform: translateX(250px); transform: translateX(250px); } /* 强制显示抽屉æ */ .mdui-drawer-open { -webkit-transform: translateX(0) !important; transform: translateX(0) !important; } /* PC ä¸Šçš„æ ·å¼ */ @media (min-width: 1024px) { /* 使 body 获得 padding-left 或 padding-right,é¿å…被抽屉æ 覆盖ä½é¡µé¢ */ body.mdui-drawer-body-left { padding-left: 240px; } body.mdui-drawer-body-right { padding-right: 240px; } /* PC ä¸Šé»˜è®¤æœ‰ä¸Šè¾¹è· */ .mdui-appbar-with-toolbar .mdui-drawer { top: 64px; } .mdui-appbar-with-tab .mdui-drawer { top: 48px; } .mdui-appbar-with-tab-larger .mdui-drawer { top: 72px; } .mdui-appbar-with-toolbar.mdui-appbar-with-tab .mdui-drawer { top: 112px; } .mdui-appbar-with-toolbar.mdui-appbar-with-tab-larger .mdui-drawer { top: 136px; } } .mdui-progress { position: relative; display: block; width: 100%; height: 4px; overflow: hidden; background-color: rgba(63, 81, 181, .2); border-radius: 2px; } /* ç¡®å®šè¿›åº¦çš„çº¿æ€§è¿›åº¦æ¡ */ .mdui-progress-determinate { position: absolute; top: 0; bottom: 0; left: 0; background-color: #3f51b5; transition: width .3s linear; } /* ä¸ç¡®å®šè¿›åº¦çš„çº¿æ€§è¿›åº¦æ¡ */ .mdui-progress-indeterminate { background-color: #3f51b5; } .mdui-progress-indeterminate:before { position: absolute; top: 0; bottom: 0; left: 0; content: ' '; background-color: inherit; -webkit-animation: mdui-progress-indeterminate 2s linear infinite; animation: mdui-progress-indeterminate 2s linear infinite; will-change: left, width; } .mdui-progress-indeterminate:after { position: absolute; top: 0; bottom: 0; left: 0; content: ' '; background-color: inherit; -webkit-animation: mdui-progress-indeterminate-short 2s linear infinite; animation: mdui-progress-indeterminate-short 2s linear infinite; will-change: left, width; } @-webkit-keyframes mdui-progress-indeterminate { 0% { left: 0; width: 0; } 50% { left: 30%; width: 70%; } 75% { left: 100%; width: 0; } } @keyframes mdui-progress-indeterminate { 0% { left: 0; width: 0; } 50% { left: 30%; width: 70%; } 75% { left: 100%; width: 0; } } @-webkit-keyframes mdui-progress-indeterminate-short { 0% { left: 0; width: 0; } 50% { left: 0; width: 0; } 75% { left: 0; width: 25%; } 100% { left: 100%; width: 0; } } @keyframes mdui-progress-indeterminate-short { 0% { left: 0; width: 0; } 50% { left: 0; width: 0; } 75% { left: 0; width: 25%; } 100% { left: 100%; width: 0; } } header{ height:48px; line-height: 48px; text-align: center; font-size:1.5em; background-color: #00b355; color:#fff; } /*列表页*/ .backprev{ float:left; width: 15%; text-align: center; color: #fff; height: 48px; line-height: 48px; } .head-middle{ width: 70%; text-align: center; float: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .head-right{ float:right; text-align: center; width:15%; } .app-hide-list i{ margin-top: -3px; margin-right: 5px; } .app-hide-list{ background: #f5f5f5; margin:5px 0; color:#007d3c; } .app-slide-menu .mdui-list-item-content{ text-align: left; padding-left: .8em; } .app-collapse-menu{ margin:0 16px; } .app-list-home{ padding:0; margin:5px 0 10px; background: #00b355; } .app-list-home:hover{ background: #00b355; } .app-list-home i{ margin-top: -3px; margin-right: 5px; color:#fff; } .app-list-home a{ color:#fff; } .app-list-item-link{ color:#fff; display: block; width:100%; text-align: left; } .mdui-collapse-item-body .app-sub-list{ padding:0 ; margin: 8px; background: #fff; } .mdui-collapse-item-body .app-sub-list a{ padding-left:23px; } .app-collapse-list{ margin:10px 0; } .menu-click{ background: #e1fff0; } .app-btn{ min-width: 100%; text-align: center; padding:0; }
Đoạn code hiện thị menu dưới đây:
<header> <a class="backprev" href="javascript:history.back(-1);"> <i class="mdui-icon1 fa fa-long-arrow-left"></i> </a> <div class="head-middle">CHIA SẺ 78</div> <div class="head-right"> <button class="mdui-btn app-btn" mdui-drawer="{target: '#left-drawer'}"><i class="mdui-icon1 material-icons fa fa-ellipsis-h"></i></button> <div class="mdui-drawer mdui-drawer-right mdui-drawer-close" id="left-drawer"> <ul class="mdui-list app-slide-menu app-collapse-menu" mdui-collapse="{accordion: true}"> <li class="mdui-list-item mdui-ripple app-list-home "> <a href="#" class="app-list-item-link mdui-text-left "> <div class="mdui-list-item-content"> <i class="mdui-list-item-icon mdui-icon material-icons fa fa-home"> </i>Trang Chủ </div> </a> </li> <li class="mdui-collapse-item app-hide-list app-collapse-list"> <div class="mdui-collapse-item-header mdui-list-item mdui-ripple mdui-p-x-0"> <div class="menu-click mdui-list-item-content mdui-text-left" onclick=""> Colum 1 <i class="mdui-collapse-item-arrow mdui-icon material-icons fa fa-angle-right mdui-float-right"> </i> </div> </div> <ul class="mdui-collapse-item-body mdui-list mdui-list-dense"> <li class="mdui-list-item mdui-ripple app-sub-list app-hide-list"> <a href="#" class="app-list-item-link mdui-text-left"> Secondary section </a> </li> <li class="mdui-list-item mdui-ripple app-sub-list app-hide-list"> <a href="#" class="app-list-item-link mdui-text-left"> Secondary section </a> </li> </ul> </li> <li class="mdui-collapse-item app-hide-list app-collapse-list"> <div class="mdui-collapse-item-header mdui-list-item mdui-ripple mdui-p-x-0"> <div class="menu-click mdui-list-item-content mdui-text-left" onclick=""> Colum 2 <i class="mdui-collapse-item-arrow mdui-icon material-icons fa fa-angle-right mdui-float-right"> </i> </div> </div> <ul class="mdui-collapse-item-body mdui-list mdui-list-dense"> <li class="mdui-list-item mdui-ripple app-sub-list app-hide-list"> <a href="#" class="app-list-item-link mdui-text-left"> Secondary section </a> </li> <li class="mdui-list-item mdui-ripple app-sub-list app-hide-list"> <a href="#" class="app-list-item-link mdui-text-left"> Secondary section </a> </li> <li class="mdui-list-item mdui-ripple app-sub-list app-hide-list"> <a href="#" class="app-list-item-link mdui-text-left"> Secondary section </a> </li> <li class="mdui-list-item mdui-ripple app-sub-list app-hide-list"> <a href="#" class="app-list-item-link mdui-text-left"> Secondary section </a> </li> </ul> </li> <li class="mdui-collapse-item app-hide-list app-collapse-list"> <a href="#" class=" mdui-list-item mdui-ripple mdui-p-x-0"> <div class="menu-click mdui-list-item-content mdui-text-left"> Colum 3 <i class="mdui-collapse-item-arrow mdui-icon material-icons fa fa-angle-right mdui-float-right"> </i> </div> </a> </li> </ul> </div> </div> </header>
Cuối cùng là đoạn JS nữa là xong:
<script> ;(function (window, document, undefined) { 'use strict'; var mdui = {}; (function () { var lastTime = 0; if (!window.requestAnimationFrame) { window.requestAnimationFrame = window.webkitRequestAnimationFrame; window.cancelAnimationFrame = window.webkitCancelAnimationFrame; } if (!window.requestAnimationFrame) { window.requestAnimationFrame = function (callback, element) { var currTime = new Date().getTime(); var timeToCall = Math.max(0, 16.7 - (currTime - lastTime)); var id = window.setTimeout(function () { callback(currTime + timeToCall); }, timeToCall); lastTime = currTime + timeToCall; return id; }; } if (!window.cancelAnimationFrame) { window.cancelAnimationFrame = function (id) { clearTimeout(id); }; } })(); var $ = (function (window, document, undefined) { 'use strict'; var emptyArray = []; var slice = emptyArray.slice; var concat = emptyArray.concat; var isArray = Array.isArray; var documentElement = document.documentElement; function isArrayLike(obj) { return typeof obj.length === 'number'; } function each(obj, callback) { var i; var prop; if (isArrayLike(obj)) { for (i = 0; i < obj.length; i++) { if (callback.call(obj[i], i, obj[i]) === false) { return obj; } } } else { for (prop in obj) { if (obj.hasOwnProperty(prop)) { if (callback.call(obj[prop], prop, obj[prop]) === false) { return obj; } } } } return obj; } function map(elems, callback) { var value; var ret = []; each(elems, function (i, elem) { value = callback(elem, i); if (value !== null && value !== undefined) { ret.push(value); } }); return concat.apply([], ret); } /** * 把对象åˆå¹¶åˆ°ç¬¬ä¸€ä¸ªå‚æ•°ä¸ï¼Œå¹¶è¿”回第一个å‚æ•° * @param first * @param second * @returns {*} */ function merge(first, second) { each(second, function (i, val) { first.push(val); }); return first; } /** * 返回去é‡åŽçš„数组 * @param arr * @returns {Array} */ function unique(arr) { var unique = []; for (var i = 0; i < arr.length; i++) { if (unique.indexOf(arr[i]) === -1) { unique.push(arr[i]); } } return unique; } /** * 是å¦æ˜¯ null * @param obj * @returns {boolean} */ function isNull(obj) { return obj === null; } /** * 判æ–一个节点å * @param ele * @param name * @returns {boolean} */ function nodeName(ele, name) { return ele.nodeName && ele.nodeName.toLowerCase() === name.toLowerCase(); } function isFunction(fn) { return typeof fn === 'function'; } function isString(obj) { return typeof obj === 'string'; } function isObject(obj) { return typeof obj === 'object'; } /** * 除去 null åŽçš„ object 类型 * @param obj * @returns {*|boolean} */ function isObjectLike(obj) { return isObject(obj) && !isNull(obj); } function isWindow(win) { return win && win === win.window; } function isDocument(doc) { return doc && doc.nodeType === doc.DOCUMENT_NODE; } var elementDisplay = {}; /** * 获å–å…ƒç´ çš„é»˜è®¤ display æ ·å¼å€¼ï¼Œç”¨äºŽ .show() 方法 * @param nodeName * @returns {*} */ function defaultDisplay(nodeName) { var element; var display; if (!elementDisplay[nodeName]) { element = document.createElement(nodeName); document.body.appendChild(element); display = getComputedStyle(element, '').getPropertyValue('display'); element.parentNode.removeChild(element); if (display === 'none') { display = 'block'; } elementDisplay[nodeName] = display; } return elementDisplay[nodeName]; } var JQ = function (arr) { var _this = this; for (var i = 0; i < arr.length; i++) { _this[i] = arr[i]; } _this.length = arr.length; return this; }; /** * @param selector {String|Function|Node|Window|NodeList|Array|JQ=} * @returns {JQ} */ var $ = function (selector) { var arr = []; var i = 0; if (!selector) { return new JQ(arr); } if (selector instanceof JQ) { return selector; } if (isString(selector)) { var els; var tempParent; selector = selector.trim(); // 创建 HTML å—符串 if (selector[0] === '<' && selector[selector.length - 1] === '>') { // HTML var toCreate = 'div'; if (selector.indexOf('<li') === 0) { toCreate = 'ul'; } if (selector.indexOf('<tr') === 0) { toCreate = 'tbody'; } if (selector.indexOf('<td') === 0 || selector.indexOf('<th') === 0) { toCreate = 'tr'; } if (selector.indexOf('<tbody') === 0) { toCreate = 'table'; } if (selector.indexOf('<option') === 0) { toCreate = 'select'; } tempParent = document.createElement(toCreate); tempParent.innerHTML = selector; for (i = 0; i < tempParent.childNodes.length; i++) { arr.push(tempParent.childNodes[i]); } } // 选择器 else { // id 选择器 if (selector[0] === '#' && !selector.match(/[ .<>:~]/)) { els = [document.getElementById(selector.slice(1))]; } // 其他选择器 else { els = document.querySelectorAll(selector); } for (i = 0; i < els.length; i++) { if (els[i]) { arr.push(els[i]); } } } } // function else if (isFunction(selector)) { return $(document).ready(selector); } // Node else if (selector.nodeType || selector === window || selector === document) { arr.push(selector); } // NodeList else if (selector.length > 0 && selector[0].nodeType) { for (i = 0; i < selector.length; i++) { arr.push(selector[i]); } } return new JQ(arr); }; $.fn = JQ.prototype; /** * 扩展函数和原型属性 * @param obj */ $.extend = $.fn.extend = function (obj) { if (obj === undefined) { return this; } var length = arguments.length; var prop; var i; var options; // $.extend(obj) if (length === 1) { for (prop in obj) { if (obj.hasOwnProperty(prop)) { this[prop] = obj[prop]; } } return this; } // $.extend({}, defaults[, obj]) for (i = 1; i < length; i++) { options = arguments[i]; for (prop in options) { if (options.hasOwnProperty(prop)) { obj[prop] = options[prop]; } } } return obj; }; $.extend({ /** * é历对象 * @param obj {String|Array|Object} * @param callback {Function} * @returns {Array|Object} */ each: each, /** * åˆå¹¶ä¸¤ä¸ªæ•°ç»„,返回的结果会修改第一个数组的内容 * @param first {Array} * @param second {Array} * @returns {Array} */ merge: merge, /** * åˆ é™¤æ•°ç»„ä¸é‡å¤å…ƒç´ * @param arr {Array} * @returns {Array} */ unique: unique, /** * 通过é历集åˆä¸çš„节点对象,通过函数返回一个新的数组,null 或 undefined 将被过滤掉。 * @param elems * @param callback * @returns {Array} */ map: map, /** * 一个 DOM 节点是å¦åŒ…å«å¦ä¸€ä¸ª DOM 节点 * @param parent {Node} 父节点 * @param node {Node} å节点 * @returns {Boolean} */ contains: function (parent, node) { if (parent && !node) { return documentElement.contains(parent); } return parent !== node && parent.contains(node); }, /** * 将数组或对象åºåˆ—化 * @param obj * @returns {String} */ param: function (obj) { if (!isObjectLike(obj)) { return ''; } var args = []; each(obj, function (key, value) { destructure(key, value); }); return args.join('&'); function destructure(key, value) { var keyTmp; if (isObjectLike(value)) { each(value, function (i, v) { if (isArray(value) && !isObjectLike(v)) { keyTmp = ''; } else { keyTmp = i; } destructure(key + '[' + keyTmp + ']', v); }); } else { if (!isNull(value) && value !== '') { keyTmp = '=' + encodeURIComponent(value); } else { keyTmp = ''; } args.push(encodeURIComponent(key) + keyTmp); } } }, }); $.fn.extend({ /** * é历对象 * @param callback {Function} * @return {JQ} */ each: function (callback) { return each(this, callback); }, /** * 通过é历集åˆä¸çš„节点对象,通过函数返回一个新的对象,null 或 undefined 将被过滤掉。 * @param callback {Function} * @returns {JQ} */ map: function (callback) { return new JQ(map(this, function (el, i) { return callback.call(el, i, el); })); }, /** * 获å–指定 DOM å…ƒç´ ï¼Œæ²¡æœ‰ index å‚数时,获å–所有 DOM 的数组 * @param index {Number=} * @returns {Node|Array} */ get: function (index) { return index === undefined ? slice.call(this) : this[index >= 0 ? index : index + this.length]; }, /** * arrayä¸æå–的方法。从start开始,如果end 指出。æå–ä¸åŒ…å«endä½ç½®çš„å…ƒç´ ã€‚ * @param argument {start, end} * @returns {JQ} */ slice: function (argument) { return new JQ(slice.apply(this, arguments)); }, /** * ç›é€‰å…ƒç´ é›†åˆ * @param selector {String|JQ|Node|Function} * @returns {JQ} */ filter: function (selector) { if (isFunction(selector)) { return this.map(function (index, ele) { return selector.call(ele, index, ele) ? ele : undefined; }); } else { var $selector = $(selector); return this.map(function (index, ele) { return $selector.index(ele) > -1 ? ele : undefined; }); } }, /** * ä»Žå…ƒç´ é›†åˆä¸åˆ é™¤æŒ‡å®šçš„å…ƒç´ * @param selector {String|Node|JQ|Function} * @return {JQ} */ not: function (selector) { var $excludes = this.filter(selector); return this.map(function (index, ele) { return $excludes.index(ele) > -1 ? undefined : ele; }); }, /** * 获å–å…ƒç´ ç›¸å¯¹äºŽ document çš„å移 * @returns {Object} */ offset: function () { if (this[0]) { var offset = this[0].getBoundingClientRect(); return { left: offset.left + window.pageXOffset, top: offset.top + window.pageYOffset, width: offset.width, height: offset.height, }; } return null; }, /** * 返回最近的用于定ä½çš„çˆ¶å…ƒç´ * @returns {*|JQ} */ offsetParent: function () { return this.map(function () { var offsetParent = this.offsetParent; while (offsetParent && $(offsetParent).css('position') === 'static') { offsetParent = offsetParent.offsetParent; } return offsetParent || documentElement; }); }, /** * 获å–å…ƒç´ ç›¸å¯¹äºŽçˆ¶å…ƒç´ çš„å移 * @return {Object} */ position: function () { var _this = this; if (!_this[0]) { return null; } var offsetParent; var offset; var parentOffset = { top: 0, left: 0, }; if (_this.css('position') === 'fixed') { offset = _this[0].getBoundingClientRect(); } else { offsetParent = _this.offsetParent(); offset = _this.offset(); if (!nodeName(offsetParent[0], 'html')) { parentOffset = offsetParent.offset(); } parentOffset = { top: parentOffset.top + offsetParent.css('borderTopWidth'), left: parentOffset.left + offsetParent.css('borderLeftWidth'), }; } return { top: offset.top - parentOffset.top - _this.css('marginTop'), left: offset.left - parentOffset.left - _this.css('marginLeft'), width: offset.width, height: offset.height, }; }, /** * æ˜¾ç¤ºæŒ‡å®šå…ƒç´ * @returns {JQ} */ show: function () { return this.each(function () { if (this.style.display === 'none') { this.style.display = ''; } if (window.getComputedStyle(this, '').getPropertyValue('display') === 'none') { this.style.display = defaultDisplay(this.nodeName); } }); }, /** * éšè—æŒ‡å®šå…ƒç´ * @returns {JQ} */ hide: function () { return this.each(function () { this.style.display = 'none'; }); }, /** * 切æ¢å…ƒç´ çš„æ˜¾ç¤ºçŠ¶æ€ * @returns {JQ} */ toggle: function () { return this.each(function () { this.style.display = this.style.display === 'none' ? '' : 'none'; }); }, /** * 是å¦å«æœ‰æŒ‡å®šçš„ CSS ç±» * @param className {String} * @returns {boolean} */ hasClass: function (className) { if (!this[0] || !className) { return false; } return this[0].classList.contains(className); }, /** * 移除指定属性 * @param attr {String} * @returns {JQ} */ removeAttr: function (attr) { return this.each(function () { this.removeAttribute(attr); }); }, /** * åˆ é™¤å±žæ€§å€¼ * @param name {String} * @returns {JQ} */ removeProp: function (name) { return this.each(function () { try { delete this[name]; } catch (e) {} }); }, /** * 获å–当å‰å¯¹è±¡ä¸ç¬¬nä¸ªå…ƒç´ * @param index {Number} * @returns {JQ} */ eq: function (index) { var ret = index === -1 ? this.slice(index) : this.slice(index, +index + 1); return new JQ(ret); }, /** * 获å–对象ä¸ç¬¬ä¸€ä¸ªå…ƒç´ * @returns {JQ} */ first: function () { return this.eq(0); }, /** * 获å–对象ä¸æœ€åŽä¸€ä¸ªå…ƒç´ * @returns {JQ} */ last: function () { return this.eq(-1); }, /** * 获å–ä¸€ä¸ªå…ƒç´ çš„ä½ç½®ã€‚ * 当 ele å‚数没有给出时,返回当å‰å…ƒç´ 在兄弟节点ä¸çš„ä½ç½®ã€‚ * 有给出了 ele å‚数时,返回 ele å…ƒç´ åœ¨å½“å‰å¯¹è±¡ä¸çš„ä½ç½® * @param ele {Selector|Node=} * @returns {Number} */ index: function (ele) { if (!ele) { // 获å–å½“å‰ JQ å¯¹è±¡çš„ç¬¬ä¸€ä¸ªå…ƒç´ åœ¨åŒè¾ˆå…ƒç´ ä¸çš„ä½ç½® return this.eq(0).parent().children().get().indexOf(this[0]); } else if (isString(ele)) { // è¿”å›žå½“å‰ JQ å¯¹è±¡çš„ç¬¬ä¸€ä¸ªå…ƒç´ åœ¨æŒ‡å®šé€‰æ‹©å™¨å¯¹åº”çš„å…ƒç´ ä¸çš„ä½ç½® return $(ele).eq(0).parent().children().get().indexOf(this[0]); } else { // è¿”å›žæŒ‡å®šå…ƒç´ åœ¨å½“å‰ JQ 对象ä¸çš„ä½ç½® return this.get().indexOf(ele); } }, /** * æ ¹æ®é€‰æ‹©å™¨ã€DOMå…ƒç´ æˆ– JQ 对象æ¥æ£€æµ‹åŒ¹é…å…ƒç´ é›†åˆï¼Œ * 如果其ä¸è‡³å°‘æœ‰ä¸€ä¸ªå…ƒç´ ç¬¦åˆè¿™ä¸ªç»™å®šçš„表达å¼å°±è¿”回true * @param selector {String|Node|NodeList|Array|JQ|Window} * @returns boolean */ is: function (selector) { var _this = this[0]; if (!_this || selector === undefined || selector === null) { return false; } var $compareWith; var i; if (isString(selector)) { if (_this === document || _this === window) { &nnbsp; return false; } var matchesSelector = _this.matches || _this.matchesSelector || _this.webkitMatchesSelector || _this.mozMatchesSelector || _this.oMatchesSelector || _this.msMatchesSelector; return matchesSelector.call(_this, selector); } else if (selector === document || selector === window) { return _this === selector; } else { if (selector.nodeType || isArrayLike(selector)) { $compareWith = selector.nodeType ? [selector] : selector; for (i = 0; i < $compareWith.length; i++) { if ($compareWith[i] === _this) { return true; } } return false; } return false; } }, /** * æ ¹æ® CSS 选择器找到åŽä»£èŠ‚ç‚¹çš„é›†åˆ * @param selector {String} * @returns {JQ} */ find: function (selector) { var foundElements = []; this.each(function (i, _this) { merge(foundElements, _this.querySelectorAll(selector)); }); return new JQ(foundElements); }, /** * 找到直接åå…ƒç´ çš„å…ƒç´ é›†åˆ * @param selector {String=} * @returns {JQ} */ children: function (selector) { var children = []; this.each(function (i, _this) { each(_this.childNodes, function (i, childNode) { if (childNode.nodeType !== 1) { return true; } if (!selector || (selector && $(childNode).is(selector))) { children.push(childNode); } }); }); return new JQ(unique(children)); }, /** * ä¿ç•™å«æœ‰æŒ‡å®šåå…ƒç´ çš„å…ƒç´ ï¼ŒåŽ»æŽ‰ä¸å«æœ‰æŒ‡å®šåå…ƒç´ çš„å…ƒç´ * @param selector {String|Node|JQ|NodeList|Array} * @return {JQ} */ has: function (selector) { var $targets = isString(selector) ? this.find(selector) : $(selector); var len = $targets.length; return this.filter(function () { for (var i = 0; i < len; i++) { if ($.contains(this, $targets[i])) { return true; } } }); }, /** * å–å¾—åŒè¾ˆå…ƒç´ çš„é›†åˆ * @param selector {String=} * @returns {JQ} */ siblings: function (selector) { return this.prevAll(selector).add(this.nextAll(selector)); }, /** * 返回首先匹é…到的父节点,包å«çˆ¶èŠ‚点 * @param selector {String} * @returns {JQ} */ closest: function (selector) { var _this = this; if (!_this.is(selector)) { _this = _this.parents(selector).eq(0); } return _this; }, /** * åˆ é™¤æ‰€æœ‰åŒ¹é…çš„å…ƒç´ * @returns {JQ} */ remove: function () { return this.each(function (i, _this) { if (_this.parentNode) { _this.parentNode.removeChild(_this); } }); }, /** * æ·»åŠ åŒ¹é…çš„å…ƒç´ åˆ°å½“å‰å¯¹è±¡ä¸ * @param selector {String|JQ} * @returns {JQ} */ add: function (selector) { return new JQ(unique(merge(this.get(), $(selector)))); }, /** * åˆ é™¤å节点 * @returns {JQ} */ empty: function () { return this.each(function () { this.innerHTML = ''; }); }, /** * 通过深度克隆æ¥å¤åˆ¶é›†åˆä¸çš„æ‰€æœ‰å…ƒç´ ã€‚ * (通过原生 cloneNode 方法深度克隆æ¥å¤åˆ¶é›†åˆä¸çš„æ‰€æœ‰å…ƒç´ ã€‚æ¤æ–¹æ³•ä¸ä¼šæœ‰æ•°æ®å’Œäº‹ä»¶å¤„ç†ç¨‹åºå¤åˆ¶åˆ°æ–°çš„å…ƒç´ ã€‚è¿™ç‚¹å’Œjqueryä¸åˆ©ç”¨ä¸€ä¸ªå‚æ•°æ¥ç¡®å®šæ˜¯å¦å¤åˆ¶æ•°æ®å’Œäº‹ä»¶å¤„ç†ä¸ç›¸åŒã€‚) * @returns {JQ} */ clone: function () { return this.map(function () { return this.cloneNode(true); }); }, /** * ç”¨æ–°å…ƒç´ æ›¿æ¢å½“å‰å…ƒç´ * @param newContent {String|Node|NodeList|JQ} * @returns {JQ} */ replaceWith: function (newContent) { return this.before(newContent).remove(); }, /** * 将表å•å…ƒç´ 的值组åˆæˆé”®å€¼å¯¹æ•°ç»„ * @returns {Array} */ serializeArray: function () { var result = []; var $ele; var type; var ele = this[0]; if (!ele || !ele.elements) { return result; } $(slice.call(ele.elements)).each(function () { $ele = $(this); type = $ele.attr('type'); if ( this.nodeName.toLowerCase() !== 'fieldset' && !this.disabled && ['submit', 'reset', 'button'].indexOf(type) === -1 && (['radio', 'checkbox'].indexOf(type) === -1 || this.checked) ) { result.push({ name: $ele.attr('name'), value: $ele.val(), }); } }); return result; }, /** * 将表å•å…ƒç´ 或对象åºåˆ—化 * @returns {String} */ serialize: function () { var result = []; each(this.serializeArray(), function (i, elm) { result.push(encodeURIComponent(elm.name) + '=' + encodeURIComponent(elm.value)); }); return result.join('&'); }, }); /** * val - 获å–æˆ–è®¾ç½®å…ƒç´ çš„å€¼ * @param value {String=} * @return {*|JQ} */ /** * html - 获å–æˆ–è®¾ç½®å…ƒç´ çš„ HTML * @param value {String=} * @return {*|JQ} */ /** * text - 获å–æˆ–è®¾ç½®å…ƒç´ çš„å†…å®¹ * @param value {String=} * @return {*|JQ} */ each(['val', 'html', 'text'], function (nameIndex, name) { var props = { 0: 'value', 1: 'innerHTML', 2: 'textContent', }; var defaults = { 0: undefined, 1: undefined, 2: null, }; $.fn[name] = function (value) { if (value === undefined) { // 获å–值 return this[0] ? this[0][props[nameIndex]] : defaults[nameIndex]; } else { // 设置值 return this.each(function (i, ele) { ele[props[nameIndex]] = value; }); } }; }); /** * attr - 获å–æˆ–è®¾ç½®å…ƒç´ çš„å±žæ€§å€¼ * @param {name|props|key,value=} * @return {String|JQ} */ /** * prop - 获å–æˆ–è®¾ç½®å…ƒç´ çš„å±žæ€§å€¼ * @param {name|props|key,value=} * @return {String|JQ} */ /** * css - 获å–æˆ–è®¾ç½®å…ƒç´ çš„æ ·å¼ * @param {name|props|key,value=} * @return {String|JQ} */ each(['attr', 'prop', 'css'], function (nameIndex, name) { var set = function (ele, key, value) { if (nameIndex === 0) { ele.setAttribute(key, value); } else if (nameIndex === 1) { ele[key] = value; } else { ele.style[key] = value; } }; var get = function (ele, key) { if (!ele) { return undefined; } var value; if (nameIndex === 0) { value = ele.getAttribute(key); } else if (nameIndex === 1) { value = ele[key]; } else { value = window.getComputedStyle(ele, null).getPropertyValue(key); } return value; }; $.fn[name] = function (key, value) { var argLength = arguments.length; if (argLength === 1 && isString(key)) { // 获å–值 return get(this[0], key); } else { // 设置值 return this.each(function (i, ele) { if (argLength === 2) { set(ele, key, value); } else { each(key, function (k, v) { set(ele, k, v); }); } }); } }; }); /** * addClass - æ·»åŠ CSS 类,多个类åç”¨ç©ºæ ¼åˆ†å‰² * @param className {String} * @return {JQ} */ /** * removeClass - 移除 CSS 类,多个类åç”¨ç©ºæ ¼åˆ†å‰² * @param className {String} * @return {JQ} */ /** * toggleClass - åˆ‡æ¢ CSS ç±»å,多个类åç”¨ç©ºæ ¼åˆ†å‰² * @param className {String} * @return {JQ} */ each(['add', 'remove', 'toggle'], function (nameIndex, name) { $.fn[name + 'Class'] = function (className) { if (!className) { return this; } var classes = className.split(' '); return this.each(function (i, ele) { each(classes, function (j, cls) { ele.classList[name](cls); }); }); }; }); /** * width - 获å–å…ƒç´ çš„å®½åº¦ * @return {Number} */ /** * height - 获å–å…ƒç´ çš„é«˜åº¦ * @return {Number} */ each({ Width: 'width', Height: 'height', }, function (prop, name) { $.fn[name] = function (val) { if (val === undefined) { // èŽ·å– var ele = this[0]; if (isWindow(ele)) { return ele['inner' + prop]; } if (isDocument(ele)) { return ele.documentElement['scroll' + prop]; } var $ele = $(ele); // IE10ã€IE11 在 box-sizing:border-box 时,ä¸ä¼šåŒ…å« paddingï¼Œè¿™é‡Œè¿›è¡Œä¿®å¤ var IEFixValue = 0; if ('ActiveXObject' in window) { // 判æ–是 IE æµè§ˆå™¨ if ($ele.css('box-sizing') === 'border-box') { IEFixValue = parseFloat($ele.css('padding-' + (name === 'width' ? 'left' : 'top'))) + parseFloat($ele.css('padding-' + (name === 'width' ? 'right' : 'bottom'))); } } return parseFloat($(ele).css(name)) + IEFixValue; } else { // 设置 if (!isNaN(Number(val)) && val !== '') { val += 'px'; } return this.css(name, val); } }; }); /** * innerWidth - 获å–å…ƒç´ çš„å®½åº¦ï¼ŒåŒ…å«å†…è¾¹è· * @return {Number} */ /** * innerHeight - 获å–å…ƒç´ çš„é«˜åº¦ï¼ŒåŒ…å«å†…è¾¹è· * @return {Number} */ each({ Width: 'width', Height: 'height', }, function (prop, name) { $.fn['inner' + prop] = function () { var value = this[name](); var $ele = $(this[0]); if ($ele.css('box-sizing') !== 'border-box') { value += parseFloat($ele.css('padding-' + (name === 'width' ? 'left' : 'top'))); value += parseFloat($ele.css('padding-' + (name === 'width' ? 'right' : 'bottom'))); } return value; }; }); var dir = function (nodes, selector, nameIndex, node) { var ret = []; var ele; nodes.each(function (j, _this) { ele = _this[node]; while (ele) { if (nameIndex === 2) { // prevUntil if (!selector || (selector && $(ele).is(selector))) { break; } ret.push(ele); } else if (nameIndex === 0) { // prev if (!selector || (selector && $(ele).is(selector))) { ret.push(ele); } break; } else { // prevAll if (!selector || (selector && $(ele).is(selector))) { ret.push(ele); } } ele = ele[node]; } }); return new JQ(unique(ret)); }; /** * prev - å–å¾—å‰ä¸€ä¸ªåŒ¹é…çš„å…ƒç´ * @param selector {String=} * @return {JQ} */ /** * prevAll - å–å¾—å‰é¢æ‰€æœ‰åŒ¹é…çš„å…ƒç´ * @param selector {String=} * @return {JQ} */ /** * prevUntil - å–å¾—å‰é¢çš„æ‰€æœ‰å…ƒç´ ï¼Œç›´åˆ°é‡åˆ°åŒ¹é…çš„å…ƒç´ ï¼Œä¸åŒ…å«åŒ¹é…çš„å…ƒç´ * @param selector {String=} * @return {JQ} */ each(['', 'All', 'Until'], function (nameIndex, name) { $.fn['prev' + name] = function (selector) { // prevAllã€prevUntil 需è¦æŠŠå…ƒç´ 的顺åºå€’åºå¤„ç†ï¼Œä»¥ä¾¿å’Œ jQuery 的结果一致 var $nodes = nameIndex === 0 ? this : $(this.get().reverse()); return dir($nodes, selector, nameIndex, 'previousElementSibling'); }; }); /** * next - å–å¾—åŽä¸€ä¸ªåŒ¹é…çš„å…ƒç´ * @param selector {String=} * @return {JQ} */ /** * nextAll - å–å¾—åŽé¢æ‰€æœ‰åŒ¹é…çš„å…ƒç´ * @param selector {String=} * @return {JQ} */ /** * nextUntil - å–å¾—åŽé¢æ‰€æœ‰åŒ¹é…çš„å…ƒç´ ï¼Œç›´åˆ°é‡åˆ°åŒ¹é…çš„å…ƒç´ ï¼Œä¸åŒ…å«åŒ¹é…çš„å…ƒç´ * @param selector {String=} * @return {JQ} */ each(['', 'All', 'Until'], function (nameIndex, name) { $.fn['next' + name] = function (selector) { return dir(this, selector, nameIndex, 'nextElementSibling'); }; }); /** * parent - å–得匹é…çš„ç›´æŽ¥çˆ¶å…ƒç´ * @param selector {String=} * @return {JQ} */ /** * parents - å–得所有匹é…çš„çˆ¶å…ƒç´ * @param selector {String=} * @return {JQ} */ /** * parentUntil - å–å¾—æ‰€æœ‰çš„çˆ¶å…ƒç´ ï¼Œç›´åˆ°é‡åˆ°åŒ¹é…çš„å…ƒç´ ï¼Œä¸åŒ…å«åŒ¹é…çš„å…ƒç´ * @param selector {String=} * @return {JQ} */ each(['', 's', 'sUntil'], function (nameIndex, name) { $.fn['parent' + name] = function (selector) { // parentsã€parentsUntil 需è¦æŠŠå…ƒç´ 的顺åºåå‘处ç†ï¼Œä»¥ä¾¿å’Œ jQuery 的结果一致 var $nodes = nameIndex === 0 ? this : $(this.get().reverse()); return dir($nodes, selector, nameIndex, 'parentNode'); }; }); /** * append - åœ¨å…ƒç´ å†…éƒ¨è¿½åŠ å†…å®¹ * @param newChild {String|Node|NodeList|JQ} * @return {JQ} */ /** * prepend - åœ¨å…ƒç´ å†…éƒ¨å‰ç½®å†…容 * @param newChild {String|Node|NodeList|JQ} * @return {JQ} */ each(['append', 'prepend'], function (nameIndex, name) { $.fn[name] = function (newChild) { var newChilds; var copyByClone = this.length > 1; if (isString(newChild)) { var tempDiv = document.createElement('div'); tempDiv.innerHTML = newChild; newChilds = slice.call(tempDiv.childNodes); } else { newChilds = $(newChild).get(); } if (nameIndex === 1) { // prepend newChilds.reverse(); } return this.each(function (i, _this) { each(newChilds, function (j, child) { // ä¸€ä¸ªå…ƒç´ è¦åŒæ—¶è¿½åŠ åˆ°å¤šä¸ªå…ƒç´ ä¸ï¼Œéœ€è¦å…ˆå¤åˆ¶ä¸€ä»½ï¼Œç„¶åŽè¿½åŠ if (copyByClone && i > 0) { child = child.cloneNode(true); } if (nameIndex === 0) { // append _this.appendChild(child); } else { // prepend _this.insertBefore(child, _this.childNodes[0]); } }); }); }; }); /** * insertBefore - æ’å…¥åˆ°æŒ‡å®šå…ƒç´ çš„å‰é¢ * @param selector {String|Node|NodeList|JQ} * @return {JQ} */ /** * insertAfter - æ’å…¥åˆ°æŒ‡å®šå…ƒç´ çš„åŽé¢ * @param selector {String|Node|NodeList|JQ} * @return {JQ} */ each(['insertBefore', 'insertAfter'], function (nameIndex, name) { $.fn[name] = function (selector) { var $ele = $(selector); return this.each(function (i, _this) { $ele.each(function (j, ele) { ele.parentNode.insertBefore( $ele.length === 1 ? _this : _this.cloneNode(true), nameIndex === 0 ? ele : ele.nextSibling ); }); }); }; }); /** * appendTo - è¿½åŠ åˆ°æŒ‡å®šå…ƒç´ å†…å®¹ * @param selector {String|Node|NodeList|JQ} * @return {JQ} */ /** * prependTo - å‰ç½®åˆ°æŒ‡å®šå…ƒç´ 内部 * @param selector {String|Node|NodeList|JQ} * @return {JQ} */ /** * before - æ’å…¥åˆ°æŒ‡å®šå…ƒç´ å‰é¢ * @param selector {String|Node|NodeList|JQ} * @return {JQ} */ /** * after - æ’å…¥åˆ°æŒ‡å®šå…ƒç´ åŽé¢ * @param selector {String|Node|NodeList|JQ} * @return {JQ} */ /** * replaceAll - 替æ¢æŽ‰æŒ‡å®šå…ƒç´ * @param selector {String|Node|NodeList|JQ} * @return {JQ} */ each({ appendTo: 'append', prependTo: 'prepend', before: 'insertBefore', after: 'insertAfter', replaceAll: 'replaceWith', }, function (name, original) { $.fn[name] = function (selector) { $(selector)[original](this); return this; }; }); (function () { var dataNS = 'mduiElementDataStorage'; $.extend({ /** * åœ¨æŒ‡å®šå…ƒç´ ä¸Šå˜å‚¨æ•°æ®ï¼Œæˆ–ä»ŽæŒ‡å®šå…ƒç´ ä¸Šè¯»å–æ•°æ® * @param ele 必须, DOM å…ƒç´ * @param key 必须,键å * @param value å¯é€‰ï¼Œå€¼ */ data: function (ele, key, value) { var data = {}; if (value !== undefined) { // æ ¹æ® keyã€value 设置值 data[key] = value; } else if (isObjectLike(key)) { // æ ¹æ®é”®å€¼å¯¹è®¾ç½®å€¼ data = key; } else if (key === undefined) { // 获å–所有值 var result = {}; each(ele.attributes, function (i, attribute) { var name = attribute.name; if (name.indexOf('data-') === 0) { var prop = name.slice(5).replace(/-./g, function (u) { // 横æ 转为驼峰法 return u.charAt(1).toUpperCase(); }); result[prop] = attribute.value; } }); if (ele[dataNS]) { each(ele[dataNS], function (k, v) { result[k] = v; }); } return result; } else { // 获å–指定值 if (ele[dataNS] && (key in ele[dataNS])) { return ele[dataNS][key]; } else { var dataKey = ele.getAttribute('data-' + key); if (dataKey) { return dataKey; } else { return undefined; } } } // 设置值 if (!ele[dataNS]) { ele[dataNS] = {}; } each(data, function (k, v) { ele[dataNS][k] = v; }); }, /** * ç§»é™¤æŒ‡å®šå…ƒç´ ä¸Šå˜æ”¾çš„æ•°æ® * @param ele 必须,DOM å…ƒç´ * @param key 必须,键å */ removeData: function (ele, key) { if (ele[dataNS] && ele[dataNS][key]) { ele[dataNS][key] = null; delete ele.mduiElementDataStorage[key]; } }, }); $.fn.extend({ /** * åœ¨å…ƒç´ ä¸Šè¯»å–æˆ–è®¾ç½®æ•°æ® * @param key å¿…é¡» * @param value * @returns {*} */ data: function (key, value) { if (value === undefined) { // 获å–值 if (this[0]) { return $.data(this[0], key); } else { return undefined; } } else { // 设置值 return this.each(function (i, ele) { $.data(ele, key, value); }); } }, /** * ç§»é™¤å…ƒç´ ä¸Šå˜å‚¨çš„æ•°æ® * @param key å¿…é¡» * @returns {*} */ removeData: function (key) { return this.each(function (i, ele) { $.removeData(ele, key); }); }, }); })(); (function () { // å˜å‚¨äº‹ä»¶ var handlers = { // i: { // å…ƒç´ ID // j: { // 事件ID // e: 事件å // fn: 事件处ç†å‡½æ•° // i: 事件ID // proxy: // sel: 选择器 // } // } }; // å…ƒç´ ID var _elementId = 1; var fnFalse = function () { return false; }; $.fn.extend({ /** * DOM åŠ è½½å®Œæ¯•åŽè°ƒç”¨çš„函数 * @param callback * @returns {ready} */ ready: function (callback) { if (/complete|loaded|interactive/.test(document.readyState) && document.body) { callback($); } else { document.addEventListener('DOMContentLoaded', function () { callback($); }, false); } return this; }, /** * 绑定事件 * * $().on({eventName: fn}, selector, data); * $().on({eventName: fn}, selector) * $().on({eventName: fn}) * $().on(eventName, selector, data, fn); * $().on(eventName, selector, fn); * $().on(eventName, data, fn); * $().on(eventName, fn); * $().on(eventName, false); * * @param eventName * @param selector * @param data * @param callback * @param one 是å¦æ˜¯ one 方法,åªåœ¨ JQ 内部使用 * @returns */ on: function (eventName, selector, data, callback, one) { var _this = this; // 默认 // $().on(event, selector, data, callback) // event 使用 事件:函数 键值对 // event = { // 'event1': callback1, // 'event2': callback2 // } // // $().on(event, selector, data) if (eventName && !isString(eventName)) { each(eventName, function (type, fn) { _this.on(type, selector, data, fn); }); return _this; } // selector ä¸å˜åœ¨ // $().on(event, data, callback) if (!isString(selector) && !isFunction(callback) && callback !== false) { callback = data; data = selector; selector = undefined; } // data ä¸å˜åœ¨ // $().on(event, callback) if (isFunction(data) || data === false) { callback = data; data = undefined; } // callback 为 false // $().on(event, false) if (callback === false) { callback = fnFalse; } if (one === 1) { var origCallback = callback; callback = function () { _this.off(eventName, selector, callback); return origCallback.apply(this, arguments); }; } return this.each(function () { add(this, eventName, callback, data, selector); }); }, /** * 绑定事件,åªè§¦å‘一次 * @param eventName * @param selector * @param data * @param callback */ one: function (eventName, selector, data, callback) { var _this = this; if (!isString(eventName)) { each(eventName, function (type, fn) { type.split(' ').forEach(function (eName) { _this.on(eName, selector, data, fn, 1); }); }); } else { eventName.split(' ').forEach(function (eName) { _this.on(eName, selector, data, callback, 1); }); } return this; }, /** * å–消绑定事件 * * $().off(eventName, selector); * $().off(eventName, callback); * $().off(eventName, false); * */ off: function (eventName, selector, callback) { var _this = this; // event 使用 事件:函数 键值对 // event = { // 'event1': callback1, // 'event2': callback2 // } // // $().off(event, selector) if (eventName && !isString(eventName)) { each(eventName, function (type, fn) { _this.off(type, selector, fn); }); return _this; } // selector ä¸å˜åœ¨ // $().off(event, callback) if (!isString(selector) && !isFunction(callback) && callback !== false) { callback = selector; selector = undefined; } // callback 为 false // $().off(event, false) if (callback === false) { callback = fnFalse; } return _this.each(function () { remove(this, eventName, callback, selector); }); }, /** * 触å‘一个事件 * @param eventName * @param data * @returns {*|JQ} */ trigger: function (eventName, data) { if (!isString(eventName)) { return; } var evt; try { evt = new CustomEvent(eventName, { detail: data, bubbles: true, cancelable: true }); } catch (e) { evt = document.createEvent('Event'); evt.initEvent(eventName, true, true); evt.detail = data; } evt._data = data; return this.each(function () { this.dispatchEvent(evt); }); }, }); /** * æ·»åŠ äº‹ä»¶ç›‘å¬ * @param element * @param eventName * @param func * @param data * @param selector */ function add(element, eventName, func, data, selector) { var elementId = getElementId(element); if (!handlers[elementId]) { handlers[elementId] = []; } // ä¼ å…¥ data.useCapture æ¥è®¾ç½® useCapture: true var useCapture = false; if (isObjectLike(data) && data.useCapture) { useCapture = true; } eventName.split(' ').forEach(function (event) { var handler = { e: event, fn: func, sel: selector, i: handlers[elementId].length, }; var callFn = function (e, ele) { var result = func.apply(ele, e._data === undefined ? [e] : [e].concat(e._data)); if (result === false) { e.preventDefault(); e.stopPropagation(); } }; var proxyfn = handler.proxy = function (e) { e.data = data; // äº‹ä»¶ä»£ç† if (selector) { $(element).find(selector).get().reverse().forEach(function (ele) { if (ele === e.target || $.contains(ele, e.target)) { callFn(e, ele); } }); } // ä¸ä½¿ç”¨äº‹ä»¶ä»£ç† else { callFn(e, element); } }; handlers[elementId].push(handler); element.addEventListener(handler.e, proxyfn, useCapture); }); } /** * ç§»é™¤äº‹ä»¶ç›‘å¬ * @param element * @param eventName * @param func * @param selector */ function remove(element, eventName, func, selector) { (eventName || '').split(' ').forEach(function (event) { getHandlers(element, event, func, selector).forEach(function (handler) { delete handlers[getElementId(element)][handler.i]; element.removeEventListener(handler.e, handler.proxy, false); }); }); } /** * ä¸ºå…ƒç´ èµ‹äºˆä¸€ä¸ªå”¯ä¸€çš„ID * @param element * @returns {number|*} */ function getElementId(element) { return element._elementId || (element._elementId = _elementId++); } /** * 获å–匹é…的事件 * @param element * @param eventName * @param func * @param selector * @returns {Array.<T>} */ function getHandlers(element, eventName, func, selector) { return (handlers[getElementId(element)] || []).filter(function (handler) { return handler && (!eventName || handler.e === eventName) && (!func || handler.fn.toString() === func.toString()) && (!selector || handler.sel === selector); }); } })(); /* jshint ignore:start */ return $; })(window, document); /* jshint ignore:end */ /** * ============================================================================= * ************ 定义全局å˜é‡ ************ * ============================================================================= */ var $body = $('body'); var $document = $(document); var $window = $(window); /** * 队列 -- 当å‰é˜Ÿåˆ—çš„ api å’Œ jquery ä¸ä¸€æ ·ï¼Œæ‰€ä»¥ä¸æ‰“包进 mdui.JQ 里 */ var queue = {}; (function () { var queueData = []; /** * 写入队列 * @param queueName 对列å * @param func 函数å,该å‚数为空时,返回所有队列 */ queue.queue = function (queueName, func) { if (queueData[queueName] === undefined) { queueData[queueName] = []; } if (func === undefined) { return queueData[queueName]; } queueData[queueName].push(func); }; /** * 从队列ä¸ç§»é™¤ç¬¬ä¸€ä¸ªå‡½æ•°ï¼Œå¹¶æ‰§è¡Œè¯¥å‡½æ•° * @param queueName */ queue.dequeue = function (queueName) { if (queueData[queueName] !== undefined && queueData[queueName].length) { (queueData[queueName].shift())(); } }; })(); /** * touch 事件åŽçš„ 500ms 内ç¦ç”¨ mousedown 事件 * * ä¸æ”¯æŒè§¦æŽ§çš„å±å¹•ä¸Šäº‹ä»¶é¡ºåºä¸º mousedown -> mouseup -> click * 支æŒè§¦æŽ§çš„å±å¹•ä¸Šäº‹ä»¶é¡ºåºä¸º touchstart -> touchend -> mousedown -> mouseup -> click */ var TouchHandler = { touches: 0, /** * 该事件是å¦è¢«å…许 * 在执行事件å‰è°ƒç”¨è¯¥æ–¹æ³•åˆ¤æ–事件是å¦å¯ä»¥æ‰§è¡Œ * @param e * @returns {boolean} */ isAllow: function (e) { var allow = true; if ( TouchHandler.touches && [ 'mousedown', 'mouseup', 'mousemove', 'click', 'mouseover', 'mouseout', 'mouseenter', 'mouseleave', ].indexOf(e.type) > -1 ) { // 触å‘了 touch 事件åŽé˜»æ¢é¼ æ ‡äº‹ä»¶ allow = false; } return allow; }, /** * 在 touchstart å’Œ touchmoveã€touchendã€touchcancel 事件ä¸è°ƒç”¨è¯¥æ–¹æ³•æ³¨å†Œäº‹ä»¶ * @param e */ register: function (e) { if (e.type === 'touchstart') { // 触å‘了 touch 事件 TouchHandler.touches += 1; } else if (['touchmove', 'touchend', 'touchcancel'].indexOf(e.type) > -1) { // touch äº‹ä»¶ç»“æŸ 500ms åŽè§£é™¤å¯¹é¼ æ ‡äº‹ä»¶çš„é˜»æ¢ setTimeout(function () { if (TouchHandler.touches) { TouchHandler.touches -= 1; } }, 500); } }, start: 'touchstart mousedown', move: 'touchmove mousemove', end: 'touchend mouseup', cancel: 'touchcancel mouseleave', unlock: 'touchend touchmove touchcancel', }; // 测试事件 // 在æ¯ä¸€ä¸ªäº‹ä»¶ä¸éƒ½ä½¿ç”¨ TouchHandler.isAllow(e) 判æ–事件是å¦å¯æ‰§è¡Œ // 在 touchstart å’Œ touchmoveã€touchendã€touchcancel // (function () { // // $document // .on(TouchHandler.start, function (e) { // if (!TouchHandler.isAllow(e)) { // return; // } // TouchHandler.register(e); // console.log(e.type); // }) // .on(TouchHandler.move, function (e) { // if (!TouchHandler.isAllow(e)) { // return; // } // console.log(e.type); // }) // .on(TouchHandler.end, function (e) { // if (!TouchHandler.isAllow(e)) { // return; // } // console.log(e.type); // }) // .on(TouchHandler.unlock, TouchHandler.register); // })(); $(function () { // é¿å…页é¢åŠ 载完åŽç›´æŽ¥æ‰§è¡Œcss动画 // https://css-tricks.com/transitions-only-after-page-load/ setTimeout(function () { $body.addClass('mdui-loaded'); }, 0); }); /** * ============================================================================= * ************ MDUI 内部使用的函数 ************ * ============================================================================= */ /** * è§£æž DATA API çš„å‚æ•° * @param str * @returns {*} */ var parseOptions = function (str) { var options = {}; if (str === null || !str) { return options; } if (typeof str === 'object') { return str; } /* jshint ignore:start */ var start = str.indexOf('{'); try { options = (new Function('', 'var json = ' + str.substr(start) + '; return JSON.parse(JSON.stringify(json));'))(); } catch (e) { } /* jshint ignore:end */ return options; }; /** * 绑定组件的事件 * @param eventName 事件å * @param pluginName æ’件å * @param inst æ’件实例 * @param trigger åœ¨è¯¥å…ƒç´ ä¸Šè§¦å‘ * @param obj 事件å‚æ•° */ var componentEvent = function (eventName, pluginName, inst, trigger, obj) { if (!obj) { obj = {}; } obj.inst = inst; var fullEventName = eventName + '.mdui.' + pluginName; // jQuery 事件 if (typeof jQuery !== 'undefined') { jQuery(trigger).trigger(fullEventName, obj); } // JQ 事件 $(trigger).trigger(fullEventName, obj); }; /** * ============================================================================= * ************ 开放的常用方法 ************ * ============================================================================= */ $.fn.extend({ /** * 执行强制é‡ç»˜ */ reflow: function () { return this.each(function () { return this.clientLeft; }); }, /** * 设置 transition 时间 * @param duration */ transition: function (duration) { if (typeof duration !== 'string') { duration = duration + 'ms'; } return this.each(function () { this.style.webkitTransitionDuration = duration; this.style.transitionDuration = duration; }); }, /** * transition 动画结æŸå›žè°ƒ * @param callback * @returns {transitionEnd} */ transitionEnd: function (callback) { var events = [ 'webkitTransitionEnd', 'transitionend', ]; var i; var _this = this; function fireCallBack(e) { if (e.target !== this) { return; } callback.call(this, e); for (i = 0; i < events.length; i++) { _this.off(events[i], fireCallBack); } } if (callback) { for (i = 0; i < events.length; i++) { _this.on(events[i], fireCallBack); } } return this; }, /** * 设置 transform-origin 属性 * @param transformOrigin */ transformOrigin: function (transformOrigin) { return this.each(function () { this.style.webkitTransformOrigin = transformOrigin; this.style.transformOrigin = transformOrigin; }); }, /** * 设置 transform 属性 * @param transform */ transform: function (transform) { return this.each(function () { this.style.webkitTransform = transform; this.style.transform = transform; }); }, }); $.extend({ /** * 创建并显示é®ç½© * @param zIndex é®ç½©å±‚çš„ z-index */ showOverlay: function (zIndex) { var $overlay = $('.mdui-overlay'); if ($overlay.length) { $overlay.data('isDeleted', 0); if (zIndex !== undefined) { $overlay.css('z-index', zIndex); } } else { if (zIndex === undefined) { zIndex = 2000; } $overlay = $('<div class="mdui-overlay">') .appendTo($body) .reflow() .css('z-index', zIndex); } var level = $overlay.data('overlay-level') || 0; return $overlay .data('overlay-level', ++level) .addClass('mdui-overlay-show'); }, /** * éšè—é®ç½©å±‚ * @param force 是å¦å¼ºåˆ¶éšè—é®ç½© */ hideOverlay: function (force) { var $overlay = $('.mdui-overlay'); if (!$overlay.length) { return; } var level = force ? 1 : $overlay.data('overlay-level'); if (level > 1) { $overlay.data('overlay-level', --level); return; } $overlay .data('overlay-level', 0) .removeClass('mdui-overlay-show') .data('isDeleted', 1) .transitionEnd(function () { if ($overlay.data('isDeleted')) { $overlay.remove(); } }); }, /** * é”定å±å¹• */ lockScreen: function () { // ä¸ç›´æŽ¥æŠŠ body 设为 box-sizing: border-box,é¿å…æ±¡æŸ“å…¨å±€æ ·å¼ var newBodyWidth = $body.width(); $body .addClass('mdui-locked') .width(newBodyWidth); var level = $body.data('lockscreen-level') || 0; $body.data('lockscreen-level', ++level); }, /** * 解除å±å¹•é”定 * @param force 是å¦å¼ºåˆ¶è§£é”å±å¹• */ unlockScreen: function (force) { var level = force ? 1 : $body.data('lockscreen-level'); if (level > 1) { $body.data('lockscreen-level', --level); return; } $body .data('lockscreen-level', 0) .removeClass('mdui-locked') .width(''); }, /** * å‡½æ•°èŠ‚æµ * @param fn * @param delay * @returns {Function} */ throttle: function (fn, delay) { var timer = null; if (!delay || delay < 16) { delay = 16; } return function () { var _this = this; var args = arguments; if (timer === null) { timer = setTimeout(function () { fn.apply(_this, args); timer = null; }, delay); } }; }, /** * 生æˆå”¯ä¸€ id * @param pluginName æ’件åï¼Œè‹¥ä¼ å…¥è¯¥å‚数,guid 将以该å‚数作为å‰ç¼€ * @returns {string} */ guid: function (pluginName) { function s4() { return Math.floor((1 + Math.random()) * 0x10000) .toString(16) .substring(1); } var guid = s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); if (pluginName) { guid = 'mdui-' + pluginName + '-' + guid; } return guid; }, }); /** * ============================================================================= * ************ Headroom.js ************ * ============================================================================= */ mdui.Headroom = (function () { /** * 默认å‚æ•° * @type {{}} */ var DEFAULT = { tolerance: 5, // 滚动æ¡æ»šåŠ¨å¤šå°‘è·ç¦»å¼€å§‹éšè—æˆ–æ˜¾ç¤ºå…ƒç´ ï¼Œ{down: num, up: num}ï¼Œæˆ–æ•°å— offset: 0, // 在页é¢é¡¶éƒ¨å¤šå°‘è·ç¦»å†…滚动ä¸ä¼šéšè—å…ƒç´ initialClass: 'mdui-headroom', // åˆå§‹åŒ–æ—¶æ·»åŠ çš„ç±» pinnedClass: 'mdui-headroom-pinned-top', // å…ƒç´ å›ºå®šæ—¶æ·»åŠ çš„ç±» unpinnedClass: 'mdui-headroom-unpinned-top', // å…ƒç´ éšè—æ—¶æ·»åŠ çš„ç±» }; /** * Headroom * @param selector * @param opts * @constructor */ function Headroom(selector, opts) { var _this = this; _this.$headroom = $(selector).eq(0); if (!_this.$headroom.length) { return; } // 已通过自定义属性实例化过,ä¸å†é‡å¤å®žä¾‹åŒ– var oldInst = _this.$headroom.data('mdui.headroom'); if (oldInst) { return oldInst; } _this.options = $.extend({}, DEFAULT, (opts || {})); // 数值转为 {down: bum, up: num} var tolerance = _this.options.tolerance; if (tolerance !== Object(tolerance)) { _this.options.tolerance = { down: tolerance, up: tolerance, }; } _this._init(); } /** * åˆå§‹åŒ– * @private */ Headroom.prototype._init = function () { var _this = this; _this.state = 'pinned'; _this.$headroom .addClass(_this.options.initialClass) .removeClass(_this.options.pinnedClass + ' ' + _this.options.unpinnedClass); _this.inited = false; _this.lastScrollY = 0; _this._attachEvent(); }; /** * 监å¬æ»šåŠ¨äº‹ä»¶ * @private */ Headroom.prototype._attachEvent = function () { var _this = this; if (!_this.inited) { _this.lastScrollY = window.pageYOffset; _this.inited = true; $window.on('scroll', function () { _this._scroll(); }); } }; /** * æ»šåŠ¨æ—¶çš„å¤„ç† * @private */ Headroom.prototype._scroll = function () { var _this = this; _this.rafId = window.requestAnimationFrame(function () { var currentScrollY = window.pageYOffset; var direction = currentScrollY > _this.lastScrollY ? 'down' : 'up'; var toleranceExceeded = Math.abs(currentScrollY - _this.lastScrollY) >= _this.options.tolerance[direction]; if ( currentScrollY > _this.lastScrollY && currentScrollY >= _this.options.offset && toleranceExceeded) { _this.unpin(); } else if ( (currentScrollY < _this.lastScrollY && toleranceExceeded) || currentScrollY <= _this.options.offset ) { _this.pin(); } _this.lastScrollY = currentScrollY; }); }; /** * 动画结æŸå›žè°ƒ * @param inst */ var transitionEnd = function (inst) { if (inst.state === 'pinning') { inst.state = 'pinned'; componentEvent('pinned', 'headroom', inst, inst.$headroom); } if (inst.state === 'unpinning') { inst.state = 'unpinned'; componentEvent('unpinned', 'headroom', inst, inst.$headroom); } }; /** * å›ºå®šä½ */ Headroom.prototype.pin = function () { var _this = this; if ( _this.state === 'pinning' || _this.state === 'pinned' || !_this.$headroom.hasClass(_this.options.initialClass) ) { return; } componentEvent('pin', 'headroom', _this, _this.$headroom); _this.state = 'pinning'; _this.$headroom .removeClass(_this.options.unpinnedClass) .addClass(_this.options.pinnedClass) .transitionEnd(function () { transitionEnd(_this); }); }; /** * ä¸å›ºå®šä½ */ Headroom.prototype.unpin = function () { var _this = this; if ( _this.state === 'unpinning' || _this.state === 'unpinned' || !_this.$headroom.hasClass(_this.options.initialClass) ) { return; } componentEvent('unpin', 'headroom', _this, _this.$headroom); _this.state = 'unpinning'; _this.$headroom .removeClass(_this.options.pinnedClass) .addClass(_this.options.unpinnedClass) .transitionEnd(function () { transitionEnd(_this); }); }; /** * å¯ç”¨ */ Headroom.prototype.enable = function () { var _this = this; if (!_this.inited) { _this._init(); } }; /** * ç¦ç”¨ */ Headroom.prototype.disable = function () { var _this = this; if (_this.inited) { _this.inited = false; _this.$headroom .removeClass([ _this.options.initialClass, _this.options.pinnedClass, _this.options.unpinnedClass, ].join(' ')); $window.off('scroll', function () { _this._scroll(); }); window.cancelAnimationFrame(_this.rafId); } }; /** * 获å–当å‰çŠ¶æ€ pinning | pinned | unpinning | unpinned */ Headroom.prototype.getState = function () { return this.state; }; return Headroom; })(); /** * ============================================================================= * ************ Headroom 自定义属性 API ************ * ============================================================================= */ $(function () { $('[mdui-headroom]').each(function () { var $this = $(this); var options = parseOptions($this.attr('mdui-headroom')); var inst = $this.data('mdui.headroom'); if (!inst) { inst = new mdui.Headroom($this, options); $this.data('mdui.headroom', inst); } }); }); /** * ============================================================================= * ************ ä¾› Collapse〠Panel 调用的折å 内容å—æ’件 ************ * ============================================================================= */ var CollapsePrivate = (function () { /** * 默认å‚æ•° */ var DEFAULT = { accordion: false, // 是å¦ä½¿ç”¨æ‰‹é£Žç´æ•ˆæžœ }; // ç±»å var CLASS = { item: 'mdui-collapse-item', // item ç±»å itemOpen: 'mdui-collapse-item-open', // 打开状æ€çš„ item header: 'mdui-collapse-item-header', // item ä¸çš„ header ç±»å body: 'mdui-collapse-item-body', // item ä¸çš„ body ç±»å }; // 命å空间 var NAMESPACE = 'collapse'; /** * 折å å†…å®¹å— * @param selector * @param opts * @param classes * @param namespace * @constructor */ function Collapse(selector, opts, classes, namespace) { var _this = this; _this.classes = $.extend({}, CLASS, classes || {}); _this.namespace = namespace ? namespace : NAMESPACE; // 折å é¢æ¿å…ƒç´ _this.$collapse = $(selector).eq(0); if (!_this.$collapse.length) { return; } // 已通过自定义属性实例化过,ä¸å†é‡å¤å®žä¾‹åŒ– var oldInst = _this.$collapse.data('mdui.' + _this.namespace); if (oldInst) { return oldInst; } _this.options = $.extend({}, DEFAULT, (opts || {})); _this.$collapse.on('click', '.' + _this.classes.header, function () { var $item = $(this).parent('.' + _this.classes.item); if (_this.$collapse.children($item).length) { _this.toggle($item); } }); } /** * 指定 item 是å¦å¤„äºŽæ‰“å¼€çŠ¶æ€ * @param $item * @returns {boolean} * @private */ Collapse.prototype._isOpen = function ($item) { return $item.hasClass(this.classes.itemOpen); }; /** * 获å–指定 item * @param item * @returns {*} * @private */ Collapse.prototype._getItem = function (item) { var _this = this; if (parseInt(item) === item) { // item æ˜¯ç´¢å¼•å· return _this.$collapse.children('.' + _this.classes.item).eq(item); } return $(item).eq(0); }; /** * 动画结æŸå›žè°ƒ * @param inst * @param $content * @param $item */ var transitionEnd = function (inst, $content, $item) { if (inst._isOpen($item)) { $content .transition(0) .height('auto') .reflow() .transition(''); componentEvent('opened', inst.namespace, inst, $item[0]); } else { $content.height(''); componentEvent('closed', inst.namespace, inst, $item[0]); } }; /** * 打开指定é¢æ¿é¡¹ * @param item é¢æ¿é¡¹çš„索引å·æˆ– DOM å…ƒç´ æˆ– CSS 选择器 */ Collapse.prototype.open = function (item) { var _this = this; var $item = _this._getItem(item); if (_this._isOpen($item)) { return; } // å…³é—其他项 if (_this.options.accordion) { _this.$collapse.children('.' + _this.classes.itemOpen).each(function () { var $tmpItem = $(this); if ($tmpItem !== $item) { _this.close($tmpItem); } }); } var $content = $item.children('.' + _this.classes.body); $content .height($content[0].scrollHeight) .transitionEnd(function () { transitionEnd(_this, $content, $item); }); componentEvent('open', _this.namespace, _this, $item[0]); $item.addClass(_this.classes.itemOpen); }; /** * å…³é—指定项 * @param item é¢æ¿é¡¹çš„索引å·æˆ– DOM å…ƒç´ æˆ– CSS 选择器 */ Collapse.prototype.close = function (item) { var _this = this; var $item = _this._getItem(item); if (!_this._isOpen($item)) { return; } var $content = $item.children('.' + _this.classes.body); componentEvent('close', _this.namespace, _this, $item[0]); $item.removeClass(_this.classes.itemOpen); $content .transition(0) .height($content[0].scrollHeight) .reflow() .transition('') .height('') .transitionEnd(function () { transitionEnd(_this, $content, $item); }); }; /** * 切æ¢æŒ‡å®šé¡¹çš„çŠ¶æ€ * @param item é¢æ¿é¡¹çš„索引å·æˆ– DOM å…ƒç´ æˆ– CSS 选择器或 JQ 对象 */ Collapse.prototype.toggle = function (item) { var _this = this; var $item = _this._getItem(item); if (_this._isOpen($item)) { _this.close($item); } else { _this.open($item); } }; /** * 打开所有项 */ Collapse.prototype.openAll = function () { var _this = this; _this.$collapse.children('.' + _this.classes.item).each(function () { var $tmpItem = $(this); if (!_this._isOpen($tmpItem)) { _this.open($tmpItem); } }); }; /** * å…³é—所有项 */ Collapse.prototype.closeAll = function () { var _this = this; _this.$collapse.children('.' + _this.classes.item).each(function () { var $tmpItem = $(this); if (_this._isOpen($tmpItem)) { _this.close($tmpItem); } }); }; return Collapse; })(); /** * ============================================================================= * ************ Collapse 折å 内容å—æ’件 ************ * ============================================================================= */ mdui.Collapse = (function () { function Collapse(selector, opts) { return new CollapsePrivate(selector, opts); } return Collapse; })(); /** * ============================================================================= * ************ Collapse 自定义属性 ************ * ============================================================================= */ $(function () { $('[mdui-collapse]').each(function () { var $this = $(this); var options = parseOptions($this.attr('mdui-collapse')); var inst = $this.data('mdui.collapse'); if (!inst) { inst = new mdui.Collapse($this, options); $this.data('mdui.collapse', inst); } }); }); /** * ============================================================================= * ************ Table è¡¨æ ¼ ************ * ============================================================================= */ (function () { /** * ç”Ÿæˆ checkbox çš„ HTML 结构 * @param tag * @returns {string} */ var checkboxHTML = function (tag) { return '<' + tag + ' class="mdui-table-cell-checkbox">' + '<label class="mdui-checkbox">' + '<input type="checkbox"/>' + '<i class="mdui-checkbox-icon"></i>' + '</label>' + '</' + tag + '>'; }; /** * Table è¡¨æ ¼ * @param selector * @constructor */ function Table(selector) { var _this = this; _this.$table = $(selector).eq(0); if (!_this.$table.length) { return; } _this.init(); } /** * åˆå§‹åŒ– */ Table.prototype.init = function () { var _this = this; _this.$thRow = _this.$table.find('thead tr'); _this.$tdRows = _this.$table.find('tbody tr'); _this.$tdCheckboxs = $(); _this.selectable = _this.$table.hasClass('mdui-table-selectable'); _this.selectedRow = 0; _this._updateThCheckbox(); _this._updateTdCheckbox(); _this._updateNumericCol(); }; /** * æ›´æ–°è¡¨æ ¼è¡Œçš„ checkbox */ Table.prototype._updateTdCheckbox = function () { var _this = this; _this.$tdRows.each(function () { var $tdRow = $(this); // 移除旧的 checkbox $tdRow.find('.mdui-table-cell-checkbox').remove(); if (!_this.selectable) { return; } // 创建 DOM var $checkbox = $(checkboxHTML('td')) .prependTo($tdRow) .find('input[type="checkbox"]'); // 默认选ä¸çš„è¡Œ if ($tdRow.hasClass('mdui-table-row-selected')) { $checkbox[0].checked = true; _this.selectedRow++; } // 所有行都选ä¸åŽï¼Œé€‰ä¸è¡¨å¤´ï¼›å¦åˆ™ï¼Œä¸é€‰ä¸è¡¨å¤´ _this.$thCheckbox[0].checked = _this.selectedRow === _this.$tdRows.length; // 绑定事件 $checkbox.on('change', function () { if ($checkbox[0].checked) { $tdRow.addClass('mdui-table-row-selected'); _this.selectedRow++; } else { $tdRow.removeClass('mdui-table-row-selected'); _this.selectedRow--; } // 所有行都选ä¸åŽï¼Œé€‰ä¸è¡¨å¤´ï¼›å¦åˆ™ï¼Œä¸é€‰ä¸è¡¨å¤´ _this.$thCheckbox[0].checked = _this.selectedRow === _this.$tdRows.length; }); _this.$tdCheckboxs = _this.$tdCheckboxs.add($checkbox); }); }; /** * 更新表头的 checkbox */ Table.prototype._updateThCheckbox = function () { var _this = this; // 移除旧的 checkbox _this.$thRow.find('.mdui-table-cell-checkbox').remove(); if (!_this.selectable) { return; } _this.$thCheckbox = $(checkboxHTML('th')) .prependTo(_this.$thRow) .find('input[type="checkbox"]') .on('change', function () { var isCheckedAll = _this.$thCheckbox[0].checked; _this.selectedRow = isCheckedAll ? _this.$tdRows.length : 0; _this.$tdCheckboxs.each(function (i, checkbox) { checkbox.checked = isCheckedAll; }); _this.$tdRows.each(function (i, row) { $(row)[isCheckedAll ? 'addClass' : 'removeClass']('mdui-table-row-selected'); }); }); }; /** * 更新数值列 */ Table.prototype._updateNumericCol = function () { var _this = this; var $th; var $tdRow; _this.$thRow.find('th').each(function (i, th) { $th = $(th); _this.$tdRows.each(function () { $tdRow = $(this); var method = $th.hasClass('mdui-table-col-numeric') ? 'addClass' : 'removeClass'; $tdRow.find('td').eq(i)[method]('mdui-table-col-numeric'); }); }); }; $(function () { // å®žä¾‹åŒ–è¡¨æ ¼ $('.mdui-table').each(function () { var $table = $(this); if (!$table.data('mdui.table')) { $table.data('mdui.table', new Table($table)); } }); }); /** * æ›´æ–°è¡¨æ ¼ */ mdui.updateTables = function () { $(arguments.length ? arguments[0] : '.mdui-table').each(function () { var $table = $(this); var inst = $table.data('mdui.table'); if (inst) { inst.init(); } else { $table.data('mdui.table', new Table($table)); } }); }; })(); /** * ============================================================================= * ************ 涟漪 ************ * ============================================================================= * * Inspired by https://github.com/nolimits4web/Framework7/blob/master/src/js/fast-clicks.js * https://github.com/nolimits4web/Framework7/blob/master/LICENSE * * Inspired by https://github.com/fians/Waves */ (function () { var Ripple = { /** * 显示涟漪动画 * @param e * @param $ripple */ show: function (e, $ripple) { // é¼ æ ‡å³é”®ä¸äº§ç”Ÿæ¶Ÿæ¼ª if (e.button === 2) { return; } // 点击ä½ç½®åæ ‡ var tmp; if ('touches' in e && e.touches.length) { tmp = e.touches[0]; } else { tmp = e; } var touchStartX = tmp.pageX; var touchStartY = tmp.pageY; // 涟漪ä½ç½® var offset = $ripple.offset(); var center = { x: touchStartX - offset.left, y: touchStartY - offset.top, }; var height = $ripple.innerHeight(); var width = $ripple.innerWidth(); var diameter = Math.max( Math.pow((Math.pow(height, 2) + Math.pow(width, 2)), 0.5), 48 ); // 涟漪扩散动画 var translate = 'translate3d(' + (-center.x + width / 2) + 'px, ' + (-center.y + height / 2) + 'px, 0) ' + 'scale(1)'; // 涟漪的 DOM 结构 $('<div class="mdui-ripple-wave" style="' + 'width: ' + diameter + 'px; ' + 'height: ' + diameter + 'px; ' + 'margin-top:-' + diameter / 2 + 'px; ' + 'margin-left:-' + diameter / 2 + 'px; ' + 'left:' + center.x + 'px; ' + 'top:' + center.y + 'px;">' + '</div>') // 缓å˜åŠ¨ç”»æ•ˆæžœ .data('translate', translate) .prependTo($ripple) .reflow() .transform(translate); }, /** * éšè—涟漪动画 */ hide: function () { var $ripple = $(this); $ripple.children('.mdui-ripple-wave').each(function () { removeRipple($(this)); }); $ripple.off('touchmove touchend touchcancel mousemove mouseup mouseleave', Ripple.hide); }, }; /** * éšè—并移除涟漪 * @param $wave */ function removeRipple($wave) { if (!$wave.length || $wave.data('isRemoved')) { return; } $wave.data('isRemoved', true); var removeTimeout = setTimeout(function () { $wave.remove(); }, 400); var translate = $wave.data('translate'); $wave .addClass('mdui-ripple-wave-fill') .transform(translate.replace('scale(1)', 'scale(1.01)')) .transitionEnd(function () { clearTimeout(removeTimeout); $wave .addClass('mdui-ripple-wave-out') .transform(translate.replace('scale(1)', 'scale(1.01)')); removeTimeout = setTimeout(function () { $wave.remove(); }, 700); setTimeout(function () { $wave.transitionEnd(function () { clearTimeout(removeTimeout); $wave.remove(); }); }, 0); }); } /** * 显示涟漪,并绑定 touchend ç‰äº‹ä»¶ * @param e */ function showRipple(e) { if (!TouchHandler.isAllow(e)) { return; } TouchHandler.register(e); var $ripple; var $target = $(e.target); // 获å–å« .mdui-ripple ç±»çš„å…ƒç´ if ($target.hasClass('mdui-ripple')) { $ripple = $target; } else { $ripple = $target.parents('.mdui-ripple').eq(0); } if ($ripple.length) { // ç¦ç”¨çŠ¶æ€çš„å…ƒç´ ä¸Šä¸äº§ç”Ÿæ¶Ÿæ¼ªæ•ˆæžœ if ($ripple[0].disabled || $ripple.attr('disabled') !== null) { return; } Ripple.show(e, $ripple); $ripple.on('touchmove touchend touchcancel mousemove mouseup mouseleave', Ripple.hide); } } // åˆå§‹åŒ–绑定的事件 $document .on(TouchHandler.start, showRipple) .on(TouchHandler.unlock, TouchHandler.register); })(); /** * ============================================================================= * ************ Text Field 文本框 ************ * ============================================================================= */ (function () { var getProp = function (obj, prop) { return ( typeof obj === 'object' && obj !== null && typeof obj[prop] !== 'undefined' && obj[prop] ) ? obj[prop] : false; }; /** * 输入框事件 * @param e */ var inputEvent = function (e) { var input = e.target; var $input = $(input); var event = e.type; var value = $input.val(); // reInit 为 true 时,需è¦é‡æ–°åˆå§‹åŒ–文本框 var reInit = getProp(e.detail, 'reInit'); // domLoadedEvent 为 true 时,为 DOM åŠ è½½å®Œæ¯•åŽè‡ªåŠ¨è§¦å‘的事件 var domLoadedEvent = getProp(e.detail, 'domLoadedEvent'); // 文本框类型 var type = $input.attr('type') || ''; if (['checkbox', 'button', 'submit', 'range', 'radio', 'image'].indexOf(type) >= 0) { return; } var $textField = $input.parent('.mdui-textfield'); // 输入框是å¦èšç„¦ if (event === 'focus') { $textField.addClass('mdui-textfield-focus'); } if (event === 'blur') { $textField.removeClass('mdui-textfield-focus'); } // 输入框是å¦ä¸ºç©º if (event === 'blur' || event === 'input') { $textField[(value && value !== '') ? 'addClass' : 'removeClass']('mdui-textfield-not-empty'); } // 输入框是å¦ç¦ç”¨ $textField[input.disabled ? 'addClass' : 'removeClass']('mdui-textfield-disabled'); // 表å•éªŒè¯ if ((event === 'input' || event === 'blur') && !domLoadedEvent) { if (input.validity) { $textField[input.validity.valid ? 'removeClass' : 'addClass']('mdui-textfield-invalid'); } } // textarea 高度自动调整 if (e.target.nodeName.toLowerCase() === 'textarea') { $input.height(''); var height = input.offsetHeight; var diff = height - input.clientHeight; var scrollHeight = input.scrollHeight; if (scrollHeight + diff > height) { var newAreaHeight = scrollHeight + diff; $input.height(newAreaHeight); } } // 实时å—数统计 if (reInit) { $textField .removeClass('mdui-textfield-has-counter') .find('.mdui-textfield-counter') .remove(); } var maxlength = $input.attr('maxlength'); if (maxlength) { if (reInit || domLoadedEvent) { $('<div class="mdui-textfield-counter">' + '<span class="mdui-textfield-counter-inputed"></span> / ' + maxlength + '</div>').appendTo($textField); // 如果没有 .mdui-textfield-error 作为å ä½ï¼Œéœ€è¦å¢žåŠ .mdui-textfield 的下边è·ï¼Œ // 使 .mdui-textfield-counter ä¸ä¼šè¦†ç›–在文本框上 if (!$textField.find('.mdui-textfield-error').length) { $textField.addClass('mdui-textfield-has-counter'); } } // å—符长度,确ä¿ç»Ÿè®¡æ–¹å¼å’Œ maxlength 一致 var inputed = value.length + value.split('\n').length - 1; $textField.find('.mdui-textfield-counter-inputed').text(inputed.toString()); } }; // 绑定事件 $document.on('input focus blur', '.mdui-textfield-input', { useCapture: true }, inputEvent); // å¯å±•å¼€æ–‡æœ¬æ¡†å±•å¼€ $document.on('click', '.mdui-textfield-expandable .mdui-textfield-icon', function () { $(this) // 展开文本框 .parents('.mdui-textfield') .addClass('mdui-textfield-expanded') // èšç„¦åˆ°è¾“入框 .find('.mdui-textfield-input')[0].focus(); }); // å¯å±•å¼€æ–‡æœ¬æ¡†å…³é— $document.on('click', '.mdui-textfield-expanded .mdui-textfield-close', function () { $(this) // å…³é—文本框 .parents('.mdui-textfield') .removeClass('mdui-textfield-expanded') // 清空输入框 .find('.mdui-textfield-input') .val(''); }); /** * 通过 JS 更新了表å•å†…容,需è¦é‡æ–°è¿›è¡Œè¡¨å•å¤„ç† * @param- å¦‚æžœä¼ å…¥äº† .mdui-textfield 所在的 DOM å…ƒç´ ï¼Œåˆ™æ›´æ–°è¯¥æ–‡æœ¬æ¡†ï¼›å¦åˆ™ï¼Œæ›´æ–°æ‰€æœ‰æ–‡æœ¬æ¡† */ mdui.updateTextFields = function () { $(arguments.length ? arguments[0] : '.mdui-textfield').each(function () { $(this) .find('.mdui-textfield-input') .trigger('input', { reInit: true, }); }); }; $(function () { // DOM åŠ è½½å®ŒåŽè‡ªåŠ¨æ‰§è¡Œ $('.mdui-textfield-input').each(function () { $(this).trigger('input', { domLoadedEvent: true, }); }); }); })(); /** * ============================================================================= * ************ Slider æ»‘å— ************ * ============================================================================= */ (function () { /** * 滑å—的值å˜æ›´åŽä¿®æ”¹æ»‘å—æ ·å¼ * @param $slider */ var updateValueStyle = function ($slider) { var data = $slider.data(); var $track = data.$track; var $fill = data.$fill; var $thumb = data.$thumb; var $input = data.$input; var min = data.min; var max = data.max; var isDisabled = data.disabled; var isDiscrete = data.discrete; var $thumbText = data.$thumbText; var value = $input.val(); var percent = (value - min) / (max - min) * 100; $fill.width(percent + '%'); $track.width((100 - percent) + '%'); if (isDisabled) { $fill.css('padding-right', '6px'); $track.css('padding-left', '6px'); } $thumb.css('left', percent + '%'); if (isDiscrete) { $thumbText.text(value); } $slider[parseFloat(percent) === 0 ? 'addClass' : 'removeClass']('mdui-slider-zero'); }; /** * é‡æ–°åˆå§‹åŒ– * @param $slider */ var reInit = function ($slider) { var $track = $('<div class="mdui-slider-track"></div>'); var $fill = $('<div class="mdui-slider-fill"></div>'); var $thumb = $('<div class="mdui-slider-thumb"></div>'); var $input = $slider.find('input[type="range"]'); // ç¦ç”¨çŠ¶æ€ var isDisabled = $input[0].disabled; $slider[isDisabled ? 'addClass' : 'removeClass']('mdui-slider-disabled'); // é‡æ–°å¡«å…… HTML $slider.find('.mdui-slider-track').remove(); $slider.find('.mdui-slider-fill').remove(); $slider.find('.mdui-slider-thumb').remove(); $slider.append($track).append($fill).append($thumb); // é—´ç»åž‹æ»‘å— var isDiscrete = $slider.hasClass('mdui-slider-discrete'); var $thumbText; if (isDiscrete) { $thumbText = $('<span></span>'); $thumb.empty().append($thumbText); } $slider.data({ $track: $track, $fill: $fill, $thumb: $thumb, $input: $input, min: $input.attr('min'), // 滑å—最å°å€¼ max: $input.attr('max'), // 滑å—最大值 disabled: isDisabled, nbsp; // 是å¦ç¦ç”¨çŠ¶æ€ discrete: isDiscrete, // 是å¦æ˜¯é—´ç»åž‹æ»‘å— $thumbText: $thumbText, // é—´ç»åž‹æ»‘å—的数值 }); // 设置默认值 updateValueStyle($slider); }; var rangeSelector = '.mdui-slider input[type="range"]'; $document // 滑动滑å—事件 .on('input change', rangeSelector, function () { var $slider = $(this).parent(); updateValueStyle($slider); }) // 开始触摸滑å—事件 .on(TouchHandler.start, rangeSelector, function (e) { if (!TouchHandler.isAllow(e)) { return; } TouchHandler.register(e); if (!this.disabled) { var $slider = $(this).parent(); $slider.addClass('mdui-slider-focus'); } }) // 结æŸè§¦æ‘¸æ»‘å—事件 .on(TouchHandler.end, rangeSelector, function (e) { if (!TouchHandler.isAllow(e)) { return; } if (!this.disabled) { var $slider = $(this).parent(); $slider.removeClass('mdui-slider-focus'); } }) .on(TouchHandler.unlock, rangeSelector, TouchHandler.register); /** * 页é¢åŠ 载完åŽè‡ªåŠ¨åˆå§‹åŒ– */ $(function () { $('.mdui-slider').each(function () { reInit($(this)); }); }); /** * é‡æ–°åˆå§‹åŒ–æ»‘å— */ mdui.updateSliders = function () { $(arguments.length ? arguments[0] : '.mdui-slider').each(function () { reInit($(this)); }); }; })(); /** * ============================================================================= * ************ Fab 浮动æ“作按钮 ************ * ============================================================================= */ mdui.Fab = (function () { /** * 默认å‚æ•° * @type {{}} */ var DEFAULT = { trigger: 'hover', // 触å‘æ–¹å¼ ['hover', 'click'] }; /** * 浮动æ“作按钮实例 * @param selector 选择器或 HTML å—符串或 DOM å…ƒç´ æˆ– JQ 对象 * @param opts * @constructor */ function Fab(selector, opts) { var _this = this; _this.$fab = $(selector).eq(0); if (!_this.$fab.length) { return; } // 已通过 data 属性实例化过,ä¸å†é‡å¤å®žä¾‹åŒ– var oldInst = _this.$fab.data('mdui.fab'); if (oldInst) { return oldInst; } _this.options = $.extend({}, DEFAULT, (opts || {})); _this.state = 'closed'; _this.$btn = _this.$fab.find('.mdui-fab'); _this.$dial = _this.$fab.find('.mdui-fab-dial'); _this.$dialBtns = _this.$dial.find('.mdui-fab'); if (_this.options.trigger === 'hover') { _this.$btn .on('touchstart mouseenter', function () { _this.open(); }); _this.$fab .on('mouseleave', function () { _this.close(); }); } if (_this.options.trigger === 'click') { _this.$btn .on(TouchHandler.start, function () { _this.open(); }); } // 触摸å±å¹•å…¶ä»–地方关é—å¿«é€Ÿæ‹¨å· $document.on(TouchHandler.start, function (e) { if (!$(e.target).parents('.mdui-fab-wrapper').length) { _this.close(); } }); } /** * 打开èœå• */ Fab.prototype.open = function () { var _this = this; if (_this.state === 'opening' || _this.state === 'opened') { return; } // 为èœå•ä¸çš„æŒ‰é’®æ·»åŠ ä¸åŒçš„ transition-delay _this.$dialBtns.each(function (index, btn) { btn.style['transition-delay'] = btn.style['-webkit-transition-delay'] = 15 * (_this.$dialBtns.length - index) + 'ms'; }); _this.$dial.addClass('mdui-fab-dial-show'); // 如果按钮ä¸å˜åœ¨ .mdui-fab-opened çš„å›¾æ ‡ï¼Œåˆ™è¿›è¡Œå›¾æ ‡åˆ‡æ¢ if (_this.$btn.find('.mdui-fab-opened').length) { _this.$btn.addClass('mdui-fab-opened'); } _this.state = 'opening'; componentEvent('open', 'fab', _this, _this.$fab); // 打开顺åºä¸ºä»Žä¸‹åˆ°ä¸Šé€ä¸ªæ‰“开,最上é¢çš„打开åŽæ‰è¡¨ç¤ºåŠ¨ç”»å®Œæˆ _this.$dialBtns.eq(0).transitionEnd(function () { if (_this.$btn.hasClass('mdui-fab-opened')) { _this.state = 'opened'; componentEvent('opened', 'fab', _this, _this.$fab); } }); }; /** * å…³é—èœå• */ Fab.prototype.close = function () { var _this = this; if (_this.state === 'closing' || _this.state === 'closed') { return; } // 为èœå•ä¸çš„æŒ‰é’®æ·»åŠ ä¸åŒçš„ transition-delay _this.$dialBtns.each(function (index, btn) { btn.style['transition-delay'] = btn.style['-webkit-transition-delay'] = 15 * index + 'ms'; }); _this.$dial.removeClass('mdui-fab-dial-show'); _this.$btn.removeClass('mdui-fab-opened'); _this.state = 'closing'; componentEvent('close', 'fab', _this, _this.$fab); // 从上往下ä¾æ¬¡å…³é—,最åŽä¸€ä¸ªå…³é—åŽæ‰è¡¨ç¤ºåŠ¨ç”»å®Œæˆ _this.$dialBtns.eq(-1).transitionEnd(function () { if (!_this.$btn.hasClass('mdui-fab-opened')) { _this.state = 'closed'; componentEvent('closed', 'fab', _this, _this.$fab); } }); }; /** * 切æ¢èœå•çš„æ‰“å¼€çŠ¶æ€ */ Fab.prototype.toggle = function () { var _this = this; if (_this.state === 'opening' || _this.state === 'opened') { _this.close(); } else if (_this.state === 'closing' || _this.state === 'closed') { _this.open(); } }; /** * 获å–当å‰èœå•çŠ¶æ€ * @returns {'opening'|'opened'|'closing'|'closed'} */ Fab.prototype.getState = function () { return this.state; }; /** * 以动画的形å¼æ˜¾ç¤ºæµ®åŠ¨æ“作按钮 */ Fab.prototype.show = function () { this.$fab.removeClass('mdui-fab-hide'); }; /** * 以动画的形å¼éšè—浮动æ“作按钮 */ Fab.prototype.hide = function () { this.$fab.addClass('mdui-fab-hide'); }; return Fab; })(); /** * ============================================================================= * ************ Fab DATA API ************ * ============================================================================= */ $(function () { // mouseenter ä¸å†’æ³¡ï¼Œæ— æ³•è¿›è¡Œäº‹ä»¶å§”æ‰˜ï¼Œè¿™é‡Œç”¨ mouseover 代替。 // ä¸ç®¡æ˜¯ click 〠mouseover 还是 touchstart ,都先åˆå§‹åŒ–。 $document.on('touchstart mousedown mouseover', '[mdui-fab]', function (e) { var $this = $(this); var inst = $this.data('mdui.fab'); if (!inst) { var options = parseOptions($this.attr('mdui-fab')); inst = new mdui.Fab($this, options); $this.data('mdui.fab', inst); } }); }); /** * ============================================================================= * ************ Appbar ************ * ============================================================================= * 滚动时自动éšè—应用æ * mdui-appbar-scroll-hide * mdui-appbar-scroll-toolbar-hide */ $(function () { // 滚动时éšè—应用æ $('.mdui-appbar-scroll-hide').each(function () { var $this = $(this); $this.data('mdui.headroom', new mdui.Headroom($this)); }); // 滚动时åªéšè—应用æ ä¸çš„工具æ $('.mdui-appbar-scroll-toolbar-hide').each(function () { var $this = $(this); var inst = new mdui.Headroom($this, { pinnedClass: 'mdui-headroom-pinned-toolbar', unpinnedClass: 'mdui-headroom-unpinned-toolbar', }); $this.data('mdui.headroom', inst); }); }); /** * ============================================================================= * ************ Tab ************ * ============================================================================= */ mdui.Tab = (function () { var DEFAULT = { trigger: 'click', // 触å‘æ–¹å¼ click: é¼ æ ‡ç‚¹å‡»åˆ‡æ¢ hover: é¼ æ ‡æ‚¬æµ®åˆ‡æ¢ //animation: false, // 切æ¢æ—¶æ˜¯å¦æ˜¾ç¤ºåŠ¨ç”» loop: false, // 为true时,在最åŽä¸€ä¸ªé€‰é¡¹å¡æ—¶è°ƒç”¨ next() æ–¹æ³•ä¼šå›žåˆ°ç¬¬ä¸€ä¸ªé€‰é¡¹å¡ }; // å…ƒç´ æ˜¯å¦å·²ç¦ç”¨ var isDisabled = function ($ele) { return $ele[0].disabled || $ele.attr('disabled') !== null; }; /** * é€‰é¡¹å¡ * @param selector * @param opts * @returns {*} * @constructor */ function Tab(selector, opts) { var _this = this; _this.$tab = $(selector).eq(0); if (!_this.$tab.length) { return; } // 已通过自定义属性实例化过,ä¸å†é‡å¤å®žä¾‹åŒ– var oldInst = _this.$tab.data('mdui.tab'); if (oldInst) { return oldInst; } _this.options = $.extend({}, DEFAULT, (opts || {})); _this.$tabs = _this.$tab.children('a'); _this.$indicator = $('<div class="mdui-tab-indicator"></div>').appendTo(_this.$tab); _this.activeIndex = false; // æ ¹æ® url hash 获å–é»˜è®¤æ¿€æ´»çš„é€‰é¡¹å¡ var hash = location.hash; if (hash) { _this.$tabs.each(function (i, tab) { if ($(tab).attr('href') === hash) { _this.activeIndex = i; return false; } }); } // å« mdui-tab-active çš„å…ƒç´ é»˜è®¤æ¿€æ´» if (_this.activeIndex === false) { _this.$tabs.each(function (i, tab) { if ($(tab).hasClass('mdui-tab-active')) { _this.activeIndex = i; return false; } }); } // é»˜è®¤æ¿€æ´»ç¬¬ä¸€ä¸ªé€‰é¡¹å¡ if (_this.activeIndex === false) { _this.activeIndex = 0; } // 设置激活状æ€é€‰é¡¹å¡ _this._setActive(); // 监å¬çª—å£å¤§å°å˜åŒ–事件,调整指示器ä½ç½® $window.on('resize', $.throttle(function () { _this._setIndicatorPosition(); }, 100)); // 监å¬ç‚¹å‡»é€‰é¡¹å¡äº‹ä»¶ _this.$tabs.each(function (i, tab) { var $tab = $(tab); // ç‚¹å‡»æˆ–é¼ æ ‡ç§»å…¥è§¦å‘的事件 var clickEvent = function (e) { // ç¦ç”¨çŠ¶æ€çš„é€‰é¡¹æ— æ³•é€‰ä¸ if (isDisabled($tab)) { e.preventDefault(); return; } _this.activeIndex = i; _this._setActive(); }; // æ— è®º trigger 是 click 还是 hover,都会å“应 click 事件 $tab.on('click', clickEvent); // trigger 为 hover 时,é¢å¤–å“应 mouseenter 事件 if (_this.options.trigger === 'hover') { $tab.on('mouseenter', clickEvent); } $tab.on('click', function (e) { // 阻æ¢é“¾æŽ¥çš„默认点击动作 if ($tab.attr('href').indexOf('#') === 0) { e.preventDefault(); } }); }); } /** * 设置激活状æ€çš„é€‰é¡¹å¡ */ Tab.prototype._setActive = function () { var _this = this; _this.$tabs.each(function (i, tab) { var $tab = $(tab); var targetId = $tab.attr('href'); // 设置选项å¡æ¿€æ´»çŠ¶æ€ if (i === _this.activeIndex && !isDisabled($tab)) { if (!$tab.hasClass('mdui-tab-active')) { componentEvent('change', 'tab', _this, _this.$tab, { index: _this.activeIndex, target: tab, }); componentEvent('show', 'tab', _this, $tab); $tab.addClass('mdui-tab-active'); } $(targetId).show(); _this._setIndicatorPosition(); } else { $tab.removeClass('mdui-tab-active'); $(targetId).hide(); } }); }; /** * 设置选项å¡æŒ‡ç¤ºå™¨çš„ä½ç½® */ Tab.prototype._setIndicatorPosition = function () { var _this = this; var $activeTab = _this.$tabs.eq(_this.activeIndex); if (isDisabled($activeTab)) { return; } var activeTabOffset = $activeTab.offset(); _this.$indicator.css({ left: activeTabOffset.left + _this.$tab[0].scrollLeft - _this.$tab[0].getBoundingClientRect().left + 'px', width: $activeTab.width() + 'px', }); }; /** * 切æ¢åˆ°ä¸‹ä¸€ä¸ªé€‰é¡¹å¡ */ Tab.prototype.next = function () { var _this = this; if (_this.$tabs.length > _this.activeIndex + 1) { _this.activeIndex++; } else if (_this.options.loop) { _this.activeIndex = 0; } _this._setActive(); }; /** * 切æ¢åˆ°ä¸Šä¸€ä¸ªé€‰é¡¹å¡ */ Tab.prototype.prev = function () { var _this = this; if (_this.activeIndex > 0) { _this.activeIndex--; } else if (_this.options.loop) { _this.activeIndex = _this.$tabs.length - 1; } _this._setActive(); }; /** * 显示指定åºå·æˆ–指定idçš„é€‰é¡¹å¡ * @param index 从0开始的åºå·ï¼Œæˆ–以#开头的id */ Tab.prototype.show = function (index) { var _this = this; if (parseInt(index) === index) { _this.activeIndex = index; } else { _this.$tabs.each(function (i, tab) { if (tab.id === index) { _this.activeIndex = i; return false; } }); } _this._setActive(); }; /** * åœ¨çˆ¶å…ƒç´ çš„å®½åº¦å˜åŒ–时,需è¦è°ƒç”¨è¯¥æ–¹æ³•é‡æ–°è°ƒæ•´æŒ‡ç¤ºå™¨ä½ç½® */ Tab.prototype.handleUpdate = function () { this._setIndicatorPosition(); }; return Tab; })(); /** * ============================================================================= * ************ Tab 自定义属性 API ************ * ============================================================================= */ $(function () { $('[mdui-tab]').each(function () { var $this = $(this); var inst = $this.data('mdui.tab'); if (!inst) { inst = new mdui.Tab($this, parseOptions($this.attr('mdui-tab'))); $this.data('mdui.tab', inst); } }); }); /** * ============================================================================= * ************ Drawer 抽屉æ ************ * ============================================================================= * * 在桌é¢è®¾å¤‡ä¸Šé»˜è®¤æ˜¾ç¤ºæŠ½å±‰æ ,ä¸æ˜¾ç¤ºé®ç½©å±‚ * 在手机和平æ¿è®¾å¤‡ä¸Šé»˜è®¤ä¸æ˜¾ç¤ºæŠ½å±‰æ ,始终显示é®ç½©å±‚,且覆盖导航æ */ mdui.Drawer = (function () { /** * 默认å‚æ•° * @type {{}} */ var DEFAULT = { // 在桌é¢è®¾å¤‡ä¸Šæ˜¯å¦æ˜¾ç¤ºé®ç½©å±‚。手机和平æ¿ä¸å—这个å‚æ•°å½±å“,始终会显示é®ç½©å±‚ overlay: false, }; var isDesktop = function () { return $window.width() >= 1024; }; /** * 抽屉æ 实例 * @param selector 选择器或 HTML å—符串或 DOM å…ƒç´ * @param opts * @constructor */ function Drawer(selector, opts) { var _this = this; _this.$drawer = $(selector).eq(0); if (!_this.$drawer.length) { return; } var oldInst = _this.$drawer.data('mdui.drawer'); if (oldInst) { return oldInst; } _this.options = $.extend({}, DEFAULT, (opts || {})); _this.overlay = false; // 是å¦æ˜¾ç¤ºç€é®ç½©å±‚ _this.position = _this.$drawer.hasClass('mdui-drawer-right') ? 'right' : 'left'; if (_this.$drawer.hasClass('mdui-drawer-close')) { _this.state = 'closed'; } else if (_this.$drawer.hasClass('mdui-drawer-open')) { _this.state = 'opened'; } else if (isDesktop()) { _this.state = 'opened'; } else { _this.state = 'closed'; } // æµè§ˆå™¨çª—å£å¤§å°è°ƒæ•´æ—¶ $window.on('resize', $.throttle(function () { // 由手机平æ¿åˆ‡æ¢åˆ°æ¡Œé¢æ—¶ if (isDesktop()) { // 如果显示ç€é®ç½©ï¼Œåˆ™éšè—é®ç½© if (_this.overlay && !_this.options.overlay) { $.hideOverlay(); _this.overlay = false; $.unlockScreen(); } // 没有强制关é—,则状æ€ä¸ºæ‰“å¼€çŠ¶æ€ if (!_this.$drawer.hasClass('mdui-drawer-close')) { _this.state = 'opened'; } } // 由桌é¢åˆ‡æ¢åˆ°æ‰‹æœºå¹³æ¿æ—¶ã€‚如果抽屉æ 是打开ç€çš„且没有é®ç½©å±‚,则关é—抽屉æ else { if (!_this.overlay && _this.state === 'opened') { // 抽屉æ 处于强制打开状æ€ï¼Œæ·»åŠ é®ç½© if (_this.$drawer.hasClass('mdui-drawer-open')) { $.showOverlay(); _this.overlay = true; $.lockScreen(); $('.mdui-overlay').one('click', function () { _this.close(); }); } else { _this.state = 'closed'; } } } }, 100)); // 绑定关é—按钮事件 _this.$drawer.find('[mdui-drawer-close]').each(function () { $(this).on('click', function () { _this.close(); }); }); } /** * 动画结æŸå›žè°ƒ * @param inst */ var transitionEnd = function (inst) { if (inst.$drawer.hasClass('mdui-drawer-open')) { inst.state = 'opened'; componentEvent('opened', 'drawer', inst, inst.$drawer); } else { inst.state = 'closed'; componentEvent('closed', 'drawer', inst, inst.$drawer); } }; /** * 打开抽屉æ */ Drawer.prototype.open = function () { var _this = this; if (_this.state === 'opening' || _this.state === 'opened') { return; } _this.state = 'opening'; componentEvent('open', 'drawer', _this, _this.$drawer); if (!_this.options.overlay) { $body.addClass('mdui-drawer-body-' + _this.position); } _this.$drawer .removeClass('mdui-drawer-close') .addClass('mdui-drawer-open') .transitionEnd(function () { transitionEnd(_this); }); if (!isDesktop() || _this.options.overlay) { _this.overlay = true; $.showOverlay().one('click', function () { _this.close(); }); $.lockScreen(); } }; /** * å…³é—抽屉æ */ Drawer.prototype.close = function () { var _this = this; if (_this.state === 'closing' || _this.state === 'closed') { return; } _this.state = 'closing'; componentEvent('close', 'drawer', _this, _this.$drawer); if (!_this.options.overlay) { $body.removeClass('mdui-drawer-body-' + _this.position); } _this.$drawer .addClass('mdui-drawer-close') .removeClass('mdui-drawer-open') .transitionEnd(function () { transitionEnd(_this); }); if (_this.overlay) { $.hideOverlay(); _this.overlay = false; $.unlockScreen(); } }; /** * 切æ¢æŠ½å±‰æ 打开/å…³é—çŠ¶æ€ */ Drawer.prototype.toggle = function () { var _this = this; if (_this.state === 'opening' || _this.state === 'opened') { _this.close(); } else if (_this.state === 'closing' || _this.state === 'closed') { _this.open(); } }; /** * 获å–抽屉æ çŠ¶æ€ * @returns {'opening'|'opened'|'closing'|'closed'} */ Drawer.prototype.getState = function () { return this.state; }; return Drawer; })(); /** * ============================================================================= * ************ Drawer 自定义属性 API ************ * ============================================================================= */ $(function () { $('[mdui-drawer]').each(function () { var $this = $(this); var options = parseOptions($this.attr('mdui-drawer')); var selector = options.target; delete options.target; var $drawer = $(selector).eq(0); var inst = $drawer.data('mdui.drawer'); if (!inst) { inst = new mdui.Drawer($drawer, options); $drawer.data('mdui.drawer', inst); } $this.on('click', function () { inst.toggle(); }); }); }); /** * ============================================================================= * ************ Dialog 对è¯æ¡† ************ * ============================================================================= */ mdui.Dialog = (function () { /** * 默认å‚æ•° */ var DEFAULT = { history: true, // ç›‘å¬ hashchange 事件 overlay: true, // 打开对è¯æ¡†æ—¶æ˜¯å¦æ˜¾ç¤ºé®ç½© modal: false, // 是å¦æ¨¡æ€åŒ–对è¯æ¡†ï¼Œä¸º false 时点击对è¯æ¡†å¤–é¢åŒºåŸŸå…³é—对è¯æ¡†ï¼Œä¸º true æ—¶ä¸å…³é— closeOnEsc: true, // 按下 esc å…³é—对è¯æ¡† closeOnCancel: true, // 按下å–消按钮时关é—对è¯æ¡† closeOnConfirm: true, // 按下确认按钮时关é—对è¯æ¡† destroyOnClosed: false, // å…³é—åŽé”€æ¯ }; /** * é®ç½©å±‚å…ƒç´ */ var $overlay; /** * 窗å£æ˜¯å¦å·²é”定 */ var isLockScreen; /** * 当å‰å¯¹è¯æ¡†å®žä¾‹ */ var currentInst; /** * 队列å * @type {string} */ var queueName = '__md_dialog'; /** * 窗å£å®½åº¦å˜åŒ–,或对è¯æ¡†å†…容å˜åŒ–时,调整对è¯æ¡†ä½ç½®å’Œå¯¹è¯æ¡†å†…çš„æ»šåŠ¨æ¡ */ var readjust = function () { if (!currentInst) { return; } var $dialog = currentInst.$dialog; var $dialogTitle = $dialog.children('.mdui-dialog-title'); var $dialogContent = $dialog.children('.mdui-dialog-content'); var $dialogActions = $dialog.children('.mdui-dialog-actions'); // 调整 dialog çš„ top å’Œ height 值 $dialog.height(''); $dialogContent.height(''); var dialogHeight = $dialog.height(); $dialog.css({ top: (($window.height() - dialogHeight) / 2) + 'px', height: dialogHeight + 'px', }); // 调整 mdui-dialog-content 的高度 $dialogContent.height( dialogHeight - ($dialogTitle.height() || 0) - ($dialogActions.height() || 0) ); }; /** * hashchange 事件触å‘时关é—对è¯æ¡† */ var hashchangeEvent = function () { if (location.hash.substring(1).indexOf('&mdui-dialog') < 0) { currentInst.close(true); } }; /** * 点击é®ç½©å±‚å…³é—对è¯æ¡† * @param e */ var overlayClick = function (e) { if ($(e.target).hasClass('mdui-overlay')) { currentInst.close(); } }; /** * 对è¯æ¡†å®žä¾‹ * @param selector 选择器或 HTML å—符串或 DOM å…ƒç´ * @param opts * @constructor */ function Dialog(selector, opts) { var _this = this; // 对è¯æ¡†å…ƒç´ _this.$dialog = $(selector).eq(0); if (!_this.$dialog.length) { return; } // 已通过 data 属性实例化过,ä¸å†é‡å¤å®žä¾‹åŒ– var oldInst = _this.$dialog.data('mdui.dialog'); if (oldInst) { return oldInst; } // 如果对è¯æ¡†å…ƒç´ 没有在当å‰æ–‡æ¡£ä¸ï¼Œåˆ™éœ€è¦æ·»åŠ if (!$.contains($body[0], _this.$dialog[0])) { _this.append = true; $body.append(_this.$dialog); } _this.options = $.extend({}, DEFAULT, (opts || {})); _this.state = 'closed'; // 绑定å–消按钮事件 _this.$dialog.find('[mdui-dialog-cancel]').each(function () { $(this).on('click', function () { componentEvent('cancel', 'dialog', _this, _this.$dialog); if (_this.options.closeOnCancel) { _this.close(); } }); }); // 绑定确认按钮事件 _this.$dialog.find('[mdui-dialog-confirm]').each(function () { $(this).on('click', function () { componentEvent('confirm', 'dialog', _this, _this.$dialog); if (_this.options.closeOnConfirm) { _this.close(); } }); }); // 绑定关é—按钮事件 _this.$dialog.find('[mdui-dialog-close]').each(function () { $(this).on('click', function () { _this.close(); }); }); } /** * 打开指定对è¯æ¡† * @private */ Dialog.prototype._doOpen = function () { var _this = this; currentInst = _this; if (!isLockScreen) { $.lockScreen(); isLockScreen = true; } _this.$dialog.show(); readjust(); $window.on('resize', $.throttle(function () { readjust(); }, 100)); // 打开消æ¯æ¡† _this.state = 'opening'; componentEvent('open', 'dialog', _this, _this.$dialog); _this.$dialog .addClass('mdui-dialog-open') .transitionEnd(function () { if (_this.$dialog.hasClass('mdui-dialog-open')) { _this.state = 'opened'; componentEvent('opened', 'dialog', _this, _this.$dialog); } else { _this.state = 'closed'; componentEvent('closed', 'dialog', _this, _this.$dialog); } }); // ä¸å˜åœ¨é®ç½©å±‚å…ƒç´ æ—¶ï¼Œæ·»åŠ é®ç½©å±‚ if (!$overlay) { $overlay = $.showOverlay(5100); } $overlay // 点击é®ç½©å±‚时是å¦å…³é—对è¯æ¡† [_this.options.modal ? 'off' : 'on']('click', overlayClick) // 是å¦æ˜¾ç¤ºé®ç½©å±‚,ä¸æ˜¾ç¤ºæ—¶ï¼ŒæŠŠé®ç½©å±‚背景é€æ˜Ž .css('opacity', _this.options.overlay ? '' : 0); if (_this.options.history) { // 如果 hash ä¸åŽŸæ¥å°±æœ‰ &mdui-dialogï¼Œå…ˆåˆ é™¤ï¼Œé¿å…åŽé€€åŽ†å²çºªå½•åŽä»ç„¶æœ‰ &mdui-dialog å¯¼è‡´æ— æ³•å…³é— var hash = location.hash.substring(1); if (hash.indexOf('&mdui-dialog') > -1) { hash = hash.replace(/&mdui-dialog/g, ''); } // åŽé€€æŒ‰é’®å…³é—对è¯æ¡† location.hash = hash + '&mdui-dialog'; $window.on('hashchange', hashchangeEvent); } }; /** * 打开对è¯æ¡† */ Dialog.prototype.open = function () { var _this = this; if (_this.state === 'opening' || _this.state === 'opened') { return; } // 如果当å‰æœ‰æ£åœ¨æ‰“开或已ç»æ‰“开的对è¯æ¡†,或队列ä¸ä¸ºç©ºï¼Œåˆ™å…ˆåŠ 入队列,ç‰æ—§å¯¹è¯æ¡†å¼€å§‹å…³é—æ—¶å†æ‰“å¼€ if ( (currentInst && (currentInst.state === 'opening' || currentInst.state === 'opened')) || queue.queue(queueName).length ) { queue.queue(queueName, function () { _this._doOpen(); }); return; } _this._doOpen(); }; /** * å…³é—对è¯æ¡† */ Dialog.prototype.close = function () { var _this = this; if (_this.state === 'closing' || _this.state === 'closed') { return; } currentInst = null; _this.state = 'closing'; componentEvent('close', 'dialog', _this, _this.$dialog); // 所有对è¯æ¡†éƒ½å…³é—,且当å‰æ²¡æœ‰æ‰“开的对è¯æ¡†æ—¶ï¼Œéšè—é®ç½© if (queue.queue(queueName).length === 0 && $overlay) { $.hideOverlay(); $overlay = null; } _this.$dialog .removeClass('mdui-dialog-open') .transitionEnd(function () { if (!_this.$dialog.hasClass('mdui-dialog-open')) { _this.state = 'closed'; componentEvent('closed', 'dialog', _this, _this.$dialog); _this.$dialog.hide(); // 所有对è¯æ¡†éƒ½å…³é—,且当å‰æ²¡æœ‰æ‰“开的对è¯æ¡†æ—¶ï¼Œè§£é”å±å¹• if (queue.queue(queueName).length === 0 && !currentInst && isLockScreen) { $.unlockScreen(); isLockScreen = false; } $window.off('resize', $.throttle(function () { readjust(); }, 100)); if (_this.options.destroyOnClosed) { _this.destroy(); } } else { _this.state = 'opened'; componentEvent('opened', 'dialog', _this, _this.$dialog); } }); if (_this.options.history && queue.queue(queueName).length === 0) { // 是å¦éœ€è¦åŽé€€åŽ†å²çºªå½•ï¼Œé»˜è®¤ä¸º false。 // 为 false 时是通过 js å…³é—,需è¦åŽé€€ä¸€ä¸ªåŽ†å²è®°å½• // 为 true 时是通过åŽé€€æŒ‰é’®å…³é—,ä¸éœ€è¦åŽé€€åŽ†å²è®°å½• if (!arguments[0]) { window.history.back(); } $window.off('hashchange', hashchangeEvent); } // å…³é—旧对è¯æ¡†ï¼Œæ‰“开新对è¯æ¡†ã€‚ // åŠ ä¸€ç‚¹å»¶è¿Ÿï¼Œä»…ä»…ä¸ºäº†è§†è§‰æ•ˆæžœæ›´å¥½ã€‚ä¸åŠ 延时也ä¸å½±å“功能 setTimeout(function () { queue.dequeue(queueName); }, 100); }; /** * 切æ¢å¯¹è¯æ¡†æ‰“å¼€/å…³é—çŠ¶æ€ */ Dialog.prototype.toggle = function () { var _this = this; if (_this.state === 'opening' || _this.state === 'opened') { _this.close(); } else if (_this.state === 'closing' || _this.state === 'closed') { _this.open(); } }; /** * 获å–对è¯æ¡†çŠ¶æ€ * @returns {'opening'|'opened'|'closing'|'closed'} */ Dialog.prototype.getState = function () { return this.state; }; /** * 销æ¯å¯¹è¯æ¡† */ Dialog.prototype.destroy = function () { var _this = this; if (_this.append) { _this.$dialog.remove(); } _this.$dialog.removeData('mdui.dialog'); if (queue.queue(queueName).length === 0 && !currentInst) { if ($overlay) { $.hideOverlay(); $overlay = null; } if (isLockScreen) { $.unlockScreen(); isLockScreen = false; } } }; /** * 对è¯æ¡†å†…容å˜åŒ–时,需è¦è°ƒç”¨è¯¥æ–¹æ³•æ¥è°ƒæ•´å¯¹è¯æ¡†ä½ç½®å’Œæ»šåŠ¨æ¡é«˜åº¦ */ Dialog.prototype.handleUpdate = function () { readjust(); }; // esc 按下时关é—对è¯æ¡† $document.on('keydown', function (e) { if ( currentInst && currentInst.options.closeOnEsc && currentInst.state === 'opened' && e.keyCode === 27 ) { currentInst.close(); } }); return Dialog; })(); /** * ============================================================================= * ************ Dialog DATA API ************ * ============================================================================= */ $(function () { $document.on('click', '[mdui-dialog]', function () { var $this = $(this); var options = parseOptions($this.attr('mdui-dialog')); var selector = options.target; delete options.target; var $dialog = $(selector).eq(0); var inst = $dialog.data('mdui.dialog'); if (!inst) { inst = new mdui.Dialog($dialog, options); $dialog.data('mdui.dialog', inst); } inst.open(); }); }); /** * ============================================================================= * ************ mdui.dialog(options) ************ * ============================================================================= */ mdui.dialog = function (options) { /** * 默认å‚æ•° */ var DEFAULT = { title: '', // æ ‡é¢˜ content: '', // 文本 buttons: [], // 按钮 stackedButtons: false, // 垂直排列按钮 cssClass: '', // 在 Dialog ä¸Šæ·»åŠ çš„ CSS ç±» history: true, // ç›‘å¬ hashchange 事件 overlay: true, // 是å¦æ˜¾ç¤ºé®ç½© modal: false, // 是å¦æ¨¡æ€åŒ–对è¯æ¡† closeOnEsc: true, // 按下 esc 时关é—对è¯æ¡† destroyOnClosed: true, // å…³é—åŽé”€æ¯ onOpen: function () { // 打开动画开始时的回调 }, onOpened: function () { // 打开动画结æŸåŽçš„回调 &nbnbsp; }, onClose: function () { // å…³é—动画开始时的回调 }, onClosed: function () { // å…³é—动画结æŸæ—¶çš„回调 }, }; /** * 按钮的默认å‚æ•° */ var DEFAULT_BUTTON = { text: '', // 按钮文本 bold: false, // 按钮文本是å¦åŠ ç²— close: true, // 点击按钮åŽå…³é—对è¯æ¡† onClick: function (inst) { // 点击按钮的回调 }, }; // åˆå¹¶å‚æ•° options = $.extend({}, DEFAULT, (options || {})); $.each(options.buttons, function (i, button) { options.buttons[i] = $.extend({}, DEFAULT_BUTTON, button); }); // 按钮的 HTML var buttonsHTML = ''; if (options.buttons.length) { buttonsHTML = '<div class="mdui-dialog-actions ' + (options.stackedButtons ? 'mdui-dialog-actions-stacked' : '') + '">'; $.each(options.buttons, function (i, button) { buttonsHTML += '<a href="javascript:void(0)" ' + 'class="mdui-btn mdui-ripple mdui-text-color-primary ' + (button.bold ? 'mdui-btn-bold' : '') + '">' + button.text + '</a>'; }); buttonsHTML += '</div>'; } // Dialog çš„ HTML var HTML = '<div class="mdui-dialog ' + options.cssClass + '">' + (options.title ? '<div class="mdui-dialog-title">' + options.title + '</div>' : '') + (options.content ? '<div class="mdui-dialog-content">' + options.content + '</div>' : '') + buttonsHTML + '</div>'; // 实例化 Dialog var inst = new mdui.Dialog(HTML, { history: options.history, overlay: options.overlay, modal: options.modal, closeOnEsc: options.closeOnEsc, destroyOnClosed: options.destroyOnClosed, }); // 绑定按钮事件 if (options.buttons.length) { inst.$dialog.find('.mdui-dialog-actions .mdui-btn').each(function (i, button) { $(button).on('click', function () { if (typeof options.buttons[i].onClick === 'function') { options.buttons[i].onClick(inst); } if (options.buttons[i].close) { inst.close(); } }); }); } // 绑定打开关é—事件 if (typeof options.onOpen === 'function') { inst.$dialog .on('open.mdui.dialog', function () { options.onOpen(inst); }) .on('opened.mdui.dialog', function () { options.onOpened(inst); }) .on('close.mdui.dialog', function () { options.onClose(inst); }) .on('closed.mdui.dialog', function () { options.onClosed(inst); }); } inst.open(); return inst; }; /** * ============================================================================= * ************ mdui.alert(text, title, onConfirm, options) ************ * ************ mdui.alert(text, onConfirm, options) ************ * ============================================================================= */ mdui.alert = function (text, title, onConfirm, options) { // title å‚æ•°å¯é€‰ if (typeof title === 'function') { title = ''; onConfirm = arguments[1]; options = arguments[2]; } if (onConfirm === undefined) { onConfirm = function () {}; } if (options === undefined) { options = {}; } /** * 默认å‚æ•° */ var DEFAULT = { confirmText: 'ok', // 按钮上的文本 history: true, // ç›‘å¬ hashchange 事件 modal: false, // 是å¦æ¨¡æ€åŒ–对è¯æ¡†ï¼Œä¸º false 时点击对è¯æ¡†å¤–é¢åŒºåŸŸå…³é—对è¯æ¡†ï¼Œä¸º true æ—¶ä¸å…³é— closeOnEsc: true, // 按下 esc å…³é—对è¯æ¡† }; options = $.extend({}, DEFAULT, options); return mdui.dialog({ title: title, content: text, buttons: [ { text: options.confirmText, bold: false, close: true, onClick: onConfirm, }, ], cssClass: 'mdui-dialog-alert', history: options.history, modal: options.modal, closeOnEsc: options.closeOnEsc, }); }; /** * ============================================================================= * ************ mdui.confirm(text, title, onConfirm, onCancel, options) ************ * ************ mdui.confirm(text, onConfirm, onCancel, options) ************ * ============================================================================= */ mdui.confirm = function (text, title, onConfirm, onCancel, options) { // title å‚æ•°å¯é€‰ if (typeof title === 'function') { title = ''; onConfirm = arguments[1]; onCancel = arguments[2]; options = arguments[3]; } if (onConfirm === undefined) { onConfirm = function () {}; } if (onCancel === undefined) { onCancel = function () {}; } if (options === undefined) { options = {}; } /** * 默认å‚æ•° */ var DEFAULT = { confirmText: 'ok', // 确认按钮的文本 cancelText: 'cancel', // å–消按钮的文本 history: true, // ç›‘å¬ hashchange 事件 modal: false, // 是å¦æ¨¡æ€åŒ–对è¯æ¡†ï¼Œä¸º false 时点击对è¯æ¡†å¤–é¢åŒºåŸŸå…³é—对è¯æ¡†ï¼Œä¸º true æ—¶ä¸å…³é— closeOnEsc: true, // 按下 esc å…³é—对è¯æ¡† }; options = $.extend({}, DEFAULT, options); return mdui.dialog({ title: title, content: text, buttons: [ { text: options.cancelText, bold: false, close: true, onClick: onCancel, }, { text: options.confirmText, bold: false, close: true, onClick: onConfirm, }, ], cssClass: 'mdui-dialog-confirm', history: options.history, modal: options.modal, closeOnEsc: options.closeOnEsc, }); }; /** * ============================================================================= * ************ mdui.prompt(label, title, onConfirm, onCancel, options) ************ * ************ mdui.prompt(label, onConfirm, onCancel, options) ************ * ============================================================================= */ mdui.prompt = function (label, title, onConfirm, onCancel, options) { // title å‚æ•°å¯é€‰ if (typeof title === 'function') { title = ''; onConfirm = arguments[1]; onCancel = arguments[2]; options = arguments[3]; } if (onConfirm === undefined) { onConfirm = function () {}; } if (onCancel === undefined) { onCancel = function () {}; } if (options === undefined) { options = {}; } /** * 默认å‚æ•° */ var DEFAULT = { confirmText: 'ok', // 确认按钮的文本 cancelText: 'cancel', // å–消按钮的文本 history: true, // ç›‘å¬ hashchange 事件 modal: false, // 是å¦æ¨¡æ€åŒ–对è¯æ¡†ï¼Œä¸º false 时点击对è¯æ¡†å¤–é¢åŒºåŸŸå…³é—对è¯æ¡†ï¼Œä¸º true æ—¶ä¸å…³é— closeOnEsc: true, // 按下 esc å…³é—对è¯æ¡† type: 'text', // 输入框类型,text: å•è¡Œæ–‡æœ¬æ¡† textarea: 多行文本框 maxlength: '', // 最大输入å—符数 defaultValue: '', // 输入框ä¸çš„默认文本 }; options = $.extend({}, DEFAULT, options); var content = '<div class="mdui-textfield">' + (label ? '<label class="mdui-textfield-label">' + label + '</label>' : '') + (options.type === 'text' ? '<input class="mdui-textfield-input" type="text" ' + 'value="' + options.defaultValue + '" ' + (options.maxlength ? ('maxlength="' + options.maxlength + '"') : '') + '/>' : '') + (options.type === 'textarea' ? '<textarea class="mdui-textfield-input" ' + (options.maxlength ? ('maxlength="' + options.maxlength + '"') : '') + '>' + options.defaultValue + '</textarea>' : '') + '</div>'; return mdui.dialog({ title: title, content: content, buttons: [ { text: options.cancelText, bold: false, close: true, onClick: function (inst) { var value = inst.$dialog.find('.mdui-textfield-input').val(); onCancel(value, inst); }, }, { text: options.confirmText, bold: false, close: true, onClick: function (inst) { var value = inst.$dialog.find('.mdui-textfield-input').val(); onConfirm(value, inst); }, }, ], cssClass: 'mdui-dialog-prompt', history: options.history, modal: options.modal, closeOnEsc: options.closeOnEsc, onOpen: function (inst) { // åˆå§‹åŒ–输入框 var $input = inst.$dialog.find('.mdui-textfield-input'); mdui.updateTextFields($input); // èšç„¦åˆ°è¾“入框 $input[0].focus(); // 如果是多行输入框,监å¬è¾“入框的 input 事件,更新对è¯æ¡†é«˜åº¦ if (options.type === 'textarea') { $input.on('input', function () { inst.handleUpdate(); }); } // 有å—符数é™åˆ¶æ—¶ï¼ŒåŠ è½½å®Œæ–‡æœ¬æ¡†åŽ DOM 会å˜åŒ–,需è¦æ›´æ–°å¯¹è¯æ¡†é«˜åº¦ if (options.maxlength) { inst.handleUpdate(); } }, }); }; /** * ============================================================================= * ************ ToolTip 工具æ示 ************ * ============================================================================= */ mdui.Tooltip = (function () { /** * 默认å‚æ•° */ var DEFAULT = { position: 'auto', // æ示所在ä½ç½® delay: 0, // 延迟,å•ä½æ¯«ç§’ content: '', // æ示文本,å…è®¸åŒ…å« HTML }; /** * 是å¦æ˜¯æ¡Œé¢è®¾å¤‡ * @returns {boolean} */ var isDesktop = function () { return $window.width() > 1024; }; /** * 设置 Tooltip çš„ä½ç½® * @param inst */ function setPosition(inst) { var marginLeft; var marginTop; var position; // 触å‘çš„å…ƒç´ var targetProps = inst.$target[0].getBoundingClientRect(); // 触å‘çš„å…ƒç´ å’Œ Tooltip 之间的è·ç¦» var targetMargin = (isDesktop() ? 14 : 24); // Tooltip 的宽度和高度 var tooltipWidth = inst.$tooltip[0].offsetWidth; var tooltipHeight = inst.$tooltip[0].offsetHeight; // Tooltip çš„æ–¹å‘ position = inst.options.position; // 自动判æ–ä½ç½®ï¼ŒåŠ 2px,使 Tooltip è·ç¦»çª—å£è¾¹æ¡†è‡³å°‘有 2px çš„é—´è· if (['bottom', 'top', 'left', 'right'].indexOf(position) === -1) { if ( targetProps.top + targetProps.height + targetMargin + tooltipHeight + 2 < $window.height() ) { position = 'bottom'; } else if (targetMargin + tooltipHeight + 2 < targetProps.top) { position = 'top'; } else if (targetMargin + tooltipWidth + 2 < targetProps.left) { position = 'left'; } else if ( targetProps.width + targetMargin + tooltipWidth + 2 < $window.width() - targetProps.left ) { position = 'right'; } else { position = 'bottom'; } } // 设置ä½ç½® switch (position) { case 'bottom': marginLeft = -1 * (tooltipWidth / 2); marginTop = (targetProps.height / 2) + targetMargin; inst.$tooltip.transformOrigin('top center'); break; case 'top': marginLeft = -1 * (tooltipWidth / 2); marginTop = -1 * (tooltipHeight + (targetProps.height / 2) + targetMargin); inst.$tooltip.transformOrigin('bottom center'); break; case 'left': marginLeft = -1 * (tooltipWidth + (targetProps.width / 2) + targetMargin); marginTop = -1 * (tooltipHeight / 2); inst.$tooltip.transformOrigin('center right'); break; case 'right': marginLeft = (targetProps.width / 2) + targetMargin; marginTop = -1 * (tooltipHeight / 2); inst.$tooltip.transformOrigin('center left'); break; } var targetOffset = inst.$target.offset(); inst.$tooltip.css({ top: targetOffset.top + (targetProps.height / 2) + 'px', left: targetOffset.left + (targetProps.width / 2) + 'px', 'margin-left': marginLeft + 'px', 'margin-top': marginTop + 'px', }); } /** * Tooltip 实例 * @param selector * @param opts * @constructor */ function Tooltip(selector, opts) { var _this = this; _this.$target = $(selector).eq(0); if (!_this.$target.length) { return; } // 已通过 data 属性实例化过,ä¸å†é‡å¤å®žä¾‹åŒ– var oldInst = _this.$target.data('mdui.tooltip'); if (oldInst) { return oldInst; } _this.options = $.extend({}, DEFAULT, (opts || {})); _this.state = 'closed'; // 创建 Tooltip HTML var guid = $.guid('tooltip'); _this.$tooltip = $( '<div class="mdui-tooltip" id="mdui-tooltip-' + guid + '">' + _this.options.content + '</div>' ).appendTo($body); // 绑定事件 _this.$target .on('touchstart mouseenter', function (e) { if (!TouchHandler.isAllow(e)) { return; } TouchHandler.register(e); _this.open(); }) .on('touchend mouseleave', function (e) { if (!TouchHandler.isAllow(e)) { return; } _this.close(); }) .on(TouchHandler.unlock, TouchHandler.register); } /** * 动画结æŸå›žè°ƒ * @private */ var transitionEnd = function (inst) { if (inst.$tooltip.hasClass('mdui-tooltip-open')) { inst.state = 'opened'; componentEvent('opened', 'tooltip', inst, inst.$target); } else { inst.state = 'closed'; componentEvent('closed', 'tooltip', inst, inst.$target); } }; /** * 执行打开 Tooltip * @private */ Tooltip.prototype._doOpen = function () { var _this = this; _this.state = 'opening'; componentEvent('open', 'tooltip', _this, _this.$target); _this.$tooltip .addClass('mdui-tooltip-open') .transitionEnd(function () { transitionEnd(_this); }); }; /** * 打开 Tooltip * @param opts å…许æ¯æ¬¡æ‰“开时设置ä¸åŒçš„å‚æ•° */ Tooltip.prototype.open = function (opts) { var _this = this; if (_this.state === 'opening' || _this.state === 'opened') { return; } var oldOpts = _this.options; // åˆå¹¶ data 属性å‚æ•° $.extend(_this.options, parseOptions(_this.$target.attr('mdui-tooltip'))); if (opts) { $.extend(_this.options, opts); } // tooltip 的内容有更新 if (oldOpts.content !== _this.options.content) { _this.$tooltip.html(_this.options.content); } setPosition(_this); if (_this.options.delay) { _this.timeoutId = setTimeout(function () { _this._doOpen(); }, _this.options.delay); } else { _this.timeoutId = false; _this._doOpen(); } }; /** * å…³é— Tooltip */ Tooltip.prototype.close = function () { var _this = this; if (_this.timeoutId) { clearTimeout(_this.timeoutId); _this.timeoutId = false; } if (_this.state === 'closing' || _this.state === 'closed') { return; } _this.state = 'closing'; componentEvent('close', 'tooltip', _this, _this.$target); _this.$tooltip .removeClass('mdui-tooltip-open') .transitionEnd(function () { transitionEnd(_this); }); }; /** * åˆ‡æ¢ Tooltip çŠ¶æ€ */ Tooltip.prototype.toggle = function () { var _this = this; if (_this.state === 'opening' || _this.state === 'opened') { _this.close(); } else if (_this.state === 'closing' || _this.state === 'closed') { _this.open(); } }; /** * èŽ·å– Tooltip çŠ¶æ€ * @returns {'opening'|'opened'|'closing'|'closed'} */ Tooltip.prototype.getState = function () { return this.state; }; /** * é”€æ¯ Tooltip */ /*Tooltip.prototype.destroy = function () { var _this = this; clearTimeout(_this.timeoutId); $.data(_this.target, 'mdui.tooltip', null); $.remove(_this.tooltip); };*/ return Tooltip; })(); /** * ============================================================================= * ************ Tooltip DATA API ************ * ============================================================================= */ $(function () { // mouseenter ä¸èƒ½å†’泡,所以这里用 mouseover 代替 $document.on('touchstart mouseover', '[mdui-tooltip]', function () { var $this = $(this); var inst = $this.data('mdui.tooltip'); if (!inst) { var options = parseOptions($this.attr('mdui-tooltip')); inst = new mdui.Tooltip($this, options); $this.data('mdui.tooltip', inst); } }); }); /** * ============================================================================= * ************ Snackbar ************ * ============================================================================= */ (function () { /** * 当å‰æ‰“å¼€ç€çš„ Snackbar */ var currentInst; /** * 对列å * @type {string} */ var queueName = '__md_snackbar'; var DEFAULT = { message: '', // 文本内容 timeout: 4000, // 在用户没有æ“作时多长时间自动éšè— buttonText: '', // 按钮的文本 buttonColor: '', // æŒ‰é’®çš„é¢œè‰²ï¼Œæ”¯æŒ blue #90caf9 rgba(...) closeOnButtonClick: true, // ç‚¹å‡»æŒ‰é’®æ—¶å…³é— closeOnOutsideClick: true, // 触摸或点击å±å¹•å…¶ä»–åœ°æ–¹æ—¶å…³é— onClick: function () { // 在 Snackbar 上点击的回调 }, onButtonClick: function () { // 点击按钮的回调 }, onClose: function () { // å…³é—动画开始时的回调 }, }; /** * 点击 Snackbar 外é¢çš„åŒºåŸŸå…³é— * @param e */ var closeOnOutsideClick = function (e) { var $target = $(e.target); if (!$target.hasClass('mdui-snackbar') && !$target.parents('.mdui-snackbar').length) { currentInst.close(); } }; /** * Snackbar 实例 * @param opts * @constructor */ function Snackbar(opts) { var _this = this; _this.options = $.extend({}, DEFAULT, (opts || {})); // message å‚æ•°å¿…é¡» if (!_this.options.message) { return; } _this.state = 'closed'; _this.timeoutId = false; // 按钮颜色 var buttonColorStyle = ''; var buttonColorClass = ''; if ( _this.options.buttonColor.indexOf('#') === 0 || _this.options.buttonColor.indexOf('rgb') === 0 ) { buttonColorStyle = 'style="color:' + _this.options.buttonColor + '"'; } else if (_this.options.buttonColor !== '') { buttonColorClass = 'mdui-text-color-' + _this.options.buttonColor; } // æ·»åŠ HTML _this.$snackbar = $( '<div class="mdui-snackbar">' + '<div class="mdui-snackbar-text">' + _this.options.message + '</div>' + (_this.options.buttonText ? ('<a href="javascript:void(0)" ' + 'class="mdui-snackbar-action mdui-btn mdui-ripple mdui-ripple-white ' + buttonColorClass + '" ' + buttonColorStyle + '>' + _this.options.buttonText + '</a>') : '' ) + '</div>') .appendTo($body); // 设置ä½ç½® _this.$snackbar .transform('translateY(' + _this.$snackbar[0].clientHeight + 'px)') .css('left', (document.body.clientWidth - _this.$snackbar[0].clientWidth) / 2 + 'px') .addClass('mdui-snackbar-transition'); } /** * 打开 Snackbar */ Snackbar.prototype.open = function () { var _this = this; if (_this.state === 'opening' || _this.state === 'opened') { return; } // 如果当å‰æœ‰æ£åœ¨æ˜¾ç¤ºçš„ Snackbarï¼Œåˆ™å…ˆåŠ å…¥é˜Ÿåˆ—ï¼Œç‰æ—§ Snackbar å…³é—åŽå†æ‰“å¼€ if (currentInst) { queue.queue(queueName, function () { _this.open(); }); return; } currentInst = _this; // 开始打开 _this.state = 'opening'; _this.$snackbar .transform('translateY(0)') .transitionEnd(function () { if (_this.state !== 'opening') { return; } _this.state = 'opened'; // 有按钮时绑定事件 if (_this.options.buttonText) { _this.$snackbar .find('.mdui-snackbar-action') .on('click', function () { _this.options.onButtonClick(); if (_this.options.closeOnButtonClick) { _this.close(); } }); } // 点击 snackbar 的事件 _this.$snackbar.on('click', function (e) { if (!$(e.target).hasClass('mdui-snackbar-action')) { _this.options.onClick(); } }); // 点击 Snackbar 外é¢çš„åŒºåŸŸå…³é— if (_this.options.closeOnOutsideClick) { $document.on(TouchHandler.start, closeOnOutsideClick); } // 超时åŽè‡ªåŠ¨å…³é— _this.timeoutId = setTimeout(function () { _this.close(); }, _this.options.timeout); }); }; /** * å…³é— Snackbar */ Snackbar.prototype.close = function () { var _this = this; if (_this.state === 'closing' || _this.state === 'closed') { return; } if (_this.timeoutId) { clearTimeout(_this.timeoutId); } if (_this.options.closeOnOutsideClick) { $document.off(TouchHandler.start, closeOnOutsideClick); } _this.state = 'closing'; _this.options.onClose(); _this.$snackbar .transform('translateY(' + _this.$snackbar[0].clientHeight + 'px)') .transitionEnd(function () { if (_this.state !== 'closing') { return; } currentInst = null; _this.state = 'closed'; _this.$snackbar.remove(); queue.dequeue(queueName); }); }; /** * 打开 Snackbar * @param params */ mdui.snackbar = function (params) { var inst = new Snackbar(params); inst.open(); return inst; }; })(); /** * ============================================================================= * ************ Bottom navigation 底部导航æ ************ * ============================================================================= */ (function () { // 切æ¢å¯¼èˆªé¡¹ $document.on('click', '.mdui-bottom-nav>a', function () { var $this = $(this); var $bottomNav = $this.parent(); var isThis; $bottomNav.children('a').each(function (i, item) { isThis = $this.is(item); if (isThis) { componentEvent('change', 'bottomNav', null, $bottomNav, { index: i, }); } $(item)[isThis ? 'addClass' : 'removeClass']('mdui-bottom-nav-active'); }); }); // 滚动时éšè— mdui-bottom-nav-scroll-hide $('.mdui-bottom-nav-scroll-hide').each(function () { var $this = $(this); var inst = new mdui.Headroom($this, { pinnedClass: 'mdui-headroom-pinned-down', unpinnedClass: 'mdui-headroom-unpinned-down', }); $this.data('mdui.headroom', inst); }); })(); /** * ============================================================================= * ************ Spinner åœ†å½¢è¿›åº¦æ¡ ************ * ============================================================================= */ (function () { /** * layer çš„ HTML 结构 */ var layerHTML = function () { var i = arguments.length ? arguments[0] : false; return '<div class="mdui-spinner-layer ' + (i ? 'mdui-spinner-layer-' + i : '') + '">' + '<div class="mdui-spinner-circle-clipper mdui-spinner-left">' + '<div class="mdui-spinner-circle"></div>' + '</div>' + '<div class="mdui-spinner-gap-patch">' + '<div class="mdui-spinner-circle"></div>' + '</div>' + '<div class="mdui-spinner-circle-clipper mdui-spinner-right">' + '<div class="mdui-spinner-circle"></div>' + '</div>' + '</div>'; }; /** * å¡«å…… HTML * @param spinner */ var fillHTML = function (spinner) { var $spinner = $(spinner); var layer; if ($spinner.hasClass('mdui-spinner-colorful')) { layer = layerHTML('1') + layerHTML('2') + layerHTML('3') + layerHTML('4'); } else { layer = layerHTML(); } $spinner.html(layer); }; /** * 页é¢åŠ 载完åŽè‡ªåŠ¨å¡«å…… HTML 结构 */ $(function () { $('.mdui-spinner').each(function () { fillHTML(this); }); }); /** * æ›´æ–°åœ†å½¢è¿›åº¦æ¡ */ mdui.updateSpinners = function () { $(arguments.length ? arguments[0] : '.mdui-spinner').each(function () { fillHTML(this); }); }; })(); /** * ============================================================================= * ************ Expansion panel å¯æ‰©å±•é¢æ¿ ************ * ============================================================================= */ mdui.Panel = (function () { function Panel(selector, opts) { return new CollapsePrivate(selector, opts, { item: 'mdui-panel-item', itemOpen: 'mdui-panel-item-open', header: 'mdui-panel-item-header', body: 'mdui-panel-item-body', }, 'panel'); } return Panel; })(); /** * ============================================================================= * ************ Expansion panel 自定义属性 ************ * ============================================================================= */ $(function () { $('[mdui-panel]').each(function () { var $target = $(this); var inst = $target.data('mdui.panel'); if (!inst) { var options = parseOptions($target.attr('mdui-panel')); inst = new mdui.Panel($target, options); $target.data('mdui.panel', inst); } }); }); /** * ============================================================================= * ************ Menu èœå• ************ * ============================================================================= */ mdui.Menu = (function () { /** * 默认å‚æ•° */ var DEFAULT = { position: 'auto', // èœå•ä½ç½® topã€bottomã€centerã€auto align: 'auto', // èœå•å’Œè§¦å‘å®ƒçš„å…ƒç´ çš„å¯¹é½æ–¹å¼ leftã€rightã€centerã€auto gutter: 16, // èœå•è·ç¦»çª—å£è¾¹ç¼˜çš„最å°è·ç¦»ï¼Œå•ä½ px fixed: false, // 是å¦ä½¿èœå•å›ºå®šåœ¨çª—å£ï¼Œä¸éšæ»šåŠ¨æ¡æ»šåŠ¨ covered: 'auto', // èœå•æ˜¯å¦è¦†ç›–在触å‘å®ƒçš„å…ƒç´ ä¸Šï¼Œtrueã€false。auto 时简å•èœå•è¦†ç›–,级è”èœå•ä¸è¦†ç›– subMenuTrigger: 'hover', // åèœå•çš„触å‘æ–¹å¼ hoverã€click subMenuDelay: 200, // åèœå•çš„触å‘延时,仅在 submenuTrigger 为 hover 有效 }; /** * 调整主èœå•ä½ç½® * @param _this 实例 */ var readjust = function (_this) { var menuLeft; var menuTop; // èœå•ä½ç½®å’Œæ–¹å‘ var position; var align; // window 窗å£çš„宽度和高度 var windowHeight = $window.height(); var windowWidth = $window.width(); // é…ç½®å‚æ•° var gutter = _this.options.gutter; var isCovered = _this.isCovered; var isFixed = _this.options.fixed; // 动画方å‘å‚æ•° var transformOriginX; var transformOriginY; // èœå•çš„原始宽度和高度 var menuWidth = _this.$menu.width(); var menuHeight = _this.$menu.height(); var $anchor = _this.$anchor; // 触å‘èœå•çš„å…ƒç´ åœ¨çª—å£ä¸çš„ä½ç½® var anchorTmp = $anchor[0].getBoundingClientRect(); var anchorTop = anchorTmp.top; var anchorLeft = anchorTmp.left; var anchorHeight = anchorTmp.height; var anchorWidth = anchorTmp.width; var anchorBottom = windowHeight - anchorTop - anchorHeight; var anchorRight = windowWidth - anchorLeft - anchorWidth; // 触å‘å…ƒç´ ç›¸å¯¹å…¶æ‹¥æœ‰å®šä½å±žæ€§çš„çˆ¶å…ƒç´ çš„ä½ç½® var anchorOffsetTop = $anchor[0].offsetTop; var anchorOffsetLeft = $anchor[0].offsetLeft; // =============================== // ================= 自动判æ–èœå•ä½ç½® // =============================== if (_this.options.position === 'auto') { // 判æ–下方是å¦æ”¾å¾—下èœå• if (anchorBottom + (isCovered ? anchorHeight : 0) > menuHeight + gutter) { position = 'bottom'; } // 判æ–上方是å¦æ”¾å¾—下èœå• else if (anchorTop + (isCovered ? anchorHeight : 0) > menuHeight + gutter) { position = 'top'; } // 上下都放ä¸ä¸‹ï¼Œå±…ä¸æ˜¾ç¤º else { position = 'center'; } } else { position = _this.options.position; } // =============================== // ============== 自动判æ–èœå•å¯¹é½æ–¹å¼ // =============================== if (_this.options.align === 'auto') { // 判æ–å³ä¾§æ˜¯å¦æ”¾å¾—下èœå• if (anchorRight + anchorWidth > menuWidth + gutter) { align = 'left'; } // 判æ–左侧是å¦æ”¾å¾—下èœå• else if (anchorLeft + anchorWidth > menuWidth + gutter) { align = 'right'; } // å·¦å³éƒ½æ”¾ä¸ä¸‹ï¼Œå±…ä¸æ˜¾ç¤º else { align = 'center'; } } else { align = _this.options.align; } // =============================== // ==================== 设置èœå•ä½ç½® // =============================== if (position === 'bottom') { transformOriginY = '0'; menuTop = (isCovered ? 0 : anchorHeight) + (isFixed ? anchorTop : anchorOffsetTop); } else if (position === 'top') { transformOriginY = '100%'; menuTop = (isCovered ? anchorHeight : 0) + (isFixed ? (anchorTop - menuHeight) : (anchorOffsetTop - menuHeight)); } else { transformOriginY = '50%'; // =====================在窗å£ä¸å±…ä¸ // 显示的èœå•çš„高度,简å•èœå•é«˜åº¦ä¸è¶…过窗å£é«˜åº¦ï¼Œè‹¥è¶…过了则在èœå•å†…éƒ¨æ˜¾ç¤ºæ»šåŠ¨æ¡ // 级è”èœå•å†…部ä¸å…è®¸å‡ºçŽ°æ»šåŠ¨æ¡ var menuHeightTemp = menuHeight; // 简å•èœå•æ¯”窗å£é«˜æ—¶ï¼Œé™åˆ¶èœå•é«˜åº¦ if (!_this.$menu.hasClass('mdui-menu-cascade')) { if (menuHeight + gutter * 2 > windowHeight) { menuHeightTemp = windowHeight - gutter * 2; _this.$menu.height(menuHeightTemp); } } menuTop = (windowHeight - menuHeightTemp) / 2 + (isFixed ? 0 : (anchorOffsetTop - anchorTop)); } _this.$menu.css('top', menuTop + 'px'); // =============================== // ================= 设置èœå•å¯¹é½æ–¹å¼ // =============================== if (align === 'left') { transformOriginX = '0'; menuLeft = isFixed ? anchorLeft : anchorOffsetLeft; } else if (align === 'right') { transformOriginX = '100%'; menuLeft = isFixed ? (anchorLeft + anchorWidth - menuWidth) : (anchorOffsetLeft + anchorWidth - menuWidth); } else { transformOriginX = '50%'; //=======================在窗å£ä¸å±…ä¸ // 显示的èœå•çš„宽度,èœå•å®½åº¦ä¸èƒ½è¶…过窗å£å®½åº¦ var menuWidthTemp = menuWidth; // èœå•æ¯”窗å£å®½ï¼Œé™åˆ¶èœå•å®½åº¦ if (menuWidth + gutter * 2 > windowWidth) { menuWidthTemp = windowWidth - gutter * 2; _this.$menu.width(menuWidthTemp); } menuLeft = (windowWidth - menuWidthTemp) / 2 + (isFixed ? 0 : anchorOffsetLeft - anchorLeft); } _this.$menu.css('left', menuLeft + 'px'); // 设置èœå•åŠ¨ç”»æ–¹å‘ _this.$menu.transformOrigin(transformOriginX + ' ' + transformOriginY); }; /** * 调整åèœå•çš„ä½ç½® * @param $submenu */ var readjustSubmenu = function ($submenu) { var $item = $submenu.parent('.mdui-menu-item'); var submenuTop; var submenuLeft; // åèœå•ä½ç½®å’Œæ–¹å‘ var position; // topã€bottom var align; // leftã€right // window 窗å£çš„宽度和高度 var windowHeight = $window.height(); var windowWidth = $window.width(); // 动画方å‘å‚æ•° var transformOriginX; var transformOriginY; // åèœå•çš„原始宽度和高度 var submenuWidth = $submenu.width(); var submenuHeight = $submenu.height(); // 触å‘åèœå•çš„èœå•é¡¹çš„宽度高度 var itemTmp = $item[0].getBoundingClientRect(); var itemWidth = itemTmp.width; var itemHeight = itemTmp.height; var itemLeft = itemTmp.left; var itemTop = itemTmp.top; // =================================== // ===================== 判æ–èœå•ä¸Šä¸‹ä½ç½® // =================================== // 判æ–下方是å¦æ”¾å¾—下èœå• if (windowHeight - itemTop > submenuHeight) { position = 'bottom'; } // 判æ–上方是å¦æ”¾å¾—下èœå• else if (itemTop + itemHeight > submenuHeight) { position = 'top'; } // 默认放在下方 else { position = 'bottom'; } // ==================================== // ====================== 判æ–èœå•å·¦å³ä½ç½® // ==================================== // 判æ–å³ä¾§æ˜¯å¦æ”¾å¾—下èœå• if (windowWidth - itemLeft - itemWidth > submenuWidth) { align = 'left'; } // 判æ–左侧是å¦æ”¾å¾—下èœå• else if (itemLeft > submenuWidth) { align = 'right'; } // 默认放在å³ä¾§ else { align = 'left'; } // =================================== // ======================== 设置èœå•ä½ç½® // =================================== if (position === 'bottom') { transformOriginY = '0'; submenuTop = '0'; } else if (position === 'top') { transformOriginY = '100%'; submenuTop = -submenuHeight + itemHeight; } $submenu.css('top', submenuTop + 'px'); // =================================== // ===================== 设置èœå•å¯¹é½æ–¹å¼ // =================================== if (align === 'left') { transformOriginX = '0'; submenuLeft = itemWidth; } else if (align === 'right') { transformOriginX = '100%'; submenuLeft = -submenuWidth; } $submenu.css('left', submenuLeft + 'px'); // 设置èœå•åŠ¨ç”»æ–¹å‘ $submenu.transformOrigin(transformOriginX + ' ' + transformOriginY); }; /** * 打开åèœå• * @param $submenu */ var openSubMenu = function ($submenu) { readjustSubmenu($submenu); $submenu .addClass('mdui-menu-open') .parent('.mdui-menu-item') .addClass('mdui-menu-item-active'); }; /** * å…³é—åèœå•ï¼ŒåŠå…¶åµŒå¥—çš„åèœå• * @param $submenu */ var closeSubMenu = function ($submenu) { // å…³é—åèœå• $submenu .removeClass('mdui-menu-open') // 移除激活状æ€çš„æ ·å¼ .parent('.mdui-menu-item') .removeClass('mdui-menu-item-active'); // 循环关é—嵌套的åèœå• $submenu.find('.mdui-menu').each(function () { $(this) .removeClass('mdui-menu-open') .parent('.mdui-menu-item') .removeClass('mdui-menu-item-active'); }); }; /** * 切æ¢åèœå•çŠ¶æ€ * @param $submenu */ var toggleSubMenu = function ($submenu) { if ($submenu.hasClass('mdui-menu-open')) { closeSubMenu($submenu); } else { openSubMenu($submenu); } }; /** * 绑定åèœå•äº‹ä»¶ * @param inst 实例 */ var bindSubMenuEvent = function (inst) { // 点击打开åèœå• inst.$menu.on('click', '.mdui-menu-item', function (e) { var $this = $(this); var $target = $(e.target); // ç¦ç”¨çŠ¶æ€èœå•ä¸æ“作 if ($this.attr('disabled') !== null) { return; } // 没有点击在åèœå•çš„èœå•é¡¹ä¸Šæ—¶ï¼Œä¸æ“作(点在了åèœå•çš„空白区域ã€æˆ–分隔线上) if ($target.is('.mdui-menu') || $target.is('.mdui-divider')) { return; } // 阻æ¢å†’泡,点击èœå•é¡¹æ—¶åªåœ¨æœ€åŽä¸€çº§çš„ mdui-menu-item 上生效,ä¸å‘上冒泡 if (!$target.parents('.mdui-menu-item').eq(0).is($this)) { return; } // 当å‰èœå•çš„åèœå• var $submenu = $this.children('.mdui-menu'); // 先关é—除当å‰åèœå•å¤–的所有åŒçº§åèœå• $this.parent('.mdui-menu').children('.mdui-menu-item').each(function () { var $tmpSubmenu = $(this).children('.mdui-menu'); if ( $tmpSubmenu.length && (!$submenu.length || !$tmpSubmenu.is($submenu)) ) { closeSubMenu($tmpSubmenu); } }); // 切æ¢å½“å‰åèœå• if ($submenu.length) { toggleSubMenu($submenu); } }); if (inst.options.subMenuTrigger === 'hover') { // 临时å˜å‚¨ setTimeout 对象 var timeout; var timeoutOpen; var timeoutClose; inst.$menu.on('mouseover mouseout', '.mdui-menu-item', function (e) { var $this = $(this); var eventType = e.type; var $relatedTarget = $(e.relatedTarget); // ç¦ç”¨çŠ¶æ€çš„èœå•ä¸æ“作 if ($this.attr('disabled') !== null) { return; } // 用 mouseover 模拟 mouseenter if (eventType === 'mouseover') { if (!$this.is($relatedTarget) && $.contains($this[0], $relatedTarget[0])) { return; } } // 用 mouseout 模拟 mouseleave else if (eventType === 'mouseout') { if ($this.is($relatedTarget) || $.contains($this[0], $relatedTarget[0])) { return; } } // 当å‰èœå•é¡¹ä¸‹çš„åèœå•ï¼Œæœªå¿…å˜åœ¨ var $submenu = $this.children('.mdui-menu'); // é¼ æ ‡ç§»å…¥èœå•é¡¹æ—¶ï¼Œæ˜¾ç¤ºèœå•é¡¹ä¸‹çš„åèœå• if (eventType === 'mouseover') { if ($submenu.length) { // 当å‰åèœå•å‡†å¤‡æ‰“开时,如果当å‰åèœå•æ£å‡†å¤‡ç€å…³é—,ä¸ç”¨å†å…³é—了 var tmpClose = $submenu.data('timeoutClose.mdui.menu'); if (tmpClose) { clearTimeout(tmpClose); } // 如果当å‰åèœå•å·²ç»æ‰“开,ä¸æ“作 if ($submenu.hasClass('mdui-menu-open')) { return; } // 当å‰åèœå•å‡†å¤‡æ‰“开时,其他准备打开的åèœå•ä¸ç”¨å†æ‰“开了 clearTimeout(timeoutOpen); // 准备打开当å‰åèœå• timeout = timeoutOpen = setTimeout(function () { openSubMenu($submenu); }, inst.options.subMenuDelay); $submenu.data('timeoutOpen.mdui.menu', timeout); } } // é¼ æ ‡ç§»å‡ºèœå•é¡¹æ—¶ï¼Œå…³é—èœå•é¡¹ä¸‹çš„åèœå• else if (eventType === 'mouseout') { if ($submenu.length) { // é¼ æ ‡ç§»å‡ºèœå•é¡¹æ—¶ï¼Œå¦‚果当å‰èœå•é¡¹ä¸‹çš„åèœå•æ£å‡†å¤‡æ‰“开,ä¸ç”¨å†æ‰“开了 var tmpOpen = $submenu.data('timeoutOpen.mdui.menu'); if (tmpOpen) { clearTimeout(tmpOpen); } // 准备关é—当å‰åèœå• timeout = timeoutClose = setTimeout(function () { closeSubMenu($submenu); }, inst.options.subMenuDelay); $submenu.data('timeoutClose.mdui.menu', timeout); } } }); } }; /** * èœå• * @param anchorSelector ç‚¹å‡»è¯¥å…ƒç´ è§¦å‘èœå• * @param menuSelector èœå• * @param opts é…置项 * @constructor */ function Menu(anchorSelector, menuSelector, opts) { var _this = this; // 触å‘èœå•çš„å…ƒç´ _this.$anchor = $(anchorSelector).eq(0); if (!_this.$anchor.length) { return; } // 已通过自定义属性实例化过,ä¸å†é‡å¤å®žä¾‹åŒ– var oldInst = _this.$anchor.data('mdui.menu'); if (oldInst) { return oldInst; } _this.$menu = $(menuSelector).eq(0); // 触å‘èœå•çš„å…ƒç´ å’Œ èœå•å¿…须是åŒçº§çš„å…ƒç´ ï¼Œå¦åˆ™èœå•å¯èƒ½ä¸èƒ½å®šä½ if (!_this.$anchor.siblings(_this.$menu).length) { return; } _this.options = $.extend({}, DEFAULT, (opts || {})); _this.state = 'closed'; // 是å¦æ˜¯çº§è”èœå• _this.isCascade = _this.$menu.hasClass('mdui-menu-cascade'); // covered å‚æ•°å¤„ç† if (_this.options.covered === 'auto') { _this.isCovered = !_this.isCascade; } else { _this.isCovered = _this.options.covered; } // 点击触å‘èœå•åˆ‡æ¢ _this.$anchor.on('click', function () { _this.toggle(); }); // 点击èœå•å¤–é¢åŒºåŸŸå…³é—èœå• $document.on('click touchstart', function (e) { var $target = $(e.target); if ( (_this.state === 'opening' || _this.state === 'opened') && !$target.is(_this.$menu) && !$.contains(_this.$menu[0], $target[0]) && !$target.is(_this.$anchor) && !$.contains(_this.$anchor[0], $target[0]) ) { _this.close(); } }); // 点击ä¸å«åèœå•çš„èœå•æ¡ç›®å…³é—èœå• $document.on('click', '.mdui-menu-item', function (e) { var $this = $(this); if (!$this.find('.mdui-menu').length && $this.attr('disabled') === null) { _this.close(); } }); // ç»‘å®šç‚¹å‡»æˆ–é¼ æ ‡ç§»å…¥å«åèœå•çš„æ¡ç›®çš„事件 bindSubMenuEvent(_this); // 窗å£å¤§å°å˜åŒ–时,é‡æ–°è°ƒæ•´èœå•ä½ç½® $window.on('resize', $.throttle(function () { readjust(_this); }, 100)); } /** * 切æ¢èœå•çŠ¶æ€ */ Menu.prototype.toggle = function () { var _this = this; if (_this.state === 'opening' || _this.state === 'opened') { _this.close(); } else if (_this.state === 'closing' || _this.state === 'closed') { _this.open(); } }; /** * 动画结æŸå›žè°ƒ * @param inst */ var transitionEnd = function (inst) { if (inst.state === 'opening') { inst.state = 'opened'; componentEvent('opened', 'menu', inst, inst.$menu); } if (inst.state === 'closing') { inst.state = 'closed'; componentEvent('closed', 'menu', inst, inst.$menu); // å…³é—åŽï¼Œæ¢å¤èœå•æ ·å¼åˆ°é»˜è®¤çŠ¶æ€ï¼Œå¹¶æ¢å¤ fixed å®šä½ inst.$menu.css({ top: '', left: '', width: '', position: 'fixed', }); } }; /** * 打开èœå• */ Menu.prototype.open = function () { var _this = this; if (_this.state === 'opening' || _this.state === 'opened') { return; } _this.state = 'opening'; componentEvent('open', 'menu', _this, _this.$menu); // 调整èœå•ä½ç½® readjust(_this); _this.$menu // èœå•éšè—状æ€ä½¿ç”¨ä½¿ç”¨ fixed 定ä½ã€‚ .css('position', _this.options.fixed ? 'fixed' : 'absolute') // 打开èœå• .addClass('mdui-menu-open') // 打开动画完æˆåŽ .transitionEnd(function () { transitionEnd(_this); }); }; /** * å…³é—èœå• */ Menu.prototype.close = function () { var _this = this; if (_this.state === 'closing' || _this.state === 'closed') { return; } _this.state = 'closing'; componentEvent('close', 'menu', _this, _this.$menu); // èœå•å¼€å§‹å…³é—时,关é—所有åèœå• _this.$menu.find('.mdui-menu').each(function () { closeSubMenu($(this)); }); _this.$menu .removeClass('mdui-menu-open') .transitionEnd(function () { transitionEnd(_this); }); }; return Menu; })(); /** * ============================================================================= * ************ Menu 自定义属性 API ************ * ============================================================================= */ $(function () { $document.on('click', '[mdui-menu]', function () { var $this = $(this); var inst = $this.data('mdui.menu'); if (!inst) { var options = parseOptions($this.attr('mdui-menu')); var menuSelector = options.target; delete options.target; inst = new mdui.Menu($this, menuSelector, options); $this.data('mdui.menu', inst); inst.toggle(); } }); }); /* jshint ignore:start */ mdui.JQ = $; window.mdui = mdui; })(window, document); /* jshint ignore:end */ </script>
ui má ơi js :)
Trả lờiXóabạn úp js ấy lên host bạn nhé :)
Xóa