11 Star 40 Fork 15

黄秀杰 / WXDropDownMenu

Create your Gitee Account
Explore and code with more than 6 million developers,Free private repositories !:)
Sign up
This repository doesn't specify license. Without author's permission, this code is only for learning and cannot be used for other purposes.
Clone or download
README.md 9.04 KB
Copy Edit Web IDE Raw Blame History
秀杰 authored 2016-10-19 09:41 . gif thumb

先来看下效果图:

效果图

思路与步骤:

布局方面,整体使用dl来写,二级包在dd中,用ul li来写;交互方面,点击某一级菜单,关闭兄弟子菜单,点击某子菜单关闭所有菜单。

1.使用dt做出第一级菜单

2.使用dd嵌套第二级菜单,初始隐藏、position为absolute,使用z-index浮出页面层

/*总菜单容器*/
.menu {
 	display: block;
	height: 38px;
}

/*一级菜单*/
.menu dt {
	font-size: 15px;
	float: left;
	/*hack*/
	width: 33%;
	height: 38px;
	border-right: 1px solid #d2d2d2;
	border-bottom: 1px solid #d2d2d2;
	text-align: center;
	background-color: #f4f4f4;
	color: #5a5a5a;
	line-height: 38px;
}

/*二级菜单外部容器样式*/
.menu dd{
	position: absolute;
	width: 100%;
	/*hack*/
	top:39px;
	left:0;
	z-index:999;
}

/*二级菜单普通样式*/
.menu li{
	font-size: 14px;
	line-height: 34px;
	color: #575757;
	height: 34px;
	display: block;
	padding-left: 8px;
	background-color: #fff;
	border-bottom: 1px solid #dbdbdb;
}

查看效果,接下来实现点击事件。

如图

静态菜单

3.dt绑定点击事件tapMainMenu,flag控制显隐toggle,提供2个class,hidden与show,来控制显隐。注:dt也是可以bindTap的,不单是view。

/* 显示与隐藏 */
.show {
	display: block;
}

.hidden {
	display: none;
}

4.关闭所有一级菜单,每个一级菜单都有一个index标识,由tapMainMenu事件传递过去,与数组subMenuDisplay一一对应,当前元素subMenuDisplay[index]视原来状态决定是显示或隐藏。

核心代码:

<dl class="menu">
	<dt data-index="0" bindtap="tapMainMenu">价格</dt>
	<dd class="{{subMenuDisplay[0]}}">
		<ul><li>sub1</li><li>sub2</li></ul>
	</dd>
</dl>
// 使用function初始化array,相比var initSubMenuDisplay = [] 既避免的引用复制的,同时方式更灵活,将来可以是多种方式实现,个数也不定的
function initSubMenuDisplay() {
	return ['hidden', 'hidden', 'hidden'];
}

Page({
	data:{
		subMenuDisplay:initSubMenuDisplay()
	},
	tapMainMenu: function(e) {
//		获取当前显示的一级菜单标识
		var index = parseInt(e.currentTarget.dataset.index);
		// 生成数组,全为hidden的,只对当前的进行显示
		var newSubMenuDisplay = initSubMenuDisplay();
//		如果目前是显示则隐藏,反之亦反之。同时要隐藏其他的菜单
		if(this.data.subMenuDisplay[index] == 'hidden') {
			newSubMenuDisplay[index] = 'show';
		} else {
			newSubMenuDisplay[index] = 'hidden';
		}
		// 设置为新的数组
		this.setData({
			subMenuDisplay: newSubMenuDisplay
		});
	}
});

5.选中二级菜单当前项,但给个系统icon及改变背景色,文本加粗,同样改变一级菜单标题,demo中给出一个弹窗

声明tapSubMenu方法,监听二级点击事件

	tapSubMenu: function(e) {
		//		获取当前显示的一级菜单标识
		var index = parseInt(e.currentTarget.dataset.index);
		console.log(index);
		// 隐藏所有一级菜单
		this.setData({
			subMenuDisplay: initSubMenuDisplay()
		});
	}

加highlight效果

/*二级菜单高亮样式*/
.menu li.highlight{
	background-color: #f4f4f4;
}

与一级菜单不同,使用二维数组的方式实现点击高亮,这样才能定位到是某一级的某二级菜单,再决定显示隐藏。 布局文件改成:

	<dd class="{{subMenuDisplay[0]}}">
		<ul>
			<li class="{{subMenuHighLight[0][0]}}" data-index="0-0" bindtap="tapSubMenu">100以内</li>
			<li class="{{subMenuHighLight[0][1]}}" data-index="0-1" bindtap="tapSubMenu">100-500</li>
			<li class="{{subMenuHighLight[0][2]}}" data-index="0-2" bindtap="tapSubMenu">500-1000</li>
			<li class="{{subMenuHighLight[0][3]}}" data-index="0-3" bindtap="tapSubMenu">1000-3000</li>
			<li class="{{subMenuHighLight[0][4]}}" data-index="0-4" bindtap="tapSubMenu">3000以上</li>
		</ul>
	</dd>

效果如图

子菜单高亮

相应的js代码要写成:

//声明初始化高亮状态数组
function initSubMenuHighLight() {
	return [
		['','','','',''],
		['',''],
		['','','']
	];
}

点击事件

tapSubMenu: function(e) {
		// 隐藏所有一级菜单
		this.setData({
			subMenuDisplay: initSubMenuDisplay()
		});
		// 处理二级菜单,首先获取当前显示的二级菜单标识
		var indexArray = e.currentTarget.dataset.index.split('-');
		console.log("indexArray : " + indexArray);
		var newSubMenuHighLight = initSubMenuHighLight();
		// 与一级菜单不同,这里不需要判断当前状态,只需要点击就给class赋予highlight即可
		newSubMenuHighLight[indexArray[0]][indexArray[1]] = 'highlight';
		console.log(newSubMenuHighLight);
		// 设置为新的数组
		this.setData({
			subMenuHighLight: newSubMenuHighLight
		});
	}

这样就实现了高亮与取消高亮。但还没完,与一级菜单不同,这里与兄弟子菜单是非互斥的,也就是说点击了本菜单,是不能一刀切掉兄弟菜单的高亮状态的。于是我们改进js代码。

声明方式,改用变量形式,方便存储。

//定义初始化数据,用于运行时保存
var initSubMenuHighLight = [
		['','','','',''],
		['',''],
		['','','']
	];

点击事件

	tapSubMenu: function(e) {
		// 隐藏所有一级菜单
		this.setData({
			subMenuDisplay: initSubMenuDisplay()
		});
		// 处理二级菜单,首先获取当前显示的二级菜单标识
		var indexArray = e.currentTarget.dataset.index.split('-');
		// 初始化状态
		// var newSubMenuHighLight = initSubMenuHighLight;
		for (var i = 0; i < initSubMenuHighLight.length; i++) {
			// 如果点中的是一级菜单,则先清空状态,即非高亮模式,然后再高亮点中的二级菜单;如果不是当前菜单,而不理会。经过这样处理就能保留其他菜单的高亮状态
			if (indexArray[0] == i) {
				for (var j = 0; j < initSubMenuHighLight[i].length; j++) {
					// 实现清空
					initSubMenuHighLight[i][j] = '';
				}
				// 将当前菜单的二级菜单设置回去
			}
		}

		// 与一级菜单不同,这里不需要判断当前状态,只需要点击就给class赋予highlight即可
		initSubMenuHighLight[indexArray[0]][indexArray[1]] = 'highlight';
		// 设置为新的数组
		this.setData({
			subMenuHighLight: initSubMenuHighLight
		});
	}

有待完善功能点:

1.显示与隐藏带动画下拉

2.抽象化,使用回调函数,将1监听每个二级菜单的点击

3.数据源与显示应当是分离的,一级与二级菜单的key value应该是独立在外,系统只认index,然后对相应点击作处理,跳转页面,筛选结果等

[2016-10-18]

官方文档:https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-animation.html

图

改为动画版,需要要满足平移动画与背景遮罩。思路如下:

1.二级菜单初始隐藏且位置位于手机屏幕之外

2.当点击一级菜单时,二级菜单平移向下,直到二级菜单上边缘与一级菜单下边缘平齐。使用linear动画

3.点击自身或其他一级菜单,做逆操作

4.背景遮罩,使用ease-in/ease-out动画

步骤1 改造样式表,top值

步骤2 声明动画

核心代码:

	animation: function(index) {
		// 定义一个动画
	    var animation = wx.createAnimation({
	    	duration: 400,
	        timingFunction: 'linear',
	    })
	    // 是显示还是隐藏
	    var flag = this.data.subMenuDisplay[index] == 'show' ? 1 : -1;
	    // flag = 1;
	    console.log(flag)
	    // 使之Y轴平移
	    animation.translateY(flag * (initSubMenuHighLight[index].length * 34) + 8).step();
	    // 导出到数据,绑定给view属性
	    this.setData({
	    	animationData:animation.export()
	    });
	}

完成动画后,需调用一次step(),不论是一组还是多组都需要调。

步骤3 声明data数组并与wxml绑定

		animationData: {}

wxml中

	<dd animation="{{animationData}}">

z-index问题,会挡住一级菜单,设置为-999,可以置于一级菜单之下

使用bottom: 0;初始在一级菜单底边缘平齐。

dl 设置为position: relative; 与二级菜单 position: absolute 对应。

步骤4 点击一级菜单调用动画

		// 设置动画
		this.animation(index);

步骤5 点击二级菜单调用动画

		// 设置动画
		this.animation(indexArray[0]);

步骤6 display属性要改为visibility

/* 显示与隐藏 */
.show {
	/*display: block;*/
	visibility: visible;
}

.hidden {
	/*display: none;*/
	visibility:hidden;
}

保留占位,宽度高度,不然点击没了动画效果。

源码下载:关注下方的公众号->回复数字1006

对小程序开发有趣的朋友关注公众号: huangxiujie85,QQ群: 575136499,微信: small_application,陆续还将推出更多作品。

公众号

Comment ( 0 )

Sign in for post a comment

wechat
1
https://gitee.com/dotton/WXDropDownMenu.git
git@gitee.com:dotton/WXDropDownMenu.git
dotton
WXDropDownMenu
WXDropDownMenu
master

Search