小程序自定义模拟键盘效果

这个是找工作的时候一个boss给的考察题,后续是题做出来了那个boss不理人,一点没有礼貌

最后效果演示,已经算是比较流畅的了。不知道ios端会不会有问题,自己手机是安卓的。不完美的就是光标没有拖拽效果

小程序模拟键盘效果演示

首先分析一下效果图

  • 样式排版比较简单,flex布局
  • 键盘部分只有删除和清空是固定值,数值应该随机生成

html代码

<view class="content">
		<!-- <view class="imput_box">
			<input type="number" v-model="numVal" @focus="inputFocus" @blur="inputBlur" @input="handlerInput">
		</view> -->

		<view class="imput_box" @click="inputFocus">

			<view v-for="(item,index) in content" :key="index" :data-str-index="index+1" @click="getStrPosition">
				<view class="number-block">
					{{item}}
					<view class="cursor cursor-insert" v-if="cursorIndex === index + 1"></view>
				</view>
			</view>
			<view class="cursor" v-if="!cursorIndex"></view>
		</view>
		
		<view class="keyboard" :class="{'show_active':boardShow}">
			<view class="key_box">
				<p class="keys" v-for="item in originKey" :key="item" @click="handlerClick(item)">
					{{item}}
				</p>

				<p class="keys bg_color" @click="handlerDel">
					<u-icon name="arrow-leftward" color="#fff" size="28"></u-icon>
				</p>
				<p class="keys bg_color" @click="handlerClear">C</p>
			</view>
		</view>

	</view>

 css代码

<style lang="scss">
	::v-deep .u-icon--right {
		justify-content: center;
		height: 90rpx;
	}

	.content {
		width: 100%;
		height: 100%;
		display: flex;
		flex-direction: column;
		align-items: center;
	}

	.imput_box {
		width: 90%;
		height: 90rpx;
		line-height: 90rpx;
		display: flex;
		border-radius: 5px;
		border: 2px solid #aeccef;
	}

	.number-block {
		position: relative;
	}

	/* 光标 */
	.cursor-insert {
		position: absolute;
		top: 0;
		right: -1rpx;
	}

	.cursor {
		width: 2rpx;
		height: 90rpx;
		background: #666;
		border-radius: 6rpx;
		animation: twinkling 0.9s infinite;
	}

	@keyframes twinkling {
		0% {
			background: #fff;
		}

		100% {
			background: #666;
		}
	}


	// * 键盘 */
	.keyboard {
		max-height: 0;
		width: 90%;
		background: #f8f6f9;
		position: fixed;
		bottom: 0;
		border: 2px solid #eae8eb;
		border-radius: 5px;
		transition: height 0.3s;
	}

	.show_active {
		max-height: 500px;
	}

	.key_box {
		display: flex;
		justify-content: flex-start;
		align-items: center;
		flex-wrap: wrap;
	}

	.keys {
		box-sizing: border-box;
		flex: 1;
		height: 90rpx;
		line-height: 90rpx;
		text-align: center;
		margin: 10px;
		width: calc((100% - 60px) / 3);
		min-width: calc((100% - 60px) / 3);
		max-width: calc((100% - 60px) / 3);
		background: #77adf7;
		border-radius: 5px;
		color: #fff;
		font-size: 14px;
	}

	.bg_color {
		background: #d32d3e;

	}
</style>

其实这里的假光标是后来才写的。刚开始用input标签,基本的输入、删除、清空都是可以做到的,但是移动光标后再做这些操作有些问题。因为我拿不到光标的位置,上网搜的方法也没用,不知道是哪里除了问题。后来不想找了就直接写假光标

模拟input框的话就需要多一些操作

  • 模拟光标元素自定义属性下标必须要+1,不然判断的时候会有问题
  • 光标处添加、删除光标位置也要自增自减
  • 删除到第一个元素后光标自动跳转到最后

js代码

<script>
	export default {
		data() {
			return {
				// originKey: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0],
				originKey: [],
				boardShow: false,
				// numVal: "",
				content: [],
				cursorIndex: '',
			}
		},
		watch: {
			boardShow(val) {
				if (val) {
					this.randomArr()
				}
			},

		},
		onLoad() {
			// this.randomArr()
		},
		methods: {
			inputFocus(e) {
				this.boardShow = true
			},
			//随机数组
			randomArr() {
				const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
				let i = arr.length;
				while (i) {
					let j = Math.floor(Math.random() * i--);
					[arr[j], arr[i]] = [arr[i], arr[j]];
				}
				this.originKey = JSON.parse(JSON.stringify(arr))
				console.log(this.originKey, 333)

			},
			// 添加事件
			handlerClick(val) {
				if (val == 0 && this.content.length == 0) {
					return
				} else {
					if (this.cursorIndex > 0 && this.cursorIndex !== this.content.length) {
						this.content.splice(this.cursorIndex, 0, val)
						this.cursorIndex++
					} else {
						this.content.push(val)
					}
				}
			},
			//删除事件
			handlerDel() {
				console.log(this.cursorIndex)
				if (this.cursorIndex > 0 && this.cursorIndex !== this.content.length) {
					this.content.splice(this.cursorIndex-1, 1)
					this.cursorIndex--
				} else {
					this.content.pop()
				}
			},
			//清空
			handlerClear() {
				// this.numVal = ''
				this.content = []
			},
			// 获取插入光标位置
			getStrPosition(e) {
				let {
					strIndex
				} = e.currentTarget.dataset
				this.cursorIndex = strIndex
				console.log(this.cursorIndex,11)
			},
		}
	}
</script>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值