微信小程序自定义键盘

0 阅读1分钟

微信小程序自定义键盘

效果图

功能

  • 如果输入.直接补0.
  • 如果是09 直接是9
  • 如果是000那就有一个0
  • 不能大于6位
  • 小数点不能大于两位仅能出现一次
  • 还有不输入是禁止支付的
  • 不能小于0.01
  • 失去焦点隐藏面板
  • 光标问题有点小bug 望大佬指点

完整代码

wxml

<view class="page_box" catchtap="hindKeyboard">
    <view class="input_view" catchtap="hindKeyboard">
        <text class="title">收款金额:</text>
        <view class="input_box" catchtap="showKeyboard">
            <text class="input_label">¥</text>
            <view class="content" wx:if="{{content.length}}">
                <view wx:for="{{content}}" wx:key="index" data-str-index="{{index + 1}}" catchtap="getStrPosition">
                    <view class="number-block">
                        {{item}}
                        <!-- 光标 -->
                        <view class="cursor cursor-insert" wx:if="{{cursorIndex === index + 1}}"></view>
                    </view>
                </view>
            </view>
            <view class="cursor" wx:if="{{!cursorIndex}}"></view>
            <text class="default-content" wx:if="{{!content.length}}">{{defaultContent}}</text>
        </view>
    </view>
    <!-- 键盘 -->
    <view class="keyboard {{keyShow&&'hind_box'}}">
        <view class="key-box">
            <view class="number-box clearfix">
                <view wx:for="{{KeyboardKeys}}" wx:key="*this" data-keys="{{item}}" class="key {{ index === 9 ? 'key-zero' : ''}}" hover-class="number-box-hover" catchtap="keyTap">
                    {{item}}
                </view>
            </view>
            <view class="btn-box">
                <!-- TODO: 需要替换成删除icon -->
                <view class="key" hover-class="number-box-hover" data-keys="<" catchtap="keyTap">
                    X
                </view>
                <view class="key pay_btn {{payMoney ? '' : 'pay-btn-display'}}" hover-class="pay-btn-hover" catchtap="handlePay">
                    付款
                </view>
            </view>
        </view>
    </view>
</view>

wxss

page {
    background: #f3f7f7;
    height: 100%;
}
 
.page_box {
    width: 100%;
    height: 100%;
    background: #f3f7f7;
    overflow: hidden;
}
 
.input_view {
    width: 700rpx;
    height: 500rpx;
    background: #fff;
    margin: 25rpx auto;
    border-radius: 10rpx;
    padding: 40rpx;
    box-sizing: border-box;
}
 
.title {
    display: block;
    line-height: 90rpx;
    font-size: 30rpx;
    color: #aaa;
}
 
.input_box {
    display: flex;
    align-items: center;
    padding: 20rpx 0;
    height: 90rpx;
    border-bottom: 1px solid #efefef;
}
 
.input_label {
    font-size: 35rpx;
    font-weight: bold;
    margin-right: 5rpx;
}
 
.content {
    display: flex;
    font-size: 80rpx;
    line-height: 90rpx;
    font-weight: 700;
}
 
.number-block {
    position: relative;
}
 
/* 光标 */
.cursor-insert {
    position: absolute;
    top: 0rpx;
    right: -1rpx;
}
 
.cursor {
    width: 2rpx;
    height: 90rpx;
    background: #666;
    border-radius: 6rpx;
    animation: twinkling 0.9s infinite;
}
 
@-webkit-keyframes twinkling {
    0% {
        background: #fff;
    }
 
    100% {
        background: #666;
    }
}
 
.default-content {
    color: #999;
    font-size: 38rpx;
    font-weight: 600;
}
 
/* 键盘 */
.keyboard {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 999;
    height: 0;
    background: #f7f7f7;
    transition: height 0.3s;
}
 
.hind_box {
    height: 456rpx;
}
 
.key-box {
    display: flex;
    padding-left: 16rpx;
    padding-bottom: 16rpx;
    padding-bottom: calc(16rpx + constant(safe-area-inset-bottom));
    padding-bottom: calc(16rpx + env(safe-area-inset-bottom));
}
 
.number-box {
    flex: 3;
}
 
.number-box .key {
    float: left;
    margin: 16rpx 16rpx 0 0;
    width: calc(100% / 3 - 16rpx);
    height: 90rpx;
    border-radius: 10rpx;
    line-height: 90rpx;
    text-align: center;
    font-size: 40rpx;
    font-weight: bold;
    background-color: #fff;
}
 
.number-box .key.key-zero {
    width: calc((100% / 3) * 2 - 16rpx);
}
 
.keyboard .number-box-hover {
    /* 临时定义颜色 */
    background-color: #e1e1e1 !important;
}
 
.btn-box {
    flex: 1;
}
 
.btn-box .key {
    margin: 16rpx 16rpx 0 0;
    height: 90rpx;
    border-radius: 10rpx;
    line-height: 90rpx;
    text-align: center;
    font-size: 40rpx;
    font-weight: bold;
    background-color: #fff;
}
 
.btn-box .pay_btn {
    height: 298rpx;
    line-height: 298rpx;
    font-weight: normal;
    background-color: #1AAD19;
    color: #fff;
    font-size: 32rpx;
}
 
.btn-box .pay_btn.pay-btn-display {
    background-color: #9ED99D !important;
}
 
.btn-box .pay_btn.pay-btn-hover {
    background-color: #179B16;
}

js

// pages/inputs/inputs.js
Page({
  data: {
    content: [], // 输入的金额
    payMoney: '', // 支付金额
    defaultContent: '请输入', // 默认内容
    KeyboardKeys: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.'],
    keyShow: true,  // 是否展示键盘
    cursorIndex: '', // 插入光标位置
  },
  //点击界面键盘消失
  hindKeyboard() {
    this.setData({ keyShow: false });
  },
  //点击输入框,键盘显示
  showKeyboard() {
    this.setData({ keyShow: true });
  },
  // 获取插入光标位置
  getStrPosition(e) {
    let { strIndex } = e.currentTarget.dataset
    this.setData({ cursorIndex: strIndex })
  },
  keyTap(e) {
    let { keys } = e.currentTarget.dataset,
      content = this.data.content.join(''),   // 转为字符串
      strLen = content.length,
      { cursorIndex } = this.data
    switch (keys) {
      case '.':
        if (content.indexOf('.') === -1) {   // 已有一个点的情况下
          content.length < 1 ? content = '0.' : content += '.'
        }
        break
      case '<':
        if (cursorIndex > 0 && cursorIndex !== strLen) {
          // 从插入光标开始删除元素
          this.data.content.splice(cursorIndex - 1, 1)
          content = this.data.content.join('')
        } else {
          content = content.substr(0, content.length - 1)
        }
        if (!strLen || cursorIndex === strLen) {    // 插入光标位置重置
          this.setData({ cursorIndex: '' })
        }
        // 删除点 组件中可以用Observer监听删除点和删除0的情况
        if (content[0] === '0' && content[1] !== '.') {
          content = content.substr(1, content.length - 1)
        }
        if (content[0] === '.') {
          content = '0' + content
        }
        break
      default:
        let spotIndex = content.indexOf('.')          //小数点的位置
        if (content[0] === '0' && content[1] !== '.') {
          content = content.substr(1, content.length - 1)
        }
        if ((spotIndex === -1 || strLen - spotIndex !== 3)) {  //小数点后只保留两位
          content += keys
        }
        break
 
    }
 
    if (content <= 100000) {
      this.setData(
        {
          content: content.split(''),// 转为数组
          payMoney: content // 支付金额
        }
      )
    } else {
      wx.showToast({
        title: '支付金额不能大于100000',
        icon: 'none',
        duration: 1500,
      })
    }
  },
  handlePay() {
    const { payMoney } = this.data
    if (payMoney === '') return
    if (payMoney < '0.01') {
      wx.showToast({
        title: '支付金额不能小于0.01',
        icon: 'none',
        duration: 1500,
      })
      return
    }
    console.log(Number(payMoney), '付款')
  }
 
 
})