首页 > 代码库 > 仿亚马逊左侧导航(精心设计的人机交互)

仿亚马逊左侧导航(精心设计的人机交互)

Demo:http://7li.github.io/jquery/jQuery-menu/index.html

Source:https://github.com/7LI/7li.github.io/tree/master/jquery/jQuery-menu

技术分享


如图:用户在左侧导航栏上有可能进行两种操作:

  1. 切换导航标签
  2. 把鼠标从标签移入右侧内容

 判断用户是在进行何种操作的依据是用户的鼠标轨迹,如果鼠标经过绿色区域,则很有可能进行的是2的操作,否则则肯定是进行1的操作。


所以我们要做的处理是:在用户鼠标经过绿色区域的时候,此时鼠标途经的导航标签(即绿色区域内的导航标签),不立即跳转,而是延迟一段时间再跳转,比如300ms。

在300ms后,如果鼠标离开了绿色区域,则证明用户是想进入右侧的内容,此时我们不进行标签跳转。


对具体实现感兴趣的童鞋可以看看源代码,也欢迎批评指正


<html>
	<head>
		<style type="text/css">
			.menu-nav, .menu-panel{float: left;}
			.menu-nav-item{width: 150px;height: 30px;line-height: 30px;text-align: center;background: #eee;margin-bottom: 2px;cursor: default;}
			.menu-nav-item-hover{background: #bbb;}
			.menu-nav-item-on{background: #999;}
			.menu-panel{position: relative;width: 500px;padding-left: 20px;height: 500px;overflow: hidden;}
			.menu-panel-item{position: absolute;background: white;display: none;}
			.menu-panel-item img{height: 317px;}
			.menu-panel-item-on{display: block;}
		</style>
	</head>
	<body>
		<div class="menu">
			<div class="menu-nav">
				<div class="menu-nav-item">menu-1</div>
				<div class="menu-nav-item">menu-2</div>
				<div class="menu-nav-item">menu-3</div>
				<div class="menu-nav-item">menu-4</div>
				<div class="menu-nav-item">menu-5</div>
				<div class="menu-nav-item">menu-6</div>
				<div class="menu-nav-item">menu-7</div>
				<div class="menu-nav-item">menu-8</div>
				<div class="menu-nav-item">menu-9</div>
				<div class="menu-nav-item">menu-10</div>
			</div>
			<div class="menu-panel">
				<div class="menu-panel-item menu-panel-item-on"><img src=http://www.mamicode.com/"img/1.jpg" />
>

/**
 * jQuery Menu plugin
 * 
 * @author lyz
 * @email 702368372#qq.com
 * @version 1.0
 * 
 * Licensed under the MIT License.
 */
(function ($, window, undefined) {
	var menu, panels, target, className, index, navOn, panelOn, me, i, reg;

	function Menu (config) {
		me = this;
		if (me == $) {
			return new Menu(config);
		}

		var DEFAULT = {
			menu: 'menu',
			nav: 'menu-nav',
			navs: 'menu-nav-item',
			panels: 'menu-panel-item',
			navHover: 'menu-nav-item-hover',
			navOn: 'menu-nav-item-on',
			panelOn: 'menu-panel-item-on',
			delay: 300,
			plugins: []
		}
		me.config = $.extend(DEFAULT, config, {});

		me.menu = $('.' + me.config.menu);
		me.nav = $('.' + me.config.nav);
		me.navs = $('.' + me.config.navs);
		me.panels = $('.' + me.config.panels);

		me.menu.mouseover (function (e) {
			target = e.target;
			className = target.className;
			target = $(target);
			index = target.index();
			reg = new RegExp(me.config.navs);

			if (reg.test(className)) {
				me.navSwitchTo(index);
				me.panelSwitchTo(index);
			}
		})

		for (i = 0; i < me.config.plugins.length; i++) {
			me.config.plugins[i].init(me);
		}
	}

	Menu.prototype.navAttemptSwitchTo = function (index) {
		me = this;
		me.navs.removeClass(me.config.navHover)
		       .eq(index).addClass(me.config.navHover);
	}

	Menu.prototype.navSwitchTo = function (index) {
		me = this;
		me.navs.removeClass(me.config.navOn + ' ' + me.config.navHover)
		       .eq(index).addClass(me.config.navOn);
	}

	Menu.prototype.panelSwitchTo = function (index) {
		me = this;
		clearTimeout(me.panelTimer);

		me.panels.removeClass(me.config.panelOn)
		         .eq(index).addClass(me.config.panelOn);
		me.navSwitchTo(index);
	};

	Menu.prototype.panelAttemptSwitchTo = function (index) {
		me = this;
		clearTimeout(me.panelTimer);

		me.panelTimer = setTimeout( function () {
			me.panelSwitchTo(index);
		}, me.config.delay)
		me.navAttemptSwitchTo(index);
	};
	
	$.Menu = Menu;

} (jQuery, this, undefined))
/**
 * Plugin for jQuery-menu which acts similar to amazon's leftside nav
 * 
 * @author lyz
 * @email 702368372#qq.com
 * @version 1.0
 * 
 * Licensed under the MIT License.
 */
(function ($, window, undefined) {
	var start, end, slope, liveSlope, target, className, index, reg, ret, paths = [];

	function MenuAmazing () {
		me = this;
		if (me == $) {
			return new MenuAmazing();
		}
	}

	/**
	 * Init plugin
	 * @param  {object} host 
	 */
	MenuAmazing.prototype.init = function (host) {
		slope = host.nav.outerHeight() / host.nav.outerWidth();
		host.menu.unbind('mouseover'); 

		host.menu.mouseover( function (e) {
			target = e.target;
			className = target.className;
			target = $(target);
			index = target.index();
			reg = new RegExp(host.config.navs);
			if (reg.test(className)) {
				if (isSwitch()) {
					host.panelSwitchTo(index);
				} else {
					host.panelAttemptSwitchTo(index);
				}
			}
		});

		host.nav.mouseleave( function () {
			clearTimeout(host.panelTimer);
			host.navs.removeClass(host.config.navHover);
		})
	}

	/**
	 * Is swiching immediately or lazily
	 * @return {Boolean} yes or not
	 */
	function isSwitch () {
		start = paths[0] || {x: 0, y: 0};
		end = paths[paths.length-1] || {x: 0, y: 0};
		liveSlope = Math.abs(end.y - start.y) / Math.abs(end.x - start.x);
		inTriangle = end.x > start.x; // In the first quadrant or the forth quadrant

		if (!inTriangle && liveSlope > slope) {
			ret = true;
		} else {
			ret = false;
		}
		return ret;
	}

	/**
	 * Mark mouse path
	 */
	$(document).mousemove (function (e) {
		if (paths.length == 3) {
			paths.shift();
		}
		paths.push({x: e.pageX, y: e.pageY});
	})

	$.MenuAmazing = MenuAmazing;

} (jQuery, this, undefined))




仿亚马逊左侧导航(精心设计的人机交互)