⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jquery.mcdropdown.js

📁 Ajax学习的一个经典范例
💻 JS
📖 第 1 页 / 共 3 页
字号:
	
			// if IE6, add the hover class
			$(this).addClass("mc_hover");

			// show the branch
			$.data(self, "timer", setTimeout(function(){
					showBranch.apply(self);
				}, settings.hoverOverDelay)
			);
	  };
		
		function hoverOut(e){
			var self = this;
			var timer = $.data(self, "timer");
			
			// if the timer exists, clear it
			if( !isNaN(timer) ) clearTimeout(timer);
	
			// if IE6, remove the hover class
			$(this).removeClass("mc_hover");
			
			// hide the branch
			$.data(self, "timer", setTimeout(function(){
					var $li = $(self);
					setTimeout(function (){
						// if no children selected, we must close the parent menus
						if( $li.parent().find("> li.mc_hover").length == 0 ){
							$li.parents("li").each(function (){
								var self = this;
								clearTimeout($.data(self, "timer"));
								hideBranch.apply(self);
								// check to see if we've hovered over a parent item
								if( $(this).siblings().filter(".mc_hover").length > 0 ) return false;
							});
					}
						
					}, settings.hoverOverDelay);

					hideBranch.apply(self);
				}, settings.hoverOutDelay)
			);
			
			// this will stop flickering in IE6, but it leaves mc_hover classes behind
			if( isIE6 ) e.stopPropagation();
	  };
		
		function getShadow(depth){
			var shadows = $self.data("shadows");
			
			// if the shadows don't exist, create an object to track them
			if( !shadows ) 
				shadows = {};
			
			// if the shadow doesn't exist, create it
			if( !shadows[depth] ){
				// create shadow
				shadows[depth] = $('<div class="mcdropdown_shadow"></div>').appendTo('body');
				// if the bgIframe exists, use the plug-in
				if( !!$.fn.bgIframe ) shadows[depth].bgIframe();
				// update the shadows cache
				$self.data("shadows", shadows);
			}
			
			return shadows[depth];
		};
		
		function showBranch(){
			var self = this;
			// the child menu
			var $ul = $("> ul", this);
			
			// if the menu is already visible or there is no submenu, cancel
			if( $ul.is(":visible") || ($ul.length == 0) ) return false;
			
			// hide any visible sibling menus
			$(this).parent().find('> li ul:visible').not($ul).parent().each(function(){
				hideBranch.apply(this);
			});
			
			// columnize the list
			columnizeList($ul);
			
			// add new bindings
			addBindings($ul);
	
			var depth = $ul.parents("ul").length;
			
			// get the screen dimensions
			var sd = getScreenDimensions();
			
			// get the coordinates for the menu item
			var li_coords = position($(this));
	
			// move the menu to the correct position and show the menu || ((depth)*2)
			$ul.css({top: li_coords.bottom, left: li_coords.marginLeft/*, zIndex: settings.baseZIndex + ((depth)*2)*/}).show();
	
			// get the bottom of the menu
			var menuBottom = $ul.outerHeight() + $ul.offset().top;
	
			// if we're hidden off the bottom of the page, move up
			if( menuBottom > sd.y ){
				// adjust the menu by subtracting the bottom edge by the screen offset
				$ul.css("top", li_coords.bottom - (menuBottom - sd.y) - settings.screenPadding);
			}
			
			var showShadow = function (){
				// if using drop shadows, then show them		
				if( settings.dropShadow ){
					// get a reference to the current shadow
					var $shadow = getShadow(depth);
					// get the position of the parent element
					var pos = position($ul);
					
					// move the shadow to the correct visual & DOM position
					$shadow.css({
						  top: pos.top + pos.marginTop
						, left: pos.left + pos.marginLeft
						, width: pos.width
						, height: pos.height
						/*, zIndex: settings.baseZIndex + ((2*depth)-1)*/
					}).insertAfter($ul).show();
			
					// store a reference to the shadow so we can hide it		
					$.data(self, "shadow", $shadow);
				}
			}
			
			// columnize the list and then show it using the defined effect
			// if the menu has a zero delay, just open it and then draw the
			// shadow, otherwise show the effect and the draw the shadow
			// after you're done.
			if( settings.showSpeed <= 0 ){
				showShadow();
			} else {
				$ul.hide()[settings.showFx](settings.showSpeed, showShadow);
			}
		};
		
		function hideBranch(){
			var $ul = $("> ul", this);
			// if the menu is already visible or there is no submenu, cancel
			if( $ul.is(":hidden") || ($ul.length == 0) ) return false;
			
			// if using drop shadows, then hide
			if( settings.dropShadow && $.data(this, "shadow") ) $.data(this, "shadow").hide();
	
			// if we're IE6, we need to set the visiblity to "hidden" so child
			// menus are correctly hidden and remove the .mc_hover class due to
			// the e.stopPropagation() call in the hoverOut() call
			if( isIE6 )
				$ul.css("visibility", "hidden").parent().removeClass("mc_hover");
	
			// hide the menu
			$ul.stop()[settings.hideFx](settings.hideSpeed);
		};
	
		function position($el){
			var bHidden = false;
			// if the element is hidden we must make it visible to the DOM to get
			if ($el.is(":hidden")) {
				bHidden = !!$el.css("visibility", "hidden").show();
			}
			
			var pos = $.extend($el.position(),{
				  width: $el.outerWidth()
				, height: $el.outerHeight()
				, marginLeft: parseInt($.curCSS($el[0], "marginLeft", true), 10) || 0
				, marginRight: parseInt($.curCSS($el[0], "marginRight", true), 10) || 0
				, marginTop: parseInt($.curCSS($el[0], "marginTop", true), 10) || 0
				, marginBottom: parseInt($.curCSS($el[0], "marginBottom", true), 10) || 0
			});
			
			if( pos.marginTop < 0 ) pos.top += pos.marginTop;
			if( pos.marginLeft < 0 ) pos.left += pos.marginLeft;
			
			pos["bottom"] = pos.top + pos.height;
			pos["right"] = pos.left + pos.width;
			
			// hide the element again
			if( bHidden ) $el.hide().css("visibility", "visible");
	
			return pos;
		};
		
		function anchorTo($anchor, $target){
			var pos = position($anchor);
			
			$target.css({
				  position: "absolute"
				, top: pos.bottom
				, left: pos.left
			});
			
			/*
			 * we need to return the top edge of the core drop down menu, because
			 * the top:0 starts at this point when repositioning items absolutely
			 * this means we have to offset everything by the offset of the top menu
			 */ 
			
			return pos.bottom;
		};
		
		function getScreenDimensions(){
			var d = {
				  scrollLeft: $(window).scrollLeft()
				, scrollTop:  $(window).scrollTop()
				, width:      $(window).width()     // changed from innerWidth
				, height:     $(window).height()    // changed from innerHeight			
			};
			
			// calculate the correct x/y positions
			d.x = d.scrollLeft + d.width;
			d.y = d.scrollTop + d.height;
			
			return d;
		};
		
		function getPadding(el, name){
			var torl = name == 'height' ? 'Top'    : 'Left',  // top or left
			    borr = name == 'height' ? 'Bottom' : 'Right'; // bottom or right
			
			return (
				// we add "0" to each string to make sure parseInt() returns a number
			    parseInt("0"+$.curCSS(el, "border"+torl+"Width", true), 10)
				+ parseInt("0"+$.curCSS(el, "border"+borr+"Width", true), 10)
				+ parseInt("0"+$.curCSS(el, "padding"+torl, true), 10)
				+ parseInt("0"+$.curCSS(el, "padding"+borr, true), 10)
				+ parseInt("0"+$.curCSS(el, "margin"+torl, true), 10)
				+ parseInt("0"+$.curCSS(el, "margin"+borr, true), 10)
			);
		};
		
		function getListDimensions($el, cols){
			if( !$el.data("dimensions") ){
				// get the width of the dropdown menu
				var ddWidth = $divInput.outerWidth();
				// if showing the root item, then try to make sure the width of the menu is sized to the drop down menu
				var width = ( ($el === $list) && ($el.data("width") * cols < ddWidth) ) ? Math.floor(ddWidth/cols) : $el.data("width");
		
				$el.data("dimensions", {
					// get the original width of the list item
					column: width
					// subtract the padding from the first list item from the width to get the width of the items
					, item: width - getPadding($el.children().eq(0)[0], "width")
					// get the original height
					, height: $el.height()
				});
			}
			
			return $el.data("dimensions");
		};
		
		function getHeight($el){
			// if we haven't cached our height, do so now
			if( !$el.data("height") ) $el.data("height", $el.outerHeight());
	
			// return the cached value
			return $el.data("height");
		};
		
		function columnizeList($el){
			// get the children items
			var $children = $el.find("> li");
			// get the total number of items
			var items = $children.length;
			
			// calculate how many columns we think we should have based on the max rows
			var calculatedCols = Math.ceil(items/settings.maxRows);
			// get the number of columns, don't columnize if we don't have enough rows
			// if the height of the column is bigger than the screen, we automatically try 
			// moving to a new column
			var cols = !!arguments[1] ? arguments[1] : ( items <= settings.minRows ) ? 1 : (calculatedCols > settings.targetColumnSize) ? calculatedCols : settings.targetColumnSize;
			// get the dimension of this element
			var widths = getListDimensions($el, cols);
			var prevColumn = 0;
			var columnHeight = 0;
			var maxColumnHeight = 0;
			var maxRows = Math.ceil(items/cols);
	
			// get the width of the parent item
			var parentLIWidth = $el.parent("li").width();
	
			// if the parent list item is wider than the child menu, increase the size		
			if( parentLIWidth > (widths.column * cols) ){
				// get the difference in the widths so we can adjust
				var widthDiff = parentLIWidth - widths.column;
				widths.column += parentLIWidth;
				widths.item += widthDiff;
			}
			
			// we need to draw the list element, but hide it so we can correctly calculate it's information
			$el.css({"visibility": "hidden", "display": "block"});
			
			// loop through each child item
			$children.each(function (i){
				var currentItem = i+1;
				var nextItemColumn = Math.floor((currentItem/items) * cols);
				// calculate the column we're in
				var column = Math.floor((i/items) * cols);
				// reference the current item
				var $li = $(this);
				// variable to track margin-top
				var marginTop;
	
				// if we're in the same column
				if( prevColumn != column ){
					// move to the top of the next column
					marginTop = (columnHeight+1) * -1;
					// reset column height
					columnHeight = 0;
				// if we're in a new column
				} else {
					marginTop = 0;
				}
				
				// increase the column height based on it's current height (calculate this before adding classes)
				columnHeight += (getHeight($li) || settings.lineHeight);
				
				// update the css settings
				$li.css({
		  		"marginLeft": (widths.column * column)
					, "marginTop": marginTop
					, "width": widths.item
		  	})
					[((nextItemColumn > column) || (currentItem == items)) ? "addClass" : "removeClass"]("mc_endcol")
					[(marginTop != 0) ? "addClass" : "removeClass"]("mc_firstrow")
					;
				// get the height of the longest column			
				if( columnHeight > maxColumnHeight ) maxColumnHeight = columnHeight;
	
				// update the previous column
				prevColumn = column;
			});
	
	/*		
	 * this would work on resize the main column
			var s = ($el === $list) ? maxColumnHeight + $divInput.offset().top + $divInput.outerHeight() : maxColumnHeight;
	*/
			
			// if the menu is too tall to fit on the screen, try adding another column
			if( ($el !== $list) && (maxColumnHeight + (settings.screenPadding*2) >= getScreenDimensions().height) ){
				return columnizeList($el, cols+1);
			}
	
			/*
			 * set the height of the list to the max column height. this fixes
			 * display problems in FF when the last column is not full.	
			 * 
			 * we also need to set the visiblity to "visible" to make sure that
			 * the element will show up	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -