微信小程序实现单击双击和长按forEachclearTimeoutsetTimeoutsplitsetClipboardDatagetClipboardDatashowToast

Posted 牧碼人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信小程序实现单击双击和长按forEachclearTimeoutsetTimeoutsplitsetClipboardDatagetClipboardDatashowToast相关的知识,希望对你有一定的参考价值。

文章目录


1、前言

本文章只针对JavaScript进行详解,不对HTML和css做解释,望悉知。


2、html部分

<view>
  <!-- 表格 -->
  <view class="font_size_32 color_000 position_fixed left_50_ top_50_ transform_translate_50_50">
    <view class="border_777 text_align_center">
      <!-- 表头 -->
      <view>
        <view class="grid_c5_80_150_170_160_170 border_b_777 height_80 line_height_80 font_weight_700">
          <view>颜色</view>
          <view class="border_l_777">十六进制</view>
          <view class="border_l_777">RGB</view>
          <view class="border_l_777">波长(nm)</view>
          <view class="border_l_777">频率(MHz)</view>
        </view>
      </view>

      <!-- 表格内容 -->
      <view>
        <view class="grid_c5_80_150_170_160_170 height_80 line_height_80 index!==0?'border_t_777':'' item.isShow?'color_olive':''" wx:for="layout" wx:key="id" data-val="item" bindtap="bindtapClick" bindlongtap="longTap">
          <view class="dis_r_c">
            <view class="width_70_ height_70 line_height_70" style="background-color: \\#item.hexadecimal;">item.colorName</view>
          </view>
          <view class="border_l_777">item.hexadecimal</view>
          <view class="border_l_777">item.rgb</view>
          <view class="border_l_777">item.wavelength</view>
          <view class="border_l_777">item.frequency</view>
        </view>
      </view>
    </view>
  </view>

  <!-- 信息全揽面板 -->
  <view wx:if="isPanel">
    <view class="position_fixed left_0 top_0 z_index_7 back_100_100_100_05 width_100_100 height_100_ border_b_777" catchtap="offPanel"></view>

    <view class="position_fixed left_50_ top_50_ z_index_9 width_90 transform_translate_50_50 back_EEE padding_30 radius_10">
      <view class="text_align_left">
        <text class="font_size_50 font_weight_700">信息全览</text>
        <text class="margin_t_10 color_red1 font_size_26">长按文字选择并复制,可选择多行</text>
      </view>

      <view>
        <view class="margin_t_10 font_size_36" wx:for="information" wx:key="id">
          <text class="inline_block text_align_right font_weight_700 width_170 margin_r_10">item.title:</text>
          <text class="margin_l_10" user-select>item.val</text>
        </view>
      </view>
    </view>
  </view>

  <!-- 复制/全揽操作面板 -->
  <view wx:if="isCopyAllInclusive">
    <view class="width_100_100 height_100_ position_fixed left_0 top_0 z_index_7 back_transparent" catchtap="offCopyAllInclusive"></view>

    <view class="position_fixed left_50_ top_50_ transform_translate_50_50 z_index_9">
      <view class="dis_r_sb padding_20 radius_10 color_EEE back_555 font_size_36">
        <view class="margin_r_36 padding_10" catchtap="copyCurrentRow">复制</view>
        <view class="margin_l_36 padding_10" catchtap="onAllInclusive">全揽</view>
      </view>
    </view>
  </view>
</view>

☺☺☺☺☺

css部分其实就是类名对应的值,例如:margin_r_36表示的就是margin-right: 36rpx;以此类推便可知道对应的css值。


3、javascript部分

Page(
	/**
	* 页面的初始数据
	*/
	data: 
		layout: [],
		// 触摸开始时间
		touchStartTime: 0,
		// 触摸结束时间
		touchEndTime: 0,
		// 最后一次单击事件点击发生时间
		lastTapTime: 0,
		// 单击事件点击后要触发的函数
		lastTapTimeoutFunc: null,
		// 控制信息面板的显示与隐藏
		isPanel: false,
		// 信息存储
		information: [],
		// 控制复制/全揽面板按钮的显示与隐藏
		isCopyAllInclusive: false
	,
	
	// 关闭复制/全揽面板
	offCopyAllInclusive() 
		this.setData(
			isCopyAllInclusive: false
		);
	,
	
	// 打开全揽面板
	onAllInclusive() 
		this.setData(
			isPanel: true,
			isCopyAllInclusive: false
		);
	,
	
	// 复制当前行
	copyCurrentRow() 
		let that = this,
			list = that.data.information,
			len = list.length - 1,
			content = '';
		
		list.forEach((item, i) => content += item.val + (i !== len ? '\\n' : ''));
		
		wx.setClipboardData(
			data: content,
			success() 
				wx.getClipboardData(
					success() 
						wx.showToast(
							title: '复制成功',
							icon: 'none',
							mask: true,
							duration: 1700,
							success() 
								that.setData(
									information: [],
									isCopyAllInclusive: false
								);
							
						);
					
				);
			
		);
	,
	
	// 长按打开复制/全揽面板按钮
	longTap(
		currentTarget: 
			dataset: 
				val
			
		
	) 
		this.setData(
			information: val.list,
			isCopyAllInclusive: true,
		);
	,
	
	// 关闭信息面板
	offPanel() 
		this.setData(
			isPanel: false,
			information: []
		);
	,
	
	// 单击/双击
	bindtapClick(
		currentTarget: 
			dataset: 
				val
			
		,
		timeStamp
	) 
		let that = this,
			thatData = that.data,
			layoutValue = thatData.layout,
			// 当前点击的时间
			currentTime = timeStamp,
			lastTapTime = thatData.lastTapTime;
		
		// 更新最后一次点击时间
		thatData.lastTapTime = currentTime;
		
		// 控制点击事件在350ms内触发,
		// 加这层判断是为了防止长按时会触发点击事件
		if (thatData.touchEndTime - thatData.touchStartTime >= 350) return false;
		
		// 如果两次点击时间在300毫秒内,则认为是双击事件
		if (currentTime - lastTapTime < 290) 
			// 成功触发双击事件时,取消单击事件的执行
			clearTimeout(thatData.lastTapTimeoutFunc);
			that.setData(
				isPanel: true,
				information: val.list
			);
		 else 
			// 当长按打开复制/全揽面板时禁止触发单击事件
			if (thatData.isCopyAllInclusive) return false;
			
			// 单击事件延时300毫秒执行,这和最初的浏览器的点击300ms延时有点像。
			thatData.lastTapTimeoutFunc = setTimeout(function () 
				layoutValue = layoutValue.map(item => 
					item.isShow = item.id === val.id ? !item.isShow : false;
					return item;
				);
			
				that.setData(
					layout: layoutValue
				);
			, 260);
		
	,
	
	// 初始化
	init() 
		// nm 波长
		// MHz 频率
		let layoutValueOrigin = ['红_FF0000_255,0,0_625~740_480~405', '橙_FF7D00_255,125,0_590~625_510~480', '黄_FFFF00_255,255,0_565~570_530~510', '绿_00FF00_0,255,0_500~565_600~530', '青_00FFFF_0,255,255_485~500_620~600', '蓝_0000FF_0,0,255_440~485_680~620', '紫_FF00FF_255,0,255_380~440_790~680'],
			title = ['颜色', '十六进制', 'RGB', '波长', '频率'],
			layoutValue = [];
		
		for (let i = 0; i < layoutValueOrigin.length; i++) 
			let val = layoutValueOrigin[i],
				arr = val.split('_'),
				list = title.map((item, j) => 
					return 
						id: `$i+1_$j+1`,
						title: item,
						val: arr[j]
					;
				);
			
			layoutValue.push(
				id: `$i+1_$arr[1]`,
				// 颜色中文名称
				colorName: arr[0],
				// 十六进制
				hexadecimal: arr[1],
				// RGB
				rgb: arr[2],
				// 波长
				wavelength: arr[3],
				// 评率
				frequency: arr[4],
				// 存储当前行数据值
				list,
				// 判断当前行是否高亮
				isShow: false
			);
		
		
		this.setData(
			layout: layoutValue
		);
	,
	
	/* 生命周期函数--监听页面加载 */
	onLoad(options) 
		// 页面加载执行初始化函数
		this.init();
	,
	
	/* 生命周期函数--监听页面初次渲染完成 */
	onReady()  ,
	
	/* 生命周期函数--监听页面显示 */
	onShow()  ,
	
	/* 生命周期函数--监听页面隐藏 */
	onHide()  ,
	
	/* 生命周期函数--监听页面卸载 */
	onUnload()  ,
	
	/* 页面相关事件处理函数--监听用户下拉动作 */
	onPullDownRefresh()  ,
	
	/* 页面上拉触底事件的处理函数 */
	onReachBottom()  ,
	
	/* 用户点击右上角分享 */
	onShareAppMessage()  
)

☺☺☺☺☺☺☺

文章涉及内容较多,如果单纯使用文字描述恐怕无法完全表达代码的含义,所以只是简单的介绍一下函数的基本功能,更详细的解答请关注博主的哔哩哔哩,后期如果上传讲解视频了会在此文章通知各位伙伴,敬请期待!UID:474290436,昵称:蒙学长682517

☺☺☺☺☺☺☺

函数介绍,本页面共有七个函数
第一个函数是页面基本构造数据的生成
第二个函数实现单击与双击功能,单击实现当前行高亮,双击打开信息全揽面板
第三个函数主要是关闭信息全揽面板
第四个函数实现长按打开复制/全揽按钮面板
第五个函数实现复制按钮复制当前行的功能,同时关掉复制/全揽按钮面板
第六个函数通过全揽按钮打开信息全揽面板,同时关掉复制/全揽按钮面板
第七个函数关闭复制/全揽面板

☺☺☺☺☺☺☺

特别提醒
信息全揽面板可通过点击遮罩层关闭面板
复制/全揽按钮面板的“遮罩层”虽然设置背景为透明,但也可点击关闭此面板;隐晦的实现了点击除面板以外实现关闭面板的功能概念


4、演示

以上是关于微信小程序实现单击双击和长按forEachclearTimeoutsetTimeoutsplitsetClipboardDatagetClipboardDatashowToast的主要内容,如果未能解决你的问题,请参考以下文章

8051识别按键单击双击和长按

微信小程序-双击长按longtap事件与tap事件冲突的解决办法

双击和单击事件冲突解决方法

jquery分别绑定双击和单击

双击和单击事件冲突解决方法

双击和单击事件冲突解决方法