码云 Gitee IDE 全新上线——支持 Git 管理的轻量在线编码环境
0 Watch 11 Star 27 Fork 14

黄秀杰 / WXDropDownMenu微信

加入码云
与超过 300 万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
小程序下拉菜单,可用于筛选
huangxiujie 最后提交于 gif thumb
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README.md 9.04 KB

先来看下效果图:

效果图

思路与步骤:

布局方面,整体使用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,陆续还将推出更多作品。

公众号

项目点评 ( 3 )

你可以在登录后,发表评论

搜索帮助