Line 1: | Line 1: | ||
− | + | {{NAU-CHINA/ResetCSS}} | |
<html> | <html> | ||
<head> | <head> | ||
+ | <meta charset="utf-8" /> | ||
+ | <title>header</title> | ||
<script src="https://code.jquery.com/jquery-3.3.1.js" | <script src="https://code.jquery.com/jquery-3.3.1.js" | ||
integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" | integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" | ||
crossorigin="anonymous"> | crossorigin="anonymous"> | ||
</script> | </script> | ||
− | <style type="text/css"> | + | <style type="text/css"> |
+ | |||
+ | /*======================================================================================*/ | ||
+ | * { | ||
+ | box-sizing: border-box; | ||
+ | } | ||
+ | body {margin:0;padding:0;} | ||
+ | #LOGO { | ||
+ | position:fixed; | ||
+ | top:0px; | ||
+ | left:70px; | ||
+ | z-index:10; | ||
+ | } | ||
+ | .menu { | ||
+ | width: 100%; | ||
+ | height:55px; | ||
+ | margin: 0; | ||
+ | /*align-content:center;*/ | ||
+ | padding: 10px 0 0 255px; | ||
+ | /*padding-right: 30px;*/ | ||
+ | font-family: 'Georgia','Goudy Old Style Regular',sans-serif !important; | ||
+ | font-size: 1.45em; | ||
+ | /*font-weight: bold;*/ | ||
+ | position: fixed; | ||
+ | top: 16px; | ||
+ | background:white; | ||
+ | /*background: #e9e9e9;*/ | ||
+ | } | ||
+ | .neiyebg { | ||
+ | position: relative; | ||
+ | top: 71px; | ||
+ | width: 100%; | ||
+ | z-index: -1; | ||
+ | /*height:200px;*/ | ||
+ | } | ||
+ | .menu > ul { | ||
+ | width: 100%; | ||
+ | list-style: none; | ||
+ | margin: 0 auto; | ||
+ | padding: 0; | ||
+ | position: relative; | ||
+ | box-sizing: border-box; | ||
− | + | } | |
− | + | ||
+ | .menu > ul:before, .menu > ul:after { | ||
+ | content: ""; | ||
+ | display: table; | ||
+ | } | ||
− | } | + | .menu > ul:after { |
+ | clear: both; | ||
+ | } | ||
− | * { | + | .menu > ul > li { |
+ | float: left; | ||
+ | /*background: #e9e9e9;*/ | ||
+ | padding: 0; | ||
+ | margin: 0; | ||
+ | } | ||
+ | /* | ||
+ | .menu > ul > li:hover { | ||
+ | background: #f0f0f0; | ||
+ | transition: linear 0.5s; | ||
+ | } | ||
+ | */ | ||
+ | .menu > ul > li a { | ||
+ | text-decoration: none; | ||
+ | padding: .5em 0.8em; | ||
+ | display: block; | ||
+ | } | ||
− | a:link,a:visited { | + | .menu > ul > li a:link, a:visited { |
− | + | color: black; | |
− | } | + | } |
+ | |||
+ | .menu > ul > li > ul { | ||
+ | display: none; | ||
+ | width: 100%; | ||
+ | background-color: whitesmoke; | ||
+ | position: absolute; | ||
+ | z-index: 99; | ||
+ | /*left: 0;*/ | ||
+ | margin: 0; | ||
+ | padding:0; | ||
+ | list-style: none; | ||
+ | box-sizing: border-box; | ||
+ | /*border-radius: 5px;*/ | ||
+ | border-radius:8px; | ||
− | .menu | + | } |
− | + | /* | |
− | + | .menu > ul > li > ul:before, .menu > ul > li > ul:after { | |
− | + | content: ""; | |
− | + | display: table; | |
− | + | } | |
− | + | */ | |
− | + | /*.menu > ul > li > ul:after { | |
− | } | + | clear: both; |
+ | }*/ | ||
+ | /*通过JS添加类:normal-sub,为下拉子菜单的格式*/ | ||
+ | .menu > ul > li > ul.normal-sub { | ||
+ | width:12.5em; | ||
+ | /*width: 185px;*/ | ||
+ | left: auto; | ||
+ | } | ||
− | .menu > ul { | + | .menu > ul > li > ul.normal-sub > li { |
− | + | width: 100%; | |
− | + | position: relative; | |
− | + | /*left:16px;*/ | |
− | + | } | |
− | + | ||
− | + | ||
− | } | + | |
− | .menu > ul | + | .menu > ul > li > ul.normal-sub > li:hover { |
− | + | color: white; | |
− | + | background-color: rgba(192,192,192,0.15); | |
− | } | + | } |
− | .menu > ul | + | .menu > ul > li > ul.normal-sub > li a { |
+ | border: 0; | ||
+ | padding: 0.7em 0; | ||
+ | margin: 0 0 0 16px; | ||
+ | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | </style> | |
− | + | </head> | |
− | + | <body> | |
− | + | <div> | |
− | + | <a href="https://2018.igem.org/Team:NAU-CHINA"> | |
− | / | + | <img id="LOGO" src="https://static.igem.org/mediawiki/2018/4/42/T--NAU-CHINA--loading_icon.png" width="150" /> |
− | + | </a> | |
− | + | </div> | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | . | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
+ | <div class="menu"> | ||
+ | <ul> | ||
+ | <li> | ||
+ | <a href="#">TEAM</a> | ||
+ | <ul> | ||
+ | <li><a href="https://2018.igem.org/Team:NAU-CHINA/Team_members">Team members</a></li> | ||
+ | <li><a href="https://2018.igem.org/Team:NAU-CHINA/Collaborations">Collaborations</a></li> | ||
+ | <li><a href="https://2018.igem.org/Team:NAU-CHINA/Attributions">Attributions</a></li> | ||
+ | </ul> | ||
+ | </li> | ||
+ | <li> | ||
+ | <a href="#">PROJECT</a> | ||
+ | <ul> | ||
+ | <li><a href="https://2018.igem.org/Team:NAU-CHINA/Overview">Overview</a></li> | ||
+ | <li><a href="https://2018.igem.org/Team:NAU-CHINA/Design">Design</a></li> | ||
+ | <li><a href="https://2018.igem.org/Team:NAU-CHINA/InterLab">Interlab</a></li> | ||
+ | <li><a href="https://2018.igem.org/Team:NAU-CHINA/Protocols">Protocols</a></li> | ||
+ | <li><a href="https://2018.igem.org/Team:NAU-CHINA/Application_prospects">Application prospects</a></li> | ||
+ | </ul> | ||
+ | </li> | ||
+ | <li> | ||
+ | <a href="#">RESULTS</a> | ||
+ | <ul> | ||
+ | <li><a href="https://2018.igem.org/Team:NAU-CHINA/Demonstrate">Demonstrate</a></li> | ||
+ | <li><a href="https://2018.igem.org/Team:NAU-CHINA/Parts">Parts</a></li> | ||
+ | </ul> | ||
+ | </li> | ||
+ | <li> | ||
+ | <a href="https://2018.igem.org/Team:NAU-CHINA/Model">MODEL</a> | ||
+ | <ul> | ||
+ | <li><a href="https://2018.igem.org/Team:NAU-CHINA/Overview">Overview</a></li> | ||
+ | <li><a href="#">Project Modeling</a></li> | ||
+ | <li><a href="#">Auxiliary Understanding</a></li> | ||
+ | </ul> | ||
+ | </li> | ||
+ | <li> | ||
+ | <a href="https://2018.igem.org/Team:NAU-CHINA/iGEMCloud">iGEMCloud</a> | ||
+ | <ul> | ||
+ | <li><a href="https://2018.igem.org/Team:NAU-CHINA/Software">Software</a></li> | ||
+ | <li><a href="#">Overview</a></li> | ||
+ | <li><a href="#">Main Function</a></li> | ||
+ | </ul> | ||
+ | </li> | ||
+ | <li> | ||
+ | <a href="https://2018.igem.org/Team:NAU-CHINA/Human_Practices">HUMAN PRACTICES</a> | ||
+ | <ul> | ||
+ | <li><a href="#">Overview</a></li> | ||
+ | <li><a href="https://2018.igem.org/Team:NAU-CHINA/Public_Engagement">Public Engagement</a></li> | ||
+ | </ul> | ||
+ | </li> | ||
+ | <li> | ||
+ | <a href="https://2018.igem.org/Team:NAU-CHINA/Safety">SAFETY</a> | ||
+ | <ul> | ||
+ | <li><a href="#">Overview</a></li> | ||
+ | <li><a href="#">Safe Project Design</a></li> | ||
+ | <li><a href="#">Safe Lab Work</a></li> | ||
+ | </ul> | ||
+ | </li> | ||
+ | <li><a href="https://2018.igem.org/Team:NAU-CHINA/Notebook">NOTEBOOK</a></li> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | </ul> | |
− | + | </div> | |
− | + | ||
− | + | ||
− | . | + | <!--<script> |
− | + | $(window).scrollTo(300, 500); | |
− | + | </script>--> | |
− | + | <div class="neiyebg"> | |
− | + | <img src="https://static.igem.org/mediawiki/2018/7/7a/T--NAU-CHINA--neiyebg.png" /> | |
+ | <script> | ||
+ | //调整内页背景图像尺寸至适合屏幕 | ||
+ | var l = $(window).width(); | ||
+ | $(".neiyebg img").attr("width", l - 16); | ||
+ | $(".menu").css("width", l - 16); | ||
+ | $(window).resize(function () { | ||
+ | var l = $(window).width(); | ||
+ | $(".neiyebg img").attr("width", l); | ||
+ | $(".menu").css("width", l); | ||
+ | if ($(window).width() < 1200) { | ||
+ | $(".menu > ul").css("display", "none"); | ||
+ | } | ||
+ | else { | ||
+ | $(".menu > ul").css("display", "block"); | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | </script> | ||
+ | </div > | ||
+ | <div> | ||
+ | <p> | ||
+ | import $ from 'jquery' | ||
+ | import Popper from 'popper.js' | ||
+ | import Util from './util' | ||
− | + | /** | |
+ | * -------------------------------------------------------------------------- | ||
+ | * Bootstrap (v4.1.3): dropdown.js | ||
+ | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | ||
+ | * -------------------------------------------------------------------------- | ||
+ | */ | ||
+ | const Dropdown = (($) => { | ||
+ | /** | ||
+ | * ------------------------------------------------------------------------ | ||
+ | * Constants | ||
+ | * ------------------------------------------------------------------------ | ||
+ | */ | ||
− | + | const NAME = 'dropdown' | |
− | + | const VERSION = '4.1.3' | |
− | + | const DATA_KEY = 'bs.dropdown' | |
− | + | const EVENT_KEY = `.${DATA_KEY}` | |
− | + | const DATA_API_KEY = '.data-api' | |
− | + | const JQUERY_NO_CONFLICT = $.fn[NAME] | |
− | + | const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key | |
− | + | const SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key | |
− | + | const TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key | |
− | + | const ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key | |
− | + | const ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key | |
− | + | const RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse) | |
− | + | const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`) | |
− | + | ||
− | + | const Event = { | |
− | + | HIDE : `hide${EVENT_KEY}`, | |
− | + | HIDDEN : `hidden${EVENT_KEY}`, | |
− | + | SHOW : `show${EVENT_KEY}`, | |
− | + | SHOWN : `shown${EVENT_KEY}`, | |
− | + | CLICK : `click${EVENT_KEY}`, | |
− | + | CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`, | |
− | + | KEYDOWN_DATA_API : `keydown${EVENT_KEY}${DATA_API_KEY}`, | |
− | + | KEYUP_DATA_API : `keyup${EVENT_KEY}${DATA_API_KEY}` | |
− | + | } | |
− | + | ||
− | + | const ClassName = { | |
− | + | DISABLED : 'disabled', | |
− | + | SHOW : 'show', | |
− | + | DROPUP : 'dropup', | |
− | + | DROPRIGHT : 'dropright', | |
− | + | DROPLEFT : 'dropleft', | |
− | + | MENURIGHT : 'dropdown-menu-right', | |
− | + | MENULEFT : 'dropdown-menu-left', | |
− | + | POSITION_STATIC : 'position-static' | |
− | + | } | |
− | + | ||
− | + | const Selector = { | |
− | + | DATA_TOGGLE : '[data-toggle="dropdown"]', | |
− | + | FORM_CHILD : '.dropdown form', | |
− | + | MENU : '.dropdown-menu', | |
− | + | NAVBAR_NAV : '.navbar-nav', | |
− | + | VISIBLE_ITEMS : '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)' | |
− | + | } | |
− | + | ||
− | + | const AttachmentMap = { | |
− | + | TOP : 'top-start', | |
− | + | TOPEND : 'top-end', | |
− | + | BOTTOM : 'bottom-start', | |
− | + | BOTTOMEND : 'bottom-end', | |
− | + | RIGHT : 'right-start', | |
− | + | RIGHTEND : 'right-end', | |
− | + | LEFT : 'left-start', | |
− | + | LEFTEND : 'left-end' | |
− | + | } | |
− | + | ||
− | + | const Default = { | |
− | + | offset : 0, | |
− | + | flip : true, | |
+ | boundary : 'scrollParent', | ||
+ | reference : 'toggle', | ||
+ | display : 'dynamic' | ||
+ | } | ||
+ | |||
+ | const DefaultType = { | ||
+ | offset : '(number|string|function)', | ||
+ | flip : 'boolean', | ||
+ | boundary : '(string|element)', | ||
+ | reference : '(string|element)', | ||
+ | display : 'string' | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * ------------------------------------------------------------------------ | ||
+ | * Class Definition | ||
+ | * ------------------------------------------------------------------------ | ||
+ | */ | ||
+ | |||
+ | class Dropdown { | ||
+ | constructor(element, config) { | ||
+ | this._element = element | ||
+ | this._popper = null | ||
+ | this._config = this._getConfig(config) | ||
+ | this._menu = this._getMenuElement() | ||
+ | this._inNavbar = this._detectNavbar() | ||
+ | |||
+ | this._addEventListeners() | ||
+ | } | ||
+ | |||
+ | // Getters | ||
+ | |||
+ | static get VERSION() { | ||
+ | return VERSION | ||
+ | } | ||
+ | |||
+ | static get Default() { | ||
+ | return Default | ||
+ | } | ||
+ | |||
+ | static get DefaultType() { | ||
+ | return DefaultType | ||
+ | } | ||
+ | |||
+ | // Public | ||
+ | |||
+ | toggle() { | ||
+ | if (this._element.disabled || $(this._element).hasClass(ClassName.DISABLED)) { | ||
+ | return | ||
+ | } | ||
+ | |||
+ | const parent = Dropdown._getParentFromElement(this._element) | ||
+ | const isActive = $(this._menu).hasClass(ClassName.SHOW) | ||
+ | |||
+ | Dropdown._clearMenus() | ||
+ | |||
+ | if (isActive) { | ||
+ | return | ||
+ | } | ||
+ | |||
+ | const relatedTarget = { | ||
+ | relatedTarget: this._element | ||
+ | } | ||
+ | const showEvent = $.Event(Event.SHOW, relatedTarget) | ||
+ | |||
+ | $(parent).trigger(showEvent) | ||
+ | |||
+ | if (showEvent.isDefaultPrevented()) { | ||
+ | return | ||
+ | } | ||
+ | |||
+ | // Disable totally Popper.js for Dropdown in Navbar | ||
+ | if (!this._inNavbar) { | ||
+ | /** | ||
+ | * Check for Popper dependency | ||
+ | * Popper - https://popper.js.org | ||
+ | */ | ||
+ | if (typeof Popper === 'undefined') { | ||
+ | throw new TypeError('Bootstrap dropdown require Popper.js (https://popper.js.org)') | ||
+ | } | ||
+ | |||
+ | let referenceElement = this._element | ||
+ | |||
+ | if (this._config.reference === 'parent') { | ||
+ | referenceElement = parent | ||
+ | } else if (Util.isElement(this._config.reference)) { | ||
+ | referenceElement = this._config.reference | ||
+ | |||
+ | // Check if it's jQuery element | ||
+ | if (typeof this._config.reference.jquery !== 'undefined') { | ||
+ | referenceElement = this._config.reference[0] | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // If boundary is not `scrollParent`, then set position to `static` | ||
+ | // to allow the menu to "escape" the scroll parent's boundaries | ||
+ | // https://github.com/twbs/bootstrap/issues/24251 | ||
+ | if (this._config.boundary !== 'scrollParent') { | ||
+ | $(parent).addClass(ClassName.POSITION_STATIC) | ||
+ | } | ||
+ | this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig()) | ||
+ | } | ||
+ | |||
+ | // If this is a touch-enabled device we add extra | ||
+ | // empty mouseover listeners to the body's immediate children; | ||
+ | // only needed because of broken event delegation on iOS | ||
+ | // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html | ||
+ | if ('ontouchstart' in document.documentElement && | ||
+ | $(parent).closest(Selector.NAVBAR_NAV).length === 0) { | ||
+ | $(document.body).children().on('mouseover', null, $.noop) | ||
+ | } | ||
+ | |||
+ | this._element.focus() | ||
+ | this._element.setAttribute('aria-expanded', true) | ||
+ | |||
+ | $(this._menu).toggleClass(ClassName.SHOW) | ||
+ | $(parent) | ||
+ | .toggleClass(ClassName.SHOW) | ||
+ | .trigger($.Event(Event.SHOWN, relatedTarget)) | ||
+ | } | ||
+ | |||
+ | dispose() { | ||
+ | $.removeData(this._element, DATA_KEY) | ||
+ | $(this._element).off(EVENT_KEY) | ||
+ | this._element = null | ||
+ | this._menu = null | ||
+ | if (this._popper !== null) { | ||
+ | this._popper.destroy() | ||
+ | this._popper = null | ||
+ | } | ||
+ | } | ||
+ | |||
+ | update() { | ||
+ | this._inNavbar = this._detectNavbar() | ||
+ | if (this._popper !== null) { | ||
+ | this._popper.scheduleUpdate() | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // Private | ||
+ | |||
+ | _addEventListeners() { | ||
+ | $(this._element).on(Event.CLICK, (event) => { | ||
+ | event.preventDefault() | ||
+ | event.stopPropagation() | ||
+ | this.toggle() | ||
+ | }) | ||
+ | } | ||
+ | |||
+ | _getConfig(config) { | ||
+ | config = { | ||
+ | ...this.constructor.Default, | ||
+ | ...$(this._element).data(), | ||
+ | ...config | ||
+ | } | ||
+ | |||
+ | Util.typeCheckConfig( | ||
+ | NAME, | ||
+ | config, | ||
+ | this.constructor.DefaultType | ||
+ | ) | ||
+ | |||
+ | return config | ||
+ | } | ||
+ | |||
+ | _getMenuElement() { | ||
+ | if (!this._menu) { | ||
+ | const parent = Dropdown._getParentFromElement(this._element) | ||
+ | if (parent) { | ||
+ | this._menu = parent.querySelector(Selector.MENU) | ||
+ | } | ||
+ | } | ||
+ | return this._menu | ||
+ | } | ||
+ | |||
+ | _getPlacement() { | ||
+ | const $parentDropdown = $(this._element.parentNode) | ||
+ | let placement = AttachmentMap.BOTTOM | ||
+ | |||
+ | // Handle dropup | ||
+ | if ($parentDropdown.hasClass(ClassName.DROPUP)) { | ||
+ | placement = AttachmentMap.TOP | ||
+ | if ($(this._menu).hasClass(ClassName.MENURIGHT)) { | ||
+ | placement = AttachmentMap.TOPEND | ||
+ | } | ||
+ | } else if ($parentDropdown.hasClass(ClassName.DROPRIGHT)) { | ||
+ | placement = AttachmentMap.RIGHT | ||
+ | } else if ($parentDropdown.hasClass(ClassName.DROPLEFT)) { | ||
+ | placement = AttachmentMap.LEFT | ||
+ | } else if ($(this._menu).hasClass(ClassName.MENURIGHT)) { | ||
+ | placement = AttachmentMap.BOTTOMEND | ||
+ | } | ||
+ | return placement | ||
+ | } | ||
+ | |||
+ | _detectNavbar() { | ||
+ | return $(this._element).closest('.navbar').length > 0 | ||
+ | } | ||
+ | |||
+ | _getPopperConfig() { | ||
+ | const offsetConf = {} | ||
+ | if (typeof this._config.offset === 'function') { | ||
+ | offsetConf.fn = (data) => { | ||
+ | data.offsets = { | ||
+ | ...data.offsets, | ||
+ | ...this._config.offset(data.offsets) || {} | ||
+ | } | ||
+ | return data | ||
+ | } | ||
+ | } else { | ||
+ | offsetConf.offset = this._config.offset | ||
+ | } | ||
+ | |||
+ | const popperConfig = { | ||
+ | placement: this._getPlacement(), | ||
+ | modifiers: { | ||
+ | offset: offsetConf, | ||
+ | flip: { | ||
+ | enabled: this._config.flip | ||
+ | }, | ||
+ | preventOverflow: { | ||
+ | boundariesElement: this._config.boundary | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // Disable Popper.js if we have a static display | ||
+ | if (this._config.display === 'static') { | ||
+ | popperConfig.modifiers.applyStyle = { | ||
+ | enabled: false | ||
+ | } | ||
+ | } | ||
+ | return popperConfig | ||
+ | } | ||
+ | |||
+ | // Static | ||
+ | |||
+ | static _jQueryInterface(config) { | ||
+ | return this.each(function () { | ||
+ | let data = $(this).data(DATA_KEY) | ||
+ | const _config = typeof config === 'object' ? config : null | ||
+ | |||
+ | if (!data) { | ||
+ | data = new Dropdown(this, _config) | ||
+ | $(this).data(DATA_KEY, data) | ||
+ | } | ||
+ | |||
+ | if (typeof config === 'string') { | ||
+ | if (typeof data[config] === 'undefined') { | ||
+ | throw new TypeError(`No method named "${config}"`) | ||
+ | } | ||
+ | data[config]() | ||
+ | } | ||
+ | }) | ||
+ | } | ||
+ | |||
+ | static _clearMenus(event) { | ||
+ | if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || | ||
+ | event.type === 'keyup' && event.which !== TAB_KEYCODE)) { | ||
+ | return | ||
+ | } | ||
+ | |||
+ | const toggles = [].slice.call(document.querySelectorAll(Selector.DATA_TOGGLE)) | ||
+ | for (let i = 0, len = toggles.length; i < len; i++) { | ||
+ | const parent = Dropdown._getParentFromElement(toggles[i]) | ||
+ | const context = $(toggles[i]).data(DATA_KEY) | ||
+ | const relatedTarget = { | ||
+ | relatedTarget: toggles[i] | ||
+ | } | ||
+ | |||
+ | if (event && event.type === 'click') { | ||
+ | relatedTarget.clickEvent = event | ||
+ | } | ||
+ | |||
+ | if (!context) { | ||
+ | continue | ||
+ | } | ||
+ | |||
+ | const dropdownMenu = context._menu | ||
+ | if (!$(parent).hasClass(ClassName.SHOW)) { | ||
+ | continue | ||
+ | } | ||
+ | |||
+ | if (event && (event.type === 'click' && | ||
+ | /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && | ||
+ | $.contains(parent, event.target)) { | ||
+ | continue | ||
+ | } | ||
+ | |||
+ | const hideEvent = $.Event(Event.HIDE, relatedTarget) | ||
+ | $(parent).trigger(hideEvent) | ||
+ | if (hideEvent.isDefaultPrevented()) { | ||
+ | continue | ||
+ | } | ||
+ | |||
+ | // If this is a touch-enabled device we remove the extra | ||
+ | // empty mouseover listeners we added for iOS support | ||
+ | if ('ontouchstart' in document.documentElement) { | ||
+ | $(document.body).children().off('mouseover', null, $.noop) | ||
+ | } | ||
+ | |||
+ | toggles[i].setAttribute('aria-expanded', 'false') | ||
+ | |||
+ | $(dropdownMenu).removeClass(ClassName.SHOW) | ||
+ | $(parent) | ||
+ | .removeClass(ClassName.SHOW) | ||
+ | .trigger($.Event(Event.HIDDEN, relatedTarget)) | ||
+ | } | ||
+ | } | ||
+ | |||
+ | static _getParentFromElement(element) { | ||
+ | let parent | ||
+ | const selector = Util.getSelectorFromElement(element) | ||
+ | |||
+ | if (selector) { | ||
+ | parent = document.querySelector(selector) | ||
+ | } | ||
+ | |||
+ | return parent || element.parentNode | ||
+ | } | ||
+ | |||
+ | // eslint-disable-next-line complexity | ||
+ | static _dataApiKeydownHandler(event) { | ||
+ | // If not input/textarea: | ||
+ | // - And not a key in REGEXP_KEYDOWN => not a dropdown command | ||
+ | // If input/textarea: | ||
+ | // - If space key => not a dropdown command | ||
+ | // - If key is other than escape | ||
+ | // - If key is not up or down => not a dropdown command | ||
+ | // - If trigger inside the menu => not a dropdown command | ||
+ | if (/input|textarea/i.test(event.target.tagName) | ||
+ | ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE && | ||
+ | (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE || | ||
+ | $(event.target).closest(Selector.MENU).length) : !REGEXP_KEYDOWN.test(event.which)) { | ||
+ | return | ||
+ | } | ||
+ | |||
+ | event.preventDefault() | ||
+ | event.stopPropagation() | ||
+ | |||
+ | if (this.disabled || $(this).hasClass(ClassName.DISABLED)) { | ||
+ | return | ||
+ | } | ||
+ | |||
+ | const parent = Dropdown._getParentFromElement(this) | ||
+ | const isActive = $(parent).hasClass(ClassName.SHOW) | ||
+ | |||
+ | if (!isActive && (event.which !== ESCAPE_KEYCODE || event.which !== SPACE_KEYCODE) || | ||
+ | isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) { | ||
+ | if (event.which === ESCAPE_KEYCODE) { | ||
+ | const toggle = parent.querySelector(Selector.DATA_TOGGLE) | ||
+ | $(toggle).trigger('focus') | ||
+ | } | ||
+ | |||
+ | $(this).trigger('click') | ||
+ | return | ||
+ | } | ||
+ | |||
+ | const items = [].slice.call(parent.querySelectorAll(Selector.VISIBLE_ITEMS)) | ||
+ | |||
+ | if (items.length === 0) { | ||
+ | return | ||
+ | } | ||
+ | |||
+ | let index = items.indexOf(event.target) | ||
+ | |||
+ | if (event.which === ARROW_UP_KEYCODE && index > 0) { // Up | ||
+ | index-- | ||
+ | } | ||
+ | |||
+ | if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // Down | ||
+ | index++ | ||
+ | } | ||
+ | |||
+ | if (index < 0) { | ||
+ | index = 0 | ||
+ | } | ||
+ | |||
+ | items[index].focus() | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * ------------------------------------------------------------------------ | ||
+ | * Data Api implementation | ||
+ | * ------------------------------------------------------------------------ | ||
+ | */ | ||
+ | |||
+ | $(document) | ||
+ | .on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler) | ||
+ | .on(Event.KEYDOWN_DATA_API, Selector.MENU, Dropdown._dataApiKeydownHandler) | ||
+ | .on(`${Event.CLICK_DATA_API} ${Event.KEYUP_DATA_API}`, Dropdown._clearMenus) | ||
+ | .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { | ||
+ | event.preventDefault() | ||
+ | event.stopPropagation() | ||
+ | Dropdown._jQueryInterface.call($(this), 'toggle') | ||
+ | }) | ||
+ | .on(Event.CLICK_DATA_API, Selector.FORM_CHILD, (e) => { | ||
+ | e.stopPropagation() | ||
+ | }) | ||
+ | |||
+ | /** | ||
+ | * ------------------------------------------------------------------------ | ||
+ | * jQuery | ||
+ | * ------------------------------------------------------------------------ | ||
+ | */ | ||
+ | |||
+ | $.fn[NAME] = Dropdown._jQueryInterface | ||
+ | $.fn[NAME].Constructor = Dropdown | ||
+ | $.fn[NAME].noConflict = function () { | ||
+ | $.fn[NAME] = JQUERY_NO_CONFLICT | ||
+ | return Dropdown._jQueryInterface | ||
+ | } | ||
+ | |||
+ | return Dropdown | ||
+ | })($, Popper) | ||
+ | |||
+ | export default Dropdown | ||
+ | |||
+ | </p> | ||
</div> | </div> | ||
+ | <script> | ||
+ | $(document).ready(function () { | ||
+ | $('.menu > ul > li > ul:not(:has(ul))').addClass('normal-sub'); | ||
+ | //导航背景变色+下滑方法 | ||
+ | $(".menu > ul > li").hover(function () { | ||
+ | //$(this).css({ "background-color": "#f0f0f0" }); | ||
+ | $(this).children("ul").stop(true, false).slideToggle(300); | ||
+ | }); | ||
+ | //背景颜色还原+下拉菜单消失 | ||
+ | $(".menu > ul > li").mouseleave(function () { | ||
+ | //$(this).css({ "background-color": "transparent" }); | ||
+ | $(this).children("ul").hide(); | ||
+ | }); | ||
+ | }); | ||
+ | </script> | ||
+ | <script> | ||
+ | |||
− | + | ||
− | + | </script> | |
− | + | </body> | |
− | / | + | </html> |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | </ | + |
Revision as of 11:17, 12 October 2018
import $ from 'jquery' import Popper from 'popper.js' import Util from './util' /** * -------------------------------------------------------------------------- * Bootstrap (v4.1.3): dropdown.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ const Dropdown = (($) => { /** * ------------------------------------------------------------------------ * Constants * ------------------------------------------------------------------------ */ const NAME = 'dropdown' const VERSION = '4.1.3' const DATA_KEY = 'bs.dropdown' const EVENT_KEY = `.${DATA_KEY}` const DATA_API_KEY = '.data-api' const JQUERY_NO_CONFLICT = $.fn[NAME] const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key const SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key const TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key const ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key const ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key const RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse) const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`) const Event = { HIDE : `hide${EVENT_KEY}`, HIDDEN : `hidden${EVENT_KEY}`, SHOW : `show${EVENT_KEY}`, SHOWN : `shown${EVENT_KEY}`, CLICK : `click${EVENT_KEY}`, CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`, KEYDOWN_DATA_API : `keydown${EVENT_KEY}${DATA_API_KEY}`, KEYUP_DATA_API : `keyup${EVENT_KEY}${DATA_API_KEY}` } const ClassName = { DISABLED : 'disabled', SHOW : 'show', DROPUP : 'dropup', DROPRIGHT : 'dropright', DROPLEFT : 'dropleft', MENURIGHT : 'dropdown-menu-right', MENULEFT : 'dropdown-menu-left', POSITION_STATIC : 'position-static' } const Selector = { DATA_TOGGLE : '[data-toggle="dropdown"]', FORM_CHILD : '.dropdown form', MENU : '.dropdown-menu', NAVBAR_NAV : '.navbar-nav', VISIBLE_ITEMS : '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)' } const AttachmentMap = { TOP : 'top-start', TOPEND : 'top-end', BOTTOM : 'bottom-start', BOTTOMEND : 'bottom-end', RIGHT : 'right-start', RIGHTEND : 'right-end', LEFT : 'left-start', LEFTEND : 'left-end' } const Default = { offset : 0, flip : true, boundary : 'scrollParent', reference : 'toggle', display : 'dynamic' } const DefaultType = { offset : '(number|string|function)', flip : 'boolean', boundary : '(string|element)', reference : '(string|element)', display : 'string' } /** * ------------------------------------------------------------------------ * Class Definition * ------------------------------------------------------------------------ */ class Dropdown { constructor(element, config) { this._element = element this._popper = null this._config = this._getConfig(config) this._menu = this._getMenuElement() this._inNavbar = this._detectNavbar() this._addEventListeners() } // Getters static get VERSION() { return VERSION } static get Default() { return Default } static get DefaultType() { return DefaultType } // Public toggle() { if (this._element.disabled || $(this._element).hasClass(ClassName.DISABLED)) { return } const parent = Dropdown._getParentFromElement(this._element) const isActive = $(this._menu).hasClass(ClassName.SHOW) Dropdown._clearMenus() if (isActive) { return } const relatedTarget = { relatedTarget: this._element } const showEvent = $.Event(Event.SHOW, relatedTarget) $(parent).trigger(showEvent) if (showEvent.isDefaultPrevented()) { return } // Disable totally Popper.js for Dropdown in Navbar if (!this._inNavbar) { /** * Check for Popper dependency * Popper - https://popper.js.org */ if (typeof Popper === 'undefined') { throw new TypeError('Bootstrap dropdown require Popper.js (https://popper.js.org)') } let referenceElement = this._element if (this._config.reference === 'parent') { referenceElement = parent } else if (Util.isElement(this._config.reference)) { referenceElement = this._config.reference // Check if it's jQuery element if (typeof this._config.reference.jquery !== 'undefined') { referenceElement = this._config.reference[0] } } // If boundary is not `scrollParent`, then set position to `static` // to allow the menu to "escape" the scroll parent's boundaries // https://github.com/twbs/bootstrap/issues/24251 if (this._config.boundary !== 'scrollParent') { $(parent).addClass(ClassName.POSITION_STATIC) } this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig()) } // If this is a touch-enabled device we add extra // empty mouseover listeners to the body's immediate children; // only needed because of broken event delegation on iOS // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html if ('ontouchstart' in document.documentElement && $(parent).closest(Selector.NAVBAR_NAV).length === 0) { $(document.body).children().on('mouseover', null, $.noop) } this._element.focus() this._element.setAttribute('aria-expanded', true) $(this._menu).toggleClass(ClassName.SHOW) $(parent) .toggleClass(ClassName.SHOW) .trigger($.Event(Event.SHOWN, relatedTarget)) } dispose() { $.removeData(this._element, DATA_KEY) $(this._element).off(EVENT_KEY) this._element = null this._menu = null if (this._popper !== null) { this._popper.destroy() this._popper = null } } update() { this._inNavbar = this._detectNavbar() if (this._popper !== null) { this._popper.scheduleUpdate() } } // Private _addEventListeners() { $(this._element).on(Event.CLICK, (event) => { event.preventDefault() event.stopPropagation() this.toggle() }) } _getConfig(config) { config = { ...this.constructor.Default, ...$(this._element).data(), ...config } Util.typeCheckConfig( NAME, config, this.constructor.DefaultType ) return config } _getMenuElement() { if (!this._menu) { const parent = Dropdown._getParentFromElement(this._element) if (parent) { this._menu = parent.querySelector(Selector.MENU) } } return this._menu } _getPlacement() { const $parentDropdown = $(this._element.parentNode) let placement = AttachmentMap.BOTTOM // Handle dropup if ($parentDropdown.hasClass(ClassName.DROPUP)) { placement = AttachmentMap.TOP if ($(this._menu).hasClass(ClassName.MENURIGHT)) { placement = AttachmentMap.TOPEND } } else if ($parentDropdown.hasClass(ClassName.DROPRIGHT)) { placement = AttachmentMap.RIGHT } else if ($parentDropdown.hasClass(ClassName.DROPLEFT)) { placement = AttachmentMap.LEFT } else if ($(this._menu).hasClass(ClassName.MENURIGHT)) { placement = AttachmentMap.BOTTOMEND } return placement } _detectNavbar() { return $(this._element).closest('.navbar').length > 0 } _getPopperConfig() { const offsetConf = {} if (typeof this._config.offset === 'function') { offsetConf.fn = (data) => { data.offsets = { ...data.offsets, ...this._config.offset(data.offsets) || {} } return data } } else { offsetConf.offset = this._config.offset } const popperConfig = { placement: this._getPlacement(), modifiers: { offset: offsetConf, flip: { enabled: this._config.flip }, preventOverflow: { boundariesElement: this._config.boundary } } } // Disable Popper.js if we have a static display if (this._config.display === 'static') { popperConfig.modifiers.applyStyle = { enabled: false } } return popperConfig } // Static static _jQueryInterface(config) { return this.each(function () { let data = $(this).data(DATA_KEY) const _config = typeof config === 'object' ? config : null if (!data) { data = new Dropdown(this, _config) $(this).data(DATA_KEY, data) } if (typeof config === 'string') { if (typeof data[config] === 'undefined') { throw new TypeError(`No method named "${config}"`) } data[config]() } }) } static _clearMenus(event) { if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) { return } const toggles = [].slice.call(document.querySelectorAll(Selector.DATA_TOGGLE)) for (let i = 0, len = toggles.length; i < len; i++) { const parent = Dropdown._getParentFromElement(toggles[i]) const context = $(toggles[i]).data(DATA_KEY) const relatedTarget = { relatedTarget: toggles[i] } if (event && event.type === 'click') { relatedTarget.clickEvent = event } if (!context) { continue } const dropdownMenu = context._menu if (!$(parent).hasClass(ClassName.SHOW)) { continue } if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $.contains(parent, event.target)) { continue } const hideEvent = $.Event(Event.HIDE, relatedTarget) $(parent).trigger(hideEvent) if (hideEvent.isDefaultPrevented()) { continue } // If this is a touch-enabled device we remove the extra // empty mouseover listeners we added for iOS support if ('ontouchstart' in document.documentElement) { $(document.body).children().off('mouseover', null, $.noop) } toggles[i].setAttribute('aria-expanded', 'false') $(dropdownMenu).removeClass(ClassName.SHOW) $(parent) .removeClass(ClassName.SHOW) .trigger($.Event(Event.HIDDEN, relatedTarget)) } } static _getParentFromElement(element) { let parent const selector = Util.getSelectorFromElement(element) if (selector) { parent = document.querySelector(selector) } return parent || element.parentNode } // eslint-disable-next-line complexity static _dataApiKeydownHandler(event) { // If not input/textarea: // - And not a key in REGEXP_KEYDOWN => not a dropdown command // If input/textarea: // - If space key => not a dropdown command // - If key is other than escape // - If key is not up or down => not a dropdown command // - If trigger inside the menu => not a dropdown command if (/input|textarea/i.test(event.target.tagName) ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE && (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE || $(event.target).closest(Selector.MENU).length) : !REGEXP_KEYDOWN.test(event.which)) { return } event.preventDefault() event.stopPropagation() if (this.disabled || $(this).hasClass(ClassName.DISABLED)) { return } const parent = Dropdown._getParentFromElement(this) const isActive = $(parent).hasClass(ClassName.SHOW) if (!isActive && (event.which !== ESCAPE_KEYCODE || event.which !== SPACE_KEYCODE) || isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) { if (event.which === ESCAPE_KEYCODE) { const toggle = parent.querySelector(Selector.DATA_TOGGLE) $(toggle).trigger('focus') } $(this).trigger('click') return } const items = [].slice.call(parent.querySelectorAll(Selector.VISIBLE_ITEMS)) if (items.length === 0) { return } let index = items.indexOf(event.target) if (event.which === ARROW_UP_KEYCODE && index > 0) { // Up index-- } if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // Down index++ } if (index < 0) { index = 0 } items[index].focus() } } /** * ------------------------------------------------------------------------ * Data Api implementation * ------------------------------------------------------------------------ */ $(document) .on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler) .on(Event.KEYDOWN_DATA_API, Selector.MENU, Dropdown._dataApiKeydownHandler) .on(`${Event.CLICK_DATA_API} ${Event.KEYUP_DATA_API}`, Dropdown._clearMenus) .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { event.preventDefault() event.stopPropagation() Dropdown._jQueryInterface.call($(this), 'toggle') }) .on(Event.CLICK_DATA_API, Selector.FORM_CHILD, (e) => { e.stopPropagation() }) /** * ------------------------------------------------------------------------ * jQuery * ------------------------------------------------------------------------ */ $.fn[NAME] = Dropdown._jQueryInterface $.fn[NAME].Constructor = Dropdown $.fn[NAME].noConflict = function () { $.fn[NAME] = JQUERY_NO_CONFLICT return Dropdown._jQueryInterface } return Dropdown })($, Popper) export default Dropdown