Bootstrap is the most popular HTML, CSS and JS framework for developing responsive layouts, mobile-first WEB projects. ― Bootstrap Chinese Documentation
Bootstrap has become the most popular front-end development framework because of its support for responsive layout, mobile device priority, and easy to use and easy to learn.
Bootstrap's responsive design, component development, and JavaScript plug-in development and preprocessing script development methods are also worth learning.
source code
Source code download and compilation
It is recommended to download the latest and most complete Bootstrap source code on GitHub.
GitHub is a Bootstrap source code hosting repository that contains not only the source code, but also the source files of the Bootstrap documentation. Therefore, you can browse documents on the local machine by compiling and running the document source code without a network.
Source Code Directory
The bootstrap source code directory contains:
• Document deployment code subdirectory_gh_pages/
•Document source code subdirectory docs/
•bootstrap deployment code subdirectory dist/
•bootstrap script subdirectory js/
•bootstrap style subdirectory less/
•bootstrap font subdirectory fonts/
•grunt build tool script subdirectory grunt/
• Package Manager nuget subdirectory nuget/
•Many configuration files
Point of entry
The source code of the Bootstrap framework is very complex, and it is undoubtedly difficult to analyze from the perspective of the author's development framework. The problem can be simplified, without paying attention to how the framework is built or deployed, but only focusing on how the framework works, namely the HTML, CSS/LESS and JS parts.
Through the idea of division and governance, complex problems are broken down into many simple problems and solved. When all small problems are solved, complex problems will be solved easily.
Divide the entire Bootstrap framework into components, take components as the entry point, understand their working principle, and then gradually analyze the entire framework.
Component Analysis
dropdown menu dropdown
HTML code
<!-- Component: drop-down menu--><div> <!-- Trigger button--> <button type="button" data-toggle="dropdown"> Dropdown <span></span> </button> <!-- drop-down menu--> <ul> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> </ul></div>
Note: The accessible attribute aria-* in the source code is removed from the code for easy analysis. It cannot be omitted in practical applications. The button style is not expanded here for analysis
CSS Code
// Dropdown arrow/caret.caret { display: inline-block; width: 0; height: 0; margin-left: 2px; vertical-align: middle; border-top: @caret-width-base dashed; border-top: @caret-width-base solid ~"/9"; // IE8 border-right: @caret-width-base solid transparent; border-left: @caret-width-base solid transparent;}// The dropdown wrapper (div).dropup,.dropdown { position: relative; // relative positioning of parent element}// Prevent the focus on the dropdown toggle when closing dropdowns.dropdown-toggle:focus { outline: 0;}// The dropdown menu (ul).dropdown-menu { position: absolute; // absolute positioning of child elements top: 100%; // The dropdown menu is close to the lower edge of parent element left: 0; z-index: @zindex-dropdown; display: none; //Hide by default, when the trigger button is displayed (display:block) float: left; min-width: 160px; padding: 5px 0; margin: 2px 0 0; // override default ul list-style: none; font-size: @font-size-base; text-align: left; background-color: @dropdown-bg; border: 1px solid @dropdown-fallback-border; // IE8 fallback border: 1px solid @dropdown-border; border-radius: @border-radius-base; .box-shadow(0 6px 12px rgba(0,0,0,.175)); background-clip: padding-box; // Aligns the dropdown menu to right &.pull-right { right: 0; left: auto; } // Horizontal divider with height of 1px.divider { .nav-divider(@dropdown-divider-bg); } // Links within the dropdown menu > li > a { display: block; padding: 3px 20px; clear: both; font-weight: normal; line-height: @line-height-base; color: @dropdown-link-color; white-space: nowrap; // Prevent links from wrapping}}// Hover/Focus state.dropdown-menu > li > a { &:hover, &:focus { text-decoration: none; color: @dropdown-link-hover-color; background-color: @dropdown-link-hover-bg; }}// Active state.dropdown-menu > .active > a { &, &:hover, &:focus { color: @dropdown-link-active-color; text-decoration: none; outline: 0; background-color: @dropdown-link-active-bg; }}// Show the dropdown menu.open { > .dropdown-menu { display: block; // Show } // Remove the outline when :focus is triggered > a { outline: 0; }}// Menu positioning.dropdown-menu-right { left: auto; // Reset the default from `.dropdown-menu` right: 0;}// `.pull-right` nav component..dropdown-menu-left { left: 0; right: auto;}// Dropdown section headers.dropdown-header { display: block; padding: 3px 20px; font-size: @font-size-small; line-height: @line-height-base; color: @dropdown-header-color; white-space: nowrap; // as with > li > a}// Non-dropdown menu area.dropdown-backdrop { position: fixed; left: 0; right: 0; bottom: 0; top: 0; z-index: (@zindex-dropdown - 10); //Make sure that the dropdown menu will not be closed when clicking the dropdown menu}// Right aligned dropdowns.pull-right > .dropdown-menu { right: 0; left: auto;}// Allow for dropdowns to go bottom up (aka, dropup-menu)//// Just add .dropup after the standard .dropdown class and you're set, bro.// TODO: abstract this so that the navbar fixed styles are not placed here?.dropup,.navbar-fixed-bottom .dropdown { // Reverse the caret .caret { border-top: 0; border-bottom: @caret-width-base dashed; border-bottom: @caret-width-base solid ~"/9"; // IE8 content: ""; } // Different positioning for bottom up menu .dropdown-menu { top: auto; bottom: 100%; margin-bottom: 2px; }}// Component alignment//// Reiterate per navbar.less and the modified component alignment there.@media (min-width: @grid-float-breakpoint) { .navbar-right { .dropdown-menu { .dropdown-menu-right(); } // Necessary for overrides of the default right aligned menu. // Will remove come v4 in all likelihood. .dropdown-menu-left { .dropdown-menu-left(); } }}The behavior of this drop-down menu component is: when the trigger button is clicked, the drop-down menu is displayed below it, and when the non-drop-down menu area is clicked, the drop-down menu is hidden.
Implementation principle:
1. Only the trigger button is displayed at the beginning, the .dropdown wrapper default drop-down menu is closed, and .dropdown-menu hides display:none by default
2. When the trigger button is clicked, add class .open after .dropdown. In .open, the display value of .dropdown-menu is block. So add/remove.open class means show/hide the drop-down menu.
3. When clicking on the non-dropdown menu area, .dropdown deletes the class.open, that is, hides the dropdown menu. The principle of implementing the non-drop-down menu area is that fixed positioning, tiling, and z-index are smaller than the drop-down menu, so that the drop-down menu will not be hidden when clicking the drop-down menu.
JavaScript Code
/* ============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================= Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ================================================================================================================================== var backdrop = '.dropdown-backdrop' var toggle = '[data-toggle="dropdown"]' var Dropdown = function (element) { $(element).on('click.bs.dropdown', this.toggle) } Dropdown.VERSION = '3.3.6' function getParent($this) { var selector = $this.attr('data-target') if (!selector) { selector = $this.attr('href') selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^/s]*$)/, '') // strip for ie7 } var $parent = selector && $(selector) return $parent && $parent.length ? $parent : $this.parent() } function clearMenus(e) { if (e && e.which === 3) return $(backdrop).remove() $(toggle).each(function () { var $this = $(this) var $parent = getParent($this) var relatedTarget = { relatedTarget: this } if (!$parent.hasClass('open')) return if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) if (e.isDefaultPrevented()) return $this.attr('aria-expanded', 'false') $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget)) }) } Dropdown.prototype.toggle = function (e) { var $this = $(this) if ($this.is('.disabled, :disabled')) return var $parent = getParent($this) var isActive = $parent.hasClass('open') clearMenus() if (!isActive) { if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { // if mobile we use a backdrop because click events don't delegate $(document.createElement('div')) .addClass('dropdown-backdrop') .insertAfter($(this)) .on('click', clearMenus) } var relatedTarget = { relatedTarget: this } $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) if (e.isDefaultPrevented()) return $this .trigger('focus') .attr('aria-expanded', 'true') $parent .toggleClass('open') .trigger($.Event('shown.bs.dropdown', relatedTarget)) } return false } Dropdown.prototype.keydown = function (e) { if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return var $this = $(this) e.preventDefault() e.stopPropagation() if ($this.is('.disabled, :disabled')) return var $parent = getParent($this) var isActive = $parent.hasClass('open') if (!isActive && e.which != 27 || isActive && e.which == 27) { if (e.which == 27) $parent.find(toggle).trigger('focus') return $this.trigger('click') } var desc = ' li:not(.disabled):visible a' var $items = $parent.find('.dropdown-menu' + desc) if (!$items.length) return var index = $items.index(e.target) if (e.which == 38 && index > 0) index-- // up if (e.which == 40 && index < $items.length - 1) index++ // down if (!~index) index = 0 $items.eq(index).trigger('focus') } // DROPDOWN PLUGIN DEFINITION // ====================================================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.dropdown') if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) if (typeof option == 'string') data[option].call($this) }) } var old = $.fn.dropdown $.fn.dropdown = Plugin $.fn.dropdown.Constructor = Dropdown // DROPDOWN NO CONFLICT // ================================= $.fn.dropdown.noConflict = function () { $.fn.dropdown = old return this } // APPLY TO STANDARD DROPDOWN ELEMENTS // ============================================================================================================================================================ $(document) .on('click.bs.dropdown.data-api', clearMenus) .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)}(jQuery);The Javascript code structure can be divided into three parts:
1. Class definition lines 1-125
2. Plugin definition lines 126-144
3. Resolve conflict lines 148-153
4. Apply to standard drop-down menu elements lines 155-166
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.