手机表单验证插件mvalidate的使用

简介:

422101-20161104152307627-1435087373.png

422101-20161104152315018-2133622789.png

使用

1.引入js和css

<script type="text/javascript" src="../script/jquery-mvalidate.js"></script>
<link rel="stylesheet" type="text/css" href="../css/mvalidate.css">

2.html处理

        <li class="aui-list-item">
            <div class="aui-list-item-inner">
                <div class="aui-list-item-input">
                    <input type="text" name="name" data-required="true" data-descriptions="name" placeholder="收货人姓名">
                </div>
            </div>
        </li>
        <li class="aui-list-item">
            <div class="aui-list-item-inner">
                <div class="aui-list-item-input">
                    <input type="text" name="tel" placeholder="手机号码" data-required="true" data-descriptions="tel" data-pattern="^0?1[3|4|5|8][0-9]\d{8}$">
                </div>
            </div>
        </li>

3.js处理

$("#myform").mvalidate({
    type:1,
    onKeyup:true,
    sendForm:true,
    firstInvalidFocus:true,
    valid:function(event,options){
        //点击提交按钮时,表单通过验证触发函数
        //alert("验证通过!接下来可以做你想做的事情啦!");
        event.preventDefault();
    },
    invalid:function(event, status, options){
        //点击提交按钮时,表单未通过验证触发函数
        // alert("表单未通过验证!");
    },
    eachField:function(event,status,options){
        //点击提交按钮时,表单每个输入域触发这个函数 this 执向当前表单输入域,是jquery对象
        // alert("每个都弹出!");
    },
    eachValidField:function(val){},
    eachInvalidField:function(event, status, options){},
    conditional:{
    },
    descriptions:{
        name:{
            required : '请输入收货人姓名'
        },
        tel : {
            required : '请输入手机号码',
            pattern : '手机号格式不正确'
        }
    }
});

jquery版本

(function (factory) {
    if (typeof define === 'function' && define.amd ) {
        define(['jquery'], function(jquery){
            // 返回构造函数
            factory(jquery); // 初始化插件   
        });
    }else if(typeof define === 'function' && define.cmd){
        define(['jquery'], function(require,exports,moudles){
            factory(
            require('jquery')); // 初始化插件
        })
    }else{
        factory(jQuery);
    }
})(function($){
    var type = ['input:not([type]),input[type="color"],input[type="date"],input[type="datetime"],input[type="datetime-local"],input[type="email"],input[type="file"],input[type="hidden"],input[type="month"],input[type="number"],input[type="password"],input[type="range"],input[type="search"],input[type="tel"],input[type="text"],input[type="time"],input[type="url"],input[type="week"],textarea', 'select', 'input[type="checkbox"],input[type="radio"]'],
        allTypes=type.join(","),
        extend={};
    var fieldValidTypeHand=function($field,status,options){
                if($field.prop("type")=="radio" || $field.prop("type")=="checkbox"){
                    var $fields=options.$form.find('[name="'+$field.prop('name')+'"]');

                    if($fields.filter(":checked").length > 0){
                        $fields.removeClass('field-invalid')
                    }else{
                        $fields.addClass('field-invalid')
                    }
                }else{
                    if(status.required && status.pattern && status.conditional) {
                        $field.removeClass('field-invalid');
                    }else{
                        $field.addClass('field-invalid');
                    }
                }
    };
    var fieldTooltip=(function(){
            var instance=null;
                function show(text){
                    if(!instance){
                        var $container=$('<div class="field-tooltipWrap"><div class="field-tooltipInner"><div class="field-tooltip fieldTipBounceIn">'+text+'</div></div></div>');
                        $container.appendTo($("body"));
                        instance=true;
                        setTimeout(function(){
                            $container.remove();
                            instance=false;
                        },1500)
                    }
                }
           
            return {
                show:show
            }
    })();
    var validateField=function(event,options){
        var $field=$(this),
            status={
                required:true,
                conditional:true,
                pattern:true
            },
            log,//验证提示信息存储变量
            
            errorTipFormat=$.fn.mvalidate.errorTipFormat,//错误信息输出的格式化
            
            fieldValue =$.trim($field.val()) || "",

            //*****获取当前字段的data-validate
            fieldValidate=$field.attr("data-validate"),
            validation=(fieldValidate != undefined) ? extend[fieldValidate]:{},
            //*****获取当前字段的data-required
            fieldRequired=$field.attr("data-required"),
            //*****获取当前字段的data-pattern
            fieldPattern = ($field.attr('data-pattern') || ($.type(validation.pattern) == 'regexp' ? validation.pattern : /(?:)/)),


            //*****获取当前字段的data-conditional
            fieldConditional=$field.attr("data-conditional") || validation.conditional,
            //*****获取当前字段的data-description
            fieldDescription=$field.attr("data-descriptions") || validation.descriptions,
            //*****获取当前字段的data-describedby
            fieldDescribedby=$field.attr("data-describedby") || validation.describedby;

            fieldDescription = $.isPlainObject(fieldDescription) ? fieldDescription : (options.descriptions[fieldDescription] || {});
            fieldRequired=fieldRequired !='' ? (fieldRequired || !!validation.required ) : true;
            if($.type(fieldPattern) != 'regexp') {
                fieldPattern=RegExp(fieldPattern);
            }

        //如果是必填验证,那么就要判断是什么类型的表单
        if(fieldRequired) {
            //如果是那种可以通过val()来判断的
            if($field.is(type[0] + ',' + type[1])) {
                if(!fieldValue.length > 0){
                    status.required = false;
                }
            //如果是raido和checkbox,通过name和checked来判断
            }else if($field.is(type[2])){
                if($field.is('[name]')) {
                    if(options.$form.find('[name="'+$field.prop('name')+'"]:checked').length==0){
                        status.required = false;
                    }
                }else{
                    status.required = field.is(':checked');
                }
            }
        }
        /**如果是正则验证
         * 只有那些类似type=text的文本框我们才能通过正则表达式去验证pattern,
         * 而对于select,radio,checkbox pattern显然是无效的
         */
        if($field.is(type[0])) {
            //如果不匹配
            if(!fieldPattern.test(fieldValue)){
                if(fieldRequired){
                    status.pattern=false;
                }else{
                    if(fieldValue.length > 0){
                        status.pattern = false;
                    }
                }
            }
        }

        //如果是data-conditional="name"函数验证,函数返回true或者是false
        if(fieldConditional !="undefined"){
            if($.isFunction(fieldConditional)){
                status.conditional=!!fieldConditional.call($field, fieldValue,options);
            }else{
                if(options.conditional.hasOwnProperty(fieldConditional) && !options.conditional[fieldConditional].call($field,fieldValue,options)){
                    status.conditional=false;
                }
            }
        }

     
        //验证通过的信息所在对象
        log = errorTipFormat(fieldDescription.valid);
        if(!status.required) {
            log = errorTipFormat(fieldDescription.required);
            
        }else if(!status.pattern) {
            log = errorTipFormat(fieldDescription.pattern);
            
            
        } else if(!status.conditional) {
            log =errorTipFormat(fieldDescription.conditional);
        }

        var $describedShowElem=$('[id="' + fieldDescribedby +'"]');
        //如果找打提示的容器,是第二种类型的验证
        if($describedShowElem.length > 0 && options.type==2){
            //如果是change 或者是keyup 同时是第一次输入的时候就不要验证
            if((event.type=="keyup" || event.type=="change") && (!$describedShowElem.children().length || !$.trim($describedShowElem.text()))){

            }else{                  
                $describedShowElem.html(log || '');
                fieldValidTypeHand($field,status,options)
            }
        }

        if(typeof(validation.each) == 'function') {
            validation.each.call($field, event, status, options);
        }
        options.eachField.call($field, event, status, options);

        if(status.required && status.pattern && status.conditional) {   
            
            if(typeof(validation.valid) == 'function') {//二外拓展的
                validation.valid.call($field, event, status, options);
            }
            options.eachValidField.call($field, event, status, options);
        }else{//验证未通过
            if(!options.firstInvalid && options.firstInvalidFocus){
                options.firstInvalid=true;
                $field.focus();
            }
            if(options.type==1){
                fieldTooltip.show(log)
            }
            if(typeof(validation.invalid) == 'function') {
                validation.invalid.call($field, event, status, options);
            }
            options.eachInvalidField.call($field, event, status, options);  
        }
        
    /**
     * 如果是data-describedby="elemId"验证信息要显示的地方,类型3的验证:
         *      第一元素获取焦点,keyUp的时候要一直验证,如果正确那么错误信息就隐藏,如果不正确,那么错误
         *      提示信息要根据状态而改变,对于与验证通过,那么可以通过eachInvalid来让用户自定义,而无需要
         *      在插件中写它的操作方式
         */
        return status;
    };
    $.extend($,{
        mvalidateExtend:function(options){
            return $.extend(extend, options);   
        },
        mvalidateTip:function(text){
            var txt=$.fn.mvalidate.errorTipFormat(text);
            fieldTooltip.show(txt)
        }
    });



    
    
    $.fn.mvalidate=function(options){
        var defaults={
            type:1,
            validateInSubmit:true,
            sendForm:true,
            onKeyup:false,
            onChange:true,
            firstInvalidFocus:true,//第一个未通过验证的表单是否获得交代呢
            conditional:{},
            descriptions:{},
            eachField : $.noop,
            eachValidField:$.noop,
            eachInvalidField : $.noop,
            valid:$.noop,
            invalid:$.noop,
            namespace:"mvalidate"
        },
        opts=$.extend(true,defaults,options),
        flag,
        namespace=opts.namespace;

        opts.type=Number(opts.type);
        opts.firstInvalid=false;
        flag=opts.type==1 ? false : true;
        return this.mvalidateDestroy().each(function(event) {
            
            var $form=$(this),
                $fields;//存放当前表单下的所有元素;
            if(!$form.is("form")) return;
            opts.$form=$form;
            $form.data(name,{"options":opts});
            $fields=$form.find(allTypes);
            
            //
            if(flag && opts.onKeyup){
                $fields.filter(type[0]).each(function() {

                    $(this).on("keyup."+namespace,function(event){
                        validateField.call(this,event,opts)
                    })
                });
            }

            if(flag && opts.onChange){
                $fields.each(function() {
                    var $this=$(this);
                    if($this.is(type[1]+ ',' + type[2])){
                        $(this).on('change.' + namespace, function(event) {
                            validateField.call(this, event, opts);
                        })
                    }   
                })
            }

            //如果需要验证的时候,在提交表单的时候对所有的字段进行验证
            if(opts.validateInSubmit){
                $form.on("submit."+namespace,function(event){
                    var formValid = true;
                    opts.firstInvalid=false;
                    $fields.each(function() {
                        var status=validateField.call(this,event,opts);
                        if(!status.pattern || !status.conditional || !status.required) {
                            formValid = false;
                        }
                    });
                    
                    if(formValid){
                        if(!opts.sendForm){
                            event.preventDefault();
                        }
                        if($.isFunction(opts.valid)){
                            opts.valid.call($form,event,opts);
                        }
                    //验证没有通过,禁用提交事件,以及绑定在这个elem上的其他事件   
                    }else{
                        event.preventDefault();
                        event.stopImmediatePropagation();
                        if($.isFunction(opts.invalid)) {
                            opts.invalid.call($form,event,opts)
                        }
                    }
                    
                })
            }
        })
    };
    $.fn.mvalidateDestroy=function(){
        var $form=$(this),$fields,
            dataValidate=$form.data(name);
        if($form.is('form') && $.isPlainObject(dataValidate) && typeof(dataValidate.options.nameSpace) == 'string') {
            $fields = $form.removeData(name).find(allTypes);
            $fields.off('.' + dataValidate.options.nameSpace);
        }   
        return $form;
    };
    $.fn.mvalidate.errorTipFormat=function(text){
        return '<div class="zvalid-resultformat">'+text+'</div>';
    }


})

zetpo版本

(function (factory) {
    if (typeof define === 'function' && define.amd ) {
        define(['Zepto'], function(zepto){
            // 返回构造函数
            factory(zepto); // 初始化插件    
        });
    }else if(typeof define === 'function' && define.cmd){
        define(['Zepto'], function(require,exports,moudles){
            factory(require('Zepto')); // 初始化插件
        })
    }else{
        factory(Zepto);
    }
})(function($){
    var type = ['input:not([type]),input[type="color"],input[type="date"],input[type="datetime"],input[type="datetime-local"],input[type="email"],input[type="file"],input[type="hidden"],input[type="month"],input[type="number"],input[type="password"],input[type="range"],input[type="search"],input[type="tel"],input[type="text"],input[type="time"],input[type="url"],input[type="week"],textarea', 'select', 'input[type="checkbox"],input[type="radio"]'],
        allTypes=type.join(","),
        extend={};
    var fieldValidTypeHand=function($field,status,options){
                if($field.prop("type")=="radio" || $field.prop("type")=="checkbox"){
                    var $fields=options.$form.find('[name="'+$field.prop('name')+'"]');

                    if($fields.filter(":checked").length > 0){
                        $fields.removeClass('field-invalid')
                    }else{
                        $fields.addClass('field-invalid')
                    }
                }else{
                    if(status.required && status.pattern && status.conditional) {
                        $field.removeClass('field-invalid');
                    }else{
                        $field.addClass('field-invalid');
                    }
                }
    };
    var fieldTooltip=(function(){
            var instance=null;
                function show(text){
                    if(!instance){
                        var $container=$('<div class="field-tooltipWrap"><div class="field-tooltipInner"><div class="field-tooltip fieldTipBounceIn">'+text+'</div></div></div>');
                        $container.appendTo($("body"));
                        instance=true;
                        setTimeout(function(){
                            $container.remove();
                            instance=false;
                        },1500)
                    }
                }
           
            return {
                show:show
            }
    })();
    var validateField=function(event,options){
        var $field=$(this),
            status={
                required:true,
                conditional:true,
                pattern:true
            },
            log,//验证提示信息存储变量
            
            errorTipFormat=$.fn.mvalidate.errorTipFormat,//错误信息输出的格式化
            
            fieldValue =$.trim($field.val()) || "",

            //*****获取当前字段的data-validate
            fieldValidate=$field.attr("data-validate"),
            validation=(fieldValidate != undefined) ? extend[fieldValidate]:{},
            //*****获取当前字段的data-required
            fieldRequired=$field.attr("data-required"),
            //*****获取当前字段的data-pattern
            fieldPattern = ($field.attr('data-pattern') || ($.type(validation.pattern) == 'regexp' ? validation.pattern : /(?:)/)),


            //*****获取当前字段的data-conditional
            fieldConditional=$field.attr("data-conditional") || validation.conditional,
            //*****获取当前字段的data-description
            fieldDescription=$field.attr("data-descriptions") || validation.descriptions,
            //*****获取当前字段的data-describedby
            fieldDescribedby=$field.attr("data-describedby") || validation.describedby;

            fieldDescription = $.isPlainObject(fieldDescription) ? fieldDescription : (options.descriptions[fieldDescription] || {});
            fieldRequired=fieldRequired !='' ? (fieldRequired || !!validation.required ) : true;
            if($.type(fieldPattern) != 'regexp') {
                fieldPattern=RegExp(fieldPattern);
            }

        //如果是必填验证,那么就要判断是什么类型的表单
        if(fieldRequired) {
            //如果是那种可以通过val()来判断的
            if($field.is(type[0] + ',' + type[1])) {
                if(!fieldValue.length > 0){
                    status.required = false;
                }
            //如果是raido和checkbox,通过name和checked来判断
            }else if($field.is(type[2])){
                if($field.is('[name]')) {
                    if(options.$form.find('[name="'+$field.prop('name')+'"]:checked').length==0){
                        status.required = false;
                    }
                }else{
                    status.required = field.is(':checked');
                }
            }
        }
        /**如果是正则验证
         * 只有那些类似type=text的文本框我们才能通过正则表达式去验证pattern,
         * 而对于select,radio,checkbox pattern显然是无效的
         */
        if($field.is(type[0])) {
            //如果不匹配
            if(!fieldPattern.test(fieldValue)){
                if(fieldRequired){
                    status.pattern=false;
                }else{
                    if(fieldValue.length > 0){
                        status.pattern = false;
                    }
                }
            }
        }

        //如果是data-conditional="name"函数验证,函数返回true或者是false
        if(fieldConditional !="undefined"){
            if($.isFunction(fieldConditional)){
                status.conditional=!!fieldConditional.call($field, fieldValue,options);
            }else{
                if(options.conditional.hasOwnProperty(fieldConditional) && !options.conditional[fieldConditional].call($field,fieldValue,options)){
                    status.conditional=false;
                }
            }
        }

     
        //验证通过的信息所在对象
        
        log = errorTipFormat(fieldDescription.valid);
        if(!status.required) {
            log = errorTipFormat(fieldDescription.required);
            
        }else if(!status.pattern) {
            log = errorTipFormat(fieldDescription.pattern);
            
            
        } else if(!status.conditional) {
            log =errorTipFormat(fieldDescription.conditional);
        }

        var $describedShowElem=$('[id="' + fieldDescribedby +'"]');
        //如果找打提示的容器,是第二种类型的验证
        if($describedShowElem.length > 0 && options.type==2){
            //如果是change 或者是keyup 同时是第一次输入的时候就不要验证
            if((event.type=="keyup" || event.type=="change") && (!$describedShowElem.children().length || !$.trim($describedShowElem.text()))){

            }else{                  
                $describedShowElem.html(log || '');
                fieldValidTypeHand($field,status,options)
            }
        }

        if(typeof(validation.each) == 'function') {
            validation.each.call($field, event, status, options);
        }
        options.eachField.call($field, event, status, options);

        if(status.required && status.pattern && status.conditional) {   
            
            if(typeof(validation.valid) == 'function') {//二外拓展的
                validation.valid.call($field, event, status, options);
            }
            options.eachValidField.call($field, event, status, options);
        }else{//验证未通过
            if(!options.firstInvalid && options.firstInvalidFocus){
                options.firstInvalid=true;
                $field.focus();
            }
            if(options.type==1){
                fieldTooltip.show(log)
            }
            if(typeof(validation.invalid) == 'function') {
                validation.invalid.call($field, event, status, options);
            }
            options.eachInvalidField.call($field, event, status, options);  
        }
        
    /**
     * 如果是data-describedby="elemId"验证信息要显示的地方,类型3的验证:
         *      第一元素获取焦点,keyUp的时候要一直验证,如果正确那么错误信息就隐藏,如果不正确,那么错误
         *      提示信息要根据状态而改变,对于与验证通过,那么可以通过eachInvalid来让用户自定义,而无需要
         *      在插件中写它的操作方式
         */
        return status;
    };
    $.extend($,{
        mvalidateExtend:function(options){
            return $.extend(extend, options);   
        }
    });

    
    
    $.fn.mvalidate=function(options){
        var defaults={
            type:1,
            validateInSubmit:true,
            sendForm:true,
            onKeyup:false,
            onChange:true,
            firstInvalidFocus:true,//第一个未通过验证的表单是否获得交代呢
            conditional:{},
            descriptions:{},
            eachField : $.noop,
            eachValidField:$.noop,
            eachInvalidField : $.noop,
            valid:$.noop,
            invalid:$.noop,
            namespace:"mvalidate"
        },
        opts=$.extend(true,defaults,options),
        flag,
        namespace=opts.namespace;

        opts.type=Number(opts.type);
        opts.firstInvalid=false;
        flag=opts.type==1 ? false : true;
        return this.mvalidateDestroy().each(function(event) {
            
            var $form=$(this),
                $fields;//存放当前表单下的所有元素;
            if(!$form.is("form")) return;
            opts.$form=$form;
            $form.data(name,{"options":opts});
            $fields=$form.find(allTypes);
            
            //
            if(flag && opts.onKeyup){
                $fields.filter(type[0]).each(function() {

                    $(this).on("keyup."+namespace,function(event){
                        validateField.call(this,event,opts)
                    })
                });
            }

            if(flag && opts.onChange){
                $fields.each(function() {
                    var $this=$(this);
                    if($this.is(type[1]+ ',' + type[2])){
                        $(this).on('change.' + namespace, function(event) {
                            validateField.call(this, event, opts);
                        })
                    }   
                })
            }

            //如果需要验证的时候,在提交表单的时候对所有的字段进行验证
            if(opts.validateInSubmit){
                $form.on("submit."+namespace,function(event){
                    var formValid = true;
                    opts.firstInvalid=false;
                    $fields.each(function() {
                        var status=validateField.call(this,event,opts);
                        if(!status.pattern || !status.conditional || !status.required) {
                            formValid = false;
                        }
                    });
                    
                    if(formValid){
                        if(!opts.sendForm){
                            event.preventDefault();
                        }
                        if($.isFunction(opts.valid)){
                            opts.valid.call($form,event,opts);
                        }
                    //验证没有通过,禁用提交事件,以及绑定在这个elem上的其他事件   
                    }else{
                        event.preventDefault();
                        event.stopImmediatePropagation();
                        if($.isFunction(opts.invalid)) {
                            opts.invalid.call($form,event,opts)
                        }
                    }
                    
                })
            }
        })
    };
    $.fn.mvalidateDestroy=function(){
        var $form=$(this),$fields,
            dataValidate=$form.data(name);
        if($form.is('form') && $.isPlainObject(dataValidate) && typeof(dataValidate.options.namespace) == 'string') {
            $fields = $form.removeData(name).find(allTypes);
            $fields.off('.' + dataValidate.options.namespace);
        }   
        return $form;
    };
    $.fn.mvalidate.errorTipFormat=function(text){
        return '<div class="zvalid-resultformat">'+text+'</div>';
    }
})

css

.field-invalid{
    border-color:#a94442;
}
.field-invalidmsg{
    color:#a94442;
}
.field-validmsg{
    color:#3c763d;
}
.field-tooltipWrap{
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    z-index: 19891014;
}
.field-tooltipInner{
    pointer-events: none;
    display: table;
    position:fixed;
    left:0;
    top:0;
    width:100%;
    height:100%;
}
.field-tooltip{
    display: table-cell;
    vertical-align: middle;
    text-align: center;
}
.field-tooltip .field-invalidmsg,
.field-tooltip .field-validmsg{
    color: #fff;
}
.field-tooltip .zvalid-resultformat{
    display: inline-block;
    position: relative;
    background-color:rgba(0,0,0,0.8);
    color: #fff;
    padding: 10px 15px;
    font-size: 14px;
    border-radius: 6px;
    box-shadow: 0 0 8px rgba(0,0,0,.1);
    pointer-events: auto;
    animation-name:fieldTipBounceIn;
    -webkit-animation-name:fieldTipBounceIn;
    -webkit-animation-fill-mode: both;
    animation-fill-mode: both;
    -webkit-animation-duration: .18s;
    animation-duration: .18s;
}

@-webkit-keyframes fieldTipBounceIn{

  0% {
    opacity: 0;
    -webkit-transform: scale3d(.3, .3, .3);
    transform: scale3d(.3, .3, .3);
  }
  100% {
    opacity: 1;
    -webkit-transform: scale3d(1, 1, 1);
    transform: scale3d(1, 1, 1);
  }
}


@keyframes 

{


  0% {
    opacity: 0;
    -webkit-transform: scale3d(.3, .3, .3);
    transform: scale3d(.3, .3, .3);
  }
  100% {
    opacity: 1;
    -webkit-transform: scale3d(1, 1, 1);
    transform: scale3d(1, 1, 1);
  }
}


本文转自TBHacker博客园博客,原文链接:http://www.cnblogs.com/jiqing9006/p/6030474.html,如需转载请自行联系原作者
相关实践学习
基于Hologres轻松玩转一站式实时仓库
本场景介绍如何利用阿里云MaxCompute、实时计算Flink和交互式分析服务Hologres开发离线、实时数据融合分析的数据大屏应用。
阿里云实时数仓实战 - 项目介绍及架构设计
课程简介 1)学习搭建一个数据仓库的过程,理解数据在整个数仓架构的从采集、存储、计算、输出、展示的整个业务流程。 2)整个数仓体系完全搭建在阿里云架构上,理解并学会运用各个服务组件,了解各个组件之间如何配合联动。 3&nbsp;)前置知识要求 &nbsp; 课程大纲 第一章&nbsp;了解数据仓库概念 初步了解数据仓库是干什么的 第二章&nbsp;按照企业开发的标准去搭建一个数据仓库 数据仓库的需求是什么 架构 怎么选型怎么购买服务器 第三章&nbsp;数据生成模块 用户形成数据的一个准备 按照企业的标准,准备了十一张用户行为表 方便使用 第四章&nbsp;采集模块的搭建 购买阿里云服务器 安装 JDK 安装 Flume 第五章&nbsp;用户行为数据仓库 严格按照企业的标准开发 第六章&nbsp;搭建业务数仓理论基础和对表的分类同步 第七章&nbsp;业务数仓的搭建&nbsp; 业务行为数仓效果图&nbsp;&nbsp;
相关文章
|
2月前
|
小程序 JavaScript
微信小程序图片预览功能?
微信小程序图片预览功能?
|
7月前
|
JavaScript 前端开发
原生JS实现移动端短信验证码功能
原生JS实现移动端短信验证码功能
148 0
原生JS实现移动端短信验证码功能
|
4月前
|
JavaScript
|
1月前
|
JavaScript 前端开发 UED
JS自动跳转手机移动网页
JS自动跳转手机移动网页
454 0
|
3月前
|
JavaScript 前端开发 iOS开发
移动端(vue)如何调用手机拨号功能
移动端(vue)如何调用手机拨号功能
|
7月前
|
缓存 Android开发 iOS开发
手机端常见兼容问题
手机端常见兼容问题
|
8月前
|
JavaScript 前端开发 Android开发
uniapp+vue+uview适配安卓4.4项目实现简单登录和操作页面
uniapp+vue+uview适配安卓4.4项目实现简单登录和操作页面
172 0
|
Web App开发 JavaScript 前端开发
实现Web端自定义截屏(原生JS版)
实现Web端自定义截屏(原生JS版)
实现Web端自定义截屏(原生JS版)
|
移动开发 前端开发 JavaScript
移动端H5通用表单验证插件
将表单验证的通用部分提炼出来,做成一个简易插件,方便调用。 已将源码放到GitHub上,名字叫zValidate。
移动端H5通用表单验证插件
|
前端开发 JavaScript Android开发
前端jquery解决安卓手机端底部菜单栏被输入法顶上去的方案
前端jquery解决安卓手机端底部菜单栏被输入法顶上去的方案
89 0