vue项目移动端实现ip输入框问题


Posted in Javascript onMarch 19, 2019

vue框架移动端做ip输入框组件,input在浏览器和微信端兼容问题。

要求:只能输入数字,输入数字以外的字符(包括点、冒号等数字符号)时自动跳到下一段ip输入框.

type=number类型,不会禁止点的输入。手动过滤拿不到包括点字符的字符串.而且输入多个点之后,拿到的值为空.

解决办法:type=tel,只能输入数字,且可以获取到点字符的输入

问题:微信下keyup事件无效,回调事件中event.keyCode返回全是229.

解决办法:监听input事件,event事件对象中keycode为空,但是event.data返回输入字符,可以实现过滤.

<template>
  <div class="ipAdress">
    <ul class="ipInput" :class="{isDisabled:isDisabled}" >
      <li :key='index' v-for="(item,index) in ipAdress">
        <input :tabindex="'ipInput'+(index+1)" :class="'ipAdress'+(index+1)" @blur="blurFocus(index)" autocomplete="off" :readonly="isDisabled" maxlength="3" type="tel" pattern="[0-9]{1,3}" @input="checkIpVal(item,index,$event)" :disabled="isDisabled" @keyup="turnIpPOS(item,index,$event)" @keydown="delteIP(item,index,$event)" v-model="item.value" ref="ipInput" />
        <span v-if="index<3">.</span>
      </li>
    </ul>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        ipAdress: [{
          value: ''
        }, {
          value: ''
        }, {
          value: ''
        }, {
          value: ''
        }],
        isWX:navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == "micromessenger"
      };
    },
    props: {
      ipStr: {
        trype: String,
        default: ''
      },
      ipType: {
        type: String
      },
      isDisabled: {
        type: Boolean,
        default: false
      },
      width: {
        type: String,
        default:'100%'
      }
    },
    watch: {
      ipStr:{
        immediate:true,
        handler:function(vall) {
          let val = vall;
          let nArr = [];
          if(val && val.includes('.') && val.length > 0) {
            let valArr = val.split('.');
            let m = valArr.length;
            for(let i = 0; i < 4; i++) {
              if(valArr[i] == 'null' || valArr[i] == 'undefined'){
                valArr[i] = '';
              }
              if(i < m) {
                nArr.push({
                  value: valArr[i]
                });
              } else {
                nArr.push({
                  value: ''
                });
              }
            }
          } else {
            nArr = [{
              value: ''
            }, {
              value: ''
            }, {
              value: ''
            }, {
              value: ''
            }];
          }
          this.ipAdress = nArr;
        }
      } 
    },
    methods: {
      //methods
      blurFocus(index) {
        if(index == 3) {
          this.$emit('blur');
        }
      },
      checkIpVal(item,index,event) {
        let self = this;
        //wx
        if(this.isWX){
          let e = event || window.event;
          let keyCode = e.data;
          
//           //.向右跳转
          if(keyCode === ".") {
            e.preventDefault();
            e.returnValue = false;
            item.value = item.value.replace(/[^\d]/g, "").replace(/[\.]/g, "");
            if(index < 3 ) {
              self.$refs.ipInput[index + 1].focus();
            }
            return false;
          }
        }
        
        
        
        
        let isNo = /^[0-9]{1,3}$/g;
        if(/[^\d]/g.test(item.value)){
          let cache = JSON.parse(JSON.stringify(self.ipAdress));
          cache[index].value = item.value.replace(/[^\d]/g, "").replace(/[\.]/g, "");
          self.ipAdress = cache;
          return false;
        }
        
        
        
        if(item.value.replace(/[^\d]/g, "").length >= 3) {        
          let val = parseInt(item.value.replace(/[^\d]/g, ""), 10);
          if(isNaN(val)) {
            val = ''
          } else if(val > 255) {
            val = 255;
          } else {
            val = val < 0 ? 0 : val;
          }
          item.value = String(val);
          this.$set(this.ipAdress,index,item);
          if(index < 3 ) {            
            self.$refs.ipInput[index + 1].focus();                
          }
        }      
        let ns = '';
        this.ipAdress.forEach(item => ns += '.' + item.value);
        if(ns.length <= 4){
          this.$emit('getIP', "", this.ipType);
        }else{
          this.$emit('getIP', ns.slice(1), this.ipType);
        }

      },
      turnIpPOS(item, index, event) {
        let self = this;
        let e = event || window.event;
        
        if(e.keyCode == 37) {
          if(index != 0) {
            self.$refs.ipInput[index - 1].focus();
          }
        }
        //右箭头、回车键、空格键、冒号均向右跳转,右一不做任何措施
        if(e.keyCode == 39 || e.keyCode == 13 || e.keyCode == 32 || e.keyCode == 110 || e.keyCode == 46 || e.keyCode == 190 ) {
          e.preventDefault();
          e.returnValue = false;
          if(index < 3 ) {
            self.$refs.ipInput[index + 1].focus();
          }
          return false;
        }
        
      },
      delteIP(item, index, event) {  
        let self = this;
        let e = event || window.event;
        
        let val = parseInt(item.value.replace(/[^\d]/g, ""), 10);
        val = isNaN(val) ? '' : val;
        if(e.keyCode == 8 && index > 0 && val.length==0) {
            self.$refs.ipInput[index - 1].focus();
        }
      }
    },
    mounted(){
      console.log(this.$props)
      console.log(this.$attrs.index)
    }
  };
</script>

<style lang="scss" scoped>
  $--border-color:#ccc;
  $--outline-color:transparent;
  $--font-color:$--input-color;
  $base-font-size:12px;
  .ipInput {
    box-sizing: border-box;
    line-height: inherit;
    border: 1px solid $--border-color;
    overflow: hidden;
    border-radius: 5px;
    padding: 0;
    margin: 0;
    display: inline-block;
    vertical-align: middle;
    outline: $--outline-color;
    font-size:0;
    text-indent: 0;
    background: #fff;
    &.isDisabled {
      background: $--outline-color;

      li{
        cursor:not-allowed;
        input{
          cursor:not-allowed;
        }
      }
    }
    li {
      display: inline-block;
      width:25%;
      box-sizing: border-box;
      font-size:0;
      input {
        appearance: none; 
        padding:10px 5px;
        width: calc(100% - 3px);
        text-align: center;
        outline: none;
        border: none;
        color: $--font-color;
        box-sizing: border-box;
        font-size: $base-font-size;
        &:disabled {
          background: $--outline-color;
        }
      }
      span {
        display: inline-block;
        font-size:$base-font-size;
        width: 3px;
        color: $--font-color;
      }
    }
  }
</style>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
用JS实现一个页面多个css样式实现
May 29 Javascript
javascript new 需不需要继续使用
Jul 02 Javascript
innerText 使用示例
Jan 23 Javascript
Bootstrap 折叠(Collapse)插件用法实例详解
Jun 01 Javascript
浅谈js中调用函数时加不加括号的问题
Jul 28 Javascript
D3.js实现折线图的方法详解
Sep 21 Javascript
layui表格checkbox选择全选样式及功能的实例
Mar 07 Javascript
vue基于mint-ui实现城市选择三级联动
Jun 30 Javascript
vue2.0实现音乐/视频播放进度条组件
Jun 06 Javascript
微信小程序页面缩放式侧滑效果的实现代码
Nov 15 Javascript
VSCode使用之Vue工程配置eslint
Apr 30 Javascript
vue循环数组改变点击文字的颜色
Oct 14 Javascript
详解使用React.memo()来优化函数组件的性能
Mar 19 #Javascript
vue组件定义,全局、局部组件,配合模板及动态组件功能示例
Mar 19 #Javascript
express.js中间件说明详解
Mar 19 #Javascript
js array数组对象操作方法汇总
Mar 18 #Javascript
浅析JavaScript异步代码优化
Mar 18 #Javascript
js实现图片局部放大效果详解
Mar 18 #Javascript
详解在React项目中安装并使用Less(用法总结)
Mar 18 #Javascript
You might like
php数组(array)输出的三种形式详解
2013/06/05 PHP
javascript字典探测用户名工具
2006/10/05 Javascript
js类后台管理菜单类-MenuSwitch
2007/09/12 Javascript
JQuery与JS里submit()的区别示例介绍
2014/02/17 Javascript
jquery高级编程的最佳实践详解
2014/03/23 Javascript
浅谈javascript获取元素transform参数
2015/07/24 Javascript
基于JavaScript实现Tab选项卡切换效果
2016/11/24 Javascript
浅谈angular2的http请求返回结果的subcribe注意事项
2017/03/01 Javascript
详解nodeJS中读写文件方法的区别
2017/03/06 NodeJs
微信小程序wepy框架笔记小结
2018/08/08 Javascript
IE9 elementUI文件上传的问题解决
2018/10/17 Javascript
layui(1.0.9)文件上传upload,前后端的实例代码
2019/09/26 Javascript
element-ui 本地化使用教程详解
2019/10/28 Javascript
分享Angular http interceptors 拦截器使用(推荐)
2019/11/10 Javascript
vue.js 实现a标签href里添加参数
2019/11/12 Javascript
利用React高阶组件实现一个面包屑导航的示例
2020/08/23 Javascript
[02:54]辉夜杯主赛事第二日败者组 iG.V赛后采访
2015/12/26 DOTA
Python中Django框架下的staticfiles使用简介
2015/05/30 Python
使用paramiko远程执行命令、下发文件的实例
2017/10/01 Python
python找出列表中大于某个阈值的数据段示例
2019/11/24 Python
HTML5实现锚点时请使用id取代name
2013/09/06 HTML / CSS
诗普兰迪官方网站:Splendid
2018/09/18 全球购物
Seavenger官网:潜水服、浮潜、靴子和袜子
2020/03/05 全球购物
应届生妇产科护士求职信
2013/10/27 职场文书
市场部专员岗位职责
2013/11/30 职场文书
大学生创业计划书的格式要求
2013/12/29 职场文书
个人优缺点自我评价
2014/01/27 职场文书
军神教学反思
2014/02/04 职场文书
心理健康活动总结
2014/04/30 职场文书
新法人代表任命书
2014/06/06 职场文书
婚内房产协议书范本
2014/10/02 职场文书
2014年店长工作总结
2014/11/17 职场文书
小学家长通知书评语
2014/12/31 职场文书
拾金不昧表扬信怎么写
2015/05/04 职场文书
无罪辩护词范文
2015/05/21 职场文书
React更新渲染原理深入分析
2022/12/24 Javascript