微信小程序开发——wx:for循环渲染元素如何修改点击样式
来源:互联网 发布:deepskystacker mac 编辑:程序博客网 时间:2024/06/05 16:28
我们在做微信小程序的时候,往往需要做导航栏,效果是:点击导航栏的子元素,显示对应的Tab页,并且要修改点击的子元素样式用来提示用户当前位置。效果是这样:
底部导航不用说,直接在app.json中定义跳转地址和选中样式即可。关键是自定义导航,需要我们自己定义。
相信看过小程序API的人都知道导航栏怎么写:在wxml中列出每个导航栏,指定每个导航栏的url和点击样式就可以了。不清楚的童鞋可以查看API:微信小程序导航栏API
就像这样:
<!-- sample.wxml --><view class="btn-area"> <navigator url="/page/navigate/navigate?title=navigate" hover-class="navigator-hover">跳转到新页面</navigator> <navigator url="../../redirect/redirect/redirect?title=redirect" open-type="redirect" hover-class="other-navigator-hover">在当前页打开</navigator> <navigator url="/page/index/index" open-type="switchTab" hover-class="other-navigator-hover">切换 Tab</navigator></view>
但是这种做法只能算入门级,因为前台wxml视图文件没有和后台数据分离,导致导航栏不是动态加载(根据请求的JSON数据渲染导航栏)。这样的话,如果我们要修改导航栏,就只能修改wxml文件,不易维护。
好的做法是动态请求JSON数据,循环渲染出整个导航栏。如果需要修改导航栏,通过后台修改数据库中导航栏的数据即可,后台返回JSON数据给展示页面,展示页面调用this.setData({})方法即可绘制出新的导航栏。
JSON数据存储了导航栏各个子元素信息,其中goodsName对应上图的名称,goodsId用于标识每个元素,goodsClass用来定义图片路径,如下:
[{ "goodsName":"油烟机", "goodsId":"1", "goodsClass":"yanji" },{ "goodsName":"热水器", "goodsId":"2", "goodsClass":"reshuiqi" },{ "goodsName":"灶具", "goodsId":"3", "goodsClass":"zao" },{ "goodsName":"浴室柜", "goodsId":"4", "goodsClass":"yushigui" },{ "goodsName":"花洒", "goodsId":"5", "goodsClass":"huasa" },{ "goodsName":"马桶", "goodsId":"6", "goodsClass":"matong" }]
wxml页面这样写即可循环渲染每一个导航栏,其中用到了wx:for="{{navList}}"来遍历页面data数据中的navList值,而这个navList就是我们请求的JSON。wx:for内层结构中的{{item.goodsId}}对应每个导航栏子元素的goodsId属性值,其他如{{item.goodsName}}以此类推。到这儿,你的页面应该能够渲染出整个导航栏了,但是还没有点击修改样式的功能。
<view class="container clearfloat"> <view class="leftNav"> <block wx:for="{{navList}}" wx:key="goodsId"> <view style="color:{{item.goodsId==currentItemId?'#e98f36':'#000'}}" data-num="{{item.goodsId}}" class="goodsTitle" bindtap="clickTap"> <image src="/images/{{item.goodsClass}}{{item.goodsId==currentItemId?2:1}}.png"></image> <!--<image src="{{item.goodsImg}}"></image>--> <span>{{item.goodsName}}</span> </view> </block> </view></view>
如果这些你读起来困惑,别急,之前的内容了解一下就好,再不行去看看小程序API中的wx:for你就能够做到。接下来给每个循环的子元素增加点击样式才是本文重点,看完下面的操作以后,相信你能够豁然开朗。
我们可以给每个子元素添加点击事件:上面代码中的bindtap="clickTap"就是给每个元素添加点击事件,这个点击事件处理函数在js文件中定义。下面我直接贴出这个页面的完整js文件:
Page({ data: { currentItemId:"1" }, onLoad: function (options) { // 页面初始化 options为页面跳转所带来的参数 var that = this //这一句不可少,能够调用Page对象的setData({})方法 wx.request({ url: 'https://www.****(你请求的域名).com/json/navList.json', //小程序要求请求的协议必须是https,所以你的服务器后台网站必须https化,而且TLS版本在1.2 以上,过程不难,后续我会写一篇如何部署服务器以及https化和TLS升级的博文 header: { 'content-type': 'application/json' }, success: function (res) { that.setData({ navList: res.data }) } }) }, clickTap:function(e){ this.setData({ currentItemId:e.currentTarget.dataset.num }) }, onReady: function () { // 页面渲染完成 }, onShow: function () { // 页面显示 }, onHide: function () { // 页面隐藏 }, onUnload: function () { // 页面关闭 }})
可以看到clickTap函数的定义。参数e可以用来获取当前点击的子元素信息,e.currentTarget.dataset.num即获取了wxml中当前被点击元素的data-num="{{item.goodsId}}",这样就获取到了被点击元素的goodsId。然后通过this.setData({})方法设置页面data数据中的currentItemId为这个值(默认值为”1”,让第一个子元素是选中的样式)。最后我们在wxml页面中通过{{currentItemId}}获取这个值,用来修改对应子元素的样式。
wxml页面通过三目运算,判断每一个子元素的样式是否需要修改
style="color:{{item.goodsId==currentItemId?'#e98f36':'#000'}}" 这一句通过运算,判断每个子元素是否需要修改,如果它的goodsId等于被点击的元素的id(即currentItemId),就让颜色是#e98f36,否则就是黑色。
<image src="images/{{item.goodsClass}}{{item.goodsId==currentItemId?2:1}}.png"></image>这一句更绝,通过判断每个子元素是不是当前被点击的,直接修改图片的路径来显示不同的图片,达到已点击的样式效果。
这里贴出样式文件wxss,需要看效果的童鞋,复制对应的代码到对应的小程序文件中就行。
.leftNav { float: left; width: 160rpx;}.goodsList { float: right;}.goodsTitle { min-width: 120rpx; text-align: center; line-height: 40rpx; float: left; font-size: 30rpx; padding: 20rpx 20rpx; background-color: #fafafa; border-bottom: 2rpx solid lightgray; border-right: 2rpx solid lightgray;}.goodsTitle>image { width: 64rpx; height: 64rpx;}.goodsTitle>span{ display: block;}.goodsTitle>first-child{ border-top: 2rpx solid lightgray;}.goodsImgView{ margin: 0 auto 10rpx; width: 64rpx; height: 64rpx; background-repeat: no-repeat;}
总结:
实现的逻辑有点绕:首先通过JSON数据循环渲染导航栏,然后给每个导航栏一个统一的点击事件函数clickTap,通过这个函数修改当前页面的全局数据currentItemId为被点击元素的goodsId,最后在视图文件中判断当前元素的goodsId是否等于这个值来修改被点击元素的样式。
不得不这样做的根本原因:小程序不能像javascript或者jquery一样获取DOM元素或JQ对象来修改样式,而是通过setData({})方法刷新全局数据,然后回调渲染方法来重绘DOM(懂ReactJS的童鞋应该很熟悉)。全局数据是修改样式的唯一依据,它由点击事件函数修改,但是不像静态wxml每个导航元素都可以定义一个点击事件函数,通过循环遍历的元素只能是调用同一个事件函数(我们定义的clickTap)修改全局数据,所以我们需要获取每个元素的唯一标识(我们定义在JSON中的goodsId)来修改全局数据,最后每个元素根据这个全局数据来修改样式。
-over-
- 微信小程序开发——wx:for循环渲染元素如何修改点击样式
- 微信小程序wx:for循环列表渲染
- 微信小程序wx:for循环
- 微信小程序循环:Wx:for
- 微信小程序 列表渲染 wx:for
- 微信小程序开发之数据使用wx:for循环展示
- 微信小程序-wx:for 循环列表
- 微信小程序 wx:for循环和数组内部元素的增加
- 微信小程序 wx:for
- 微信小程序--wx:for
- 微信小程序循环列表添加默认事件,默认样式,点击后修改样式
- 微信小程序项目总结:for循环,绑定点击事件,二维数组列表渲染 ...
- 微信小程序入门教程--列表渲染多层嵌套循环及wx:key的使用
- 微信小程序入门教程--列表渲染多层嵌套循环及wx:key的使用
- 微信小程序wx:if条件渲染
- 微信小程序点击控件修改样式
- 微信小程序之wx:if视图层的条件渲染 —— 微信小程序教程系列(10)
- 微信小程序判断wx:if wx:for template
- ReactNative---WebStorm 环境配置------遇到的坑点
- 当case when then else end 语句遇上sum或count等统计函数
- MFC基本数据类型
- 利用maven整合SSH步骤以及源码解析可以更好的深入理解
- Linux环境下部署jasperreport出现net.sf.jasperreports.engine.util.JRFontNotFoundException
- 微信小程序开发——wx:for循环渲染元素如何修改点击样式
- 一种解决在Linux环境下发送短信中文乱码问题的方案
- cuda error:cudaregister fail
- 解决UITableView下划线左右两边多出来的空白
- select多选和checkbox复选的值在js和action中的展现形式
- 迷宫问题
- 使用java理解程序逻辑第三章
- 加密算法常用知识1
- PHP伪造referer访问地址的三种方法