微信小程序开发-实现自定义多功能复制栏

        公司有个需求,要求在能选中文字的前提下,对弹出的功能栏进行自定义,要求多添加几个功能,原生的实现方式可以通过<text>组件的user-select实现,这种方式无法对弹出的弹窗进行自定义,因此只能手写。,这篇文章主要记录我实现的思路。

        我的思路是将单独的文字分割成数组,同时作为元素属性,监听拖动与长按事件,当时间触发时,可以通过dataset属性获取当前数组的下标,从而获取对应的文字信息以及当前选中了哪些文字,后来发现,拖动事件的元素属性并不能够随着拖动目标的变化而变化,他的dataset值时不变的,例如,从元素1开始拖动,就只能获取元素1的dataset值,无论如何拖动,这个值始终固定,不会变化,我无法获取元素的dataset值。

        计算当前拖动距离与元素高度和宽度

        在发现通过动态监听touchmove事件从而获取对应元素的dataset值不行后,只能通过计算当前移动事件的开始距离与结束距离,获取每个元素距离顶部与左侧的距离,从而判断哪些元素处于移动的范围内,为这些元素添加选中样式并将选中的元素信息保存。

        处理完选中的问题,还需要考虑二次选中。在已经选中的基础上,需要对各种拖动范围进行处理,包括:

开始光标或结束光标向左侧或右侧拖动:修改startindex或endIndex为当前拖动元素index(通过dataset绑定)

再次选中的元素处于被选中的元素范围之内:修改endIndex为当前选中元素index。

这里只说明最关键的选中文字实现部分,还有分割字符数组、为每个元素添加对应的选中样式、长按事件处理、拖动事件结束处理都是比较简单的部分就不过多赘述,下面附上核心的代码

 //节流
moveHandle: throttle(function (e) {
      let _this = this;
      if (_this.data.activeObj.wordIndex.length === 0) return;
      this.setData({
        isShowNotice: false
      })
      const {
        pageX,
        pageY
      } = e[0].touches[0];
      const query = _this.createSelectorQuery();
      query.selectAll('.normal').boundingClientRect(res => {
        let moveNode = res.find(item => pageY >= item.top && pageY <= item.top + item.height && pageX >= item.left && pageX <= item.left + item.width);
        console.log(moveNode);
        if (!moveNode) {
          const allLimitNodes = res.filter(item => pageY > item.top + item.height && pageX > item.left + item.width);
          if (allLimitNodes.length > 0) {
            moveNode = allLimitNodes[allLimitNodes.length - 1]
          }
        }
        if (moveNode) {
          const {
            index
          } = moveNode.dataset;
          const activeObj = _this.data.activeObj;
          if (index <= activeObj.startIndex) {
            activeObj.startIndex = index;
            activeObj.wordIndex = [..._this.generateArray(activeObj.startIndex, activeObj.endIndex)];
          } else if (index > activeObj.startIndex && index < activeObj.endIndex) {
            activeObj.endIndex = index;
            activeObj.wordIndex = [..._this.generateArray(activeObj.startIndex, activeObj.endIndex)];
          } else {    
            activeObj.endIndex = index;
            activeObj.wordIndex = [..._this.generateArray(activeObj.startIndex, activeObj.endIndex)];
          };
          let arr = JSON.parse(JSON.stringify(_this.data.wordArr));
          arr.forEach(item => {
            item.isActive = false;
            if (activeObj.wordIndex.includes(item.index)) {
              item.isActive = true;
            }
          })
          _this.setData({
            wordArr: arr,
            activeObj: activeObj
          })
        }
      }).exec();
    }, 100),

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值