常见的API扩展形式

prototype

比如我现在有一个需求,给定一个字符串,给方法传递一个参数为数字类型来确定当前字符串重复次数,例如:

'abc'.repeatStringNumTimes(3) // abcabcabc

如果按照一般的思维就是我们把这个方法绑定到String的原型上,如下代码:

String.prototype.repeatStringNumTimes = String.prototype.repeatStringNumTimes || function(times) {
var str = '';
for(var i = 0; i < times; i++) {
str += this;
}
return str;
}

jQuery

根据《jQuery高级编程》的描述,jQuery插件开发方式主要有三种:

  • 通过$.extend()来扩展jQuery

  • 通过$.fn 向jQuery添加新的方法

  • 通过$.widget()应用jQuery UI的部件工厂方式创建

通常我们使用第二种方法来进行简单插件开发,说简单是相对于第三种方式。第三种方式是用来开发更高级jQuery部件的,该模式开发出来的部件带有很多jQuery内建的特性,比如插件的状态信息自动保存,各种关于插件的常用方法等,非常贴心,这里不细说。

而第一种方式又太简单,仅仅是在jQuery命名空间或者理解成jQuery身上添加了一个静态方法而以。所以我们调用通过.extend()添加的函数时直接通过.extend()添加的函数时直接通过符号调用($.myfunction())而不需要选中DOM元素($('#example').myfunction())。请看下面的例子。

$.extend({
sayHello: function(name) {
console.log('Hello,' + (name ? name : 'Dude') + '!');
}
})
$.sayHello(); //调用
$.sayHello('Wayou'); //带参调用

看一个jquery封装的面向对象的插件开发代码:

//定义Beautifier的构造函数
var Beautifier = function(ele, opt) {
this.$element = ele,
this.defaults = {
'color': 'red',
'fontSize': '12px',
'textDecoration':'none'
},
this.options = $.extend({}, this.defaults, opt)
}
//定义Beautifier的方法
Beautifier.prototype = {
beautify: function() {
return this.$element.css({
'color': this.options.color,
'fontSize': this.options.fontSize,
'textDecoration': this.options.textDecoration
});
}
}
//在插件中使用Beautifier对象
$.fn.myPlugin = function(options) {
//创建Beautifier的实体
var beautifier = new Beautifier(this, options);
//调用其方法
return beautifier.beautify();
}

调用方式:

$(function() {
$('a').myPlugin({
'color': '#2C9929',
'fontSize': '20px'
});
})

感兴趣的可以详细查看文章:《jQuery插件开发进阶》

vue

插件通常会为 Vue 添加全局功能。插件的范围没有限制——一般有下面几种:

  • 1.添加全局方法或者属性,如: vue-custom-element
  • 2.添加全局资源:指令/过滤器/过渡等,如 vue-touch
  • 3.通过全局 mixin 方法添加一些组件选项,如: vue-router
  • 4.添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。
  • 5.一个库,提供自己的 API,同时提供上面提到的一个或多个功能,如 vue-router

Vue.js 的插件应当有一个公开方法 install 。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象:

MyPlugin.install = function (Vue, options) {
// 1. 添加全局方法或属性
Vue.myGlobalMethod = function () {
// 逻辑...
} // 2. 添加全局资源
Vue.directive('my-directive', {
bind (el, binding, vnode, oldVnode) {
// 逻辑...
}
...
}) // 3. 注入组件
Vue.mixin({
created: function () {
// 逻辑...
}
...
}) // 4. 添加实例方法
Vue.prototype.$myMethod = function (methodOptions) {
// 逻辑...
}
}
export default MyPlugin

封装的插件怎样使用?通过全局方法 Vue.use() 使用插件:

// 调用 `MyPlugin.install(Vue)`
Vue.use(MyPlugin)

也可以传入一个选项对象:

Vue.use(MyPlugin, { someOption: true })

实现一个表单验证

设计表单验证的规则就是开放-封闭验证,使用策略模式封装。

一般方案

我们先写一个html代码片段好验证代码:

<form action="" id="registerForm" method="post" onsubmit="return submitValidate()">
<p>
<label>请输入用户名:</label>
<input type="text" name="userName" />
</p>
<p>
<label>请输入密码:</label>
<input type="text" name="password" />
</p>
<p>
<label>请输入手机号码:</label>
<input type="text" name="phoneNumber" />
</p>
<div>
<button type="submit">提交</button>
</div>
</form>

在form上绑定的submit,想实现的submitValidate方法代码如下:

function submitValidate() {
var registerForm = document.getElementById("registerForm");
var rulesArr = [
{
el: registerForm.userName.value,
rules: [{rule: 'isNonEmpty',message: '用户名不能为空'},{rule:'minLength:3',message: '用户名长度不能小于3位'}]
},
{
el: registerForm.password.value,
rules: [{rule: 'isNonEmpty',message: '密码不能为空'},{rule:'minLength:6',message: '密码的长度不能小于6位'}]
},
{
el: registerForm.phoneNumber.value,
rules: [{rule: 'isNonEmpty',message: '手机号不能为空'},{rule:'isMobile',message: '手机号码格式不正确'}]
}
]
var resultMsg = validate.check(rulesArr);
if(resultMsg) {
alert(resultMsg);
return false;
}
return true;
}

下面我们编写validate验证方法,代码如下:

var validate = (function() {
// 校验规则的各种算法
var rules = {
// 判断非空
isNonEmpty: function(value,errorMsg) {
if(!value) {
return errorMsg;
}
},
// 判断最小长度
minLength: function(value,length,errorMsg) {
if(value.toString().length < length) {
return errorMsg;
}
},
// 判断最大长度
maxLength: function(value,length,errorMsg) {
if(value.toString().length > length) {
return errorMsg;
}
},
// 判断手机号
isMobile: function(value,errorMsg) {
if (!/(^1[0-9]{10}$)/.test(value)) {
return errorMsg;
}
},
// 判断座机电话
isTel: function(value,errorMsg) {
if(!/^\d{3}-d{8}|d{4}-d{7}|d{11}$/.test(value)) {
return errorMsg;
}
}
} return {
/** 校验方法
* @param {Array} arr
* @return {*}
* */
check: function(arr) {
var ruleMsg;
var checkRule;
var _rule;
for(var i = 0, len = arr.length; i < len; i++) {
// 没有当前校验字段
if(arr[i].el === undefined) {
return '没有当前字段'
}
for(var j = 0, ruleLen = arr[i].rules.length; j < ruleLen; j++) {
var ruleObj = arr[i].rules[j];
checkRule = ruleObj.rule.split(':'); // rule规则存在minLenth:6这样的校验
_rule = checkRule.shift(); // 获取校验算法名称
checkRule.unshift(arr[i].el); // checkRule首位存入校验的value值
checkRule.push(ruleObj.message); // checkRule末尾加入校验的message
ruleMsg = rules[_rule].apply(null,checkRule);
if(ruleMsg) {
return ruleMsg;
}
}
}
}
}
})();

以上代码就是常规实现的表单验证,看似也够用了,但是如果一个系统中有多个表单提交验证,并且有部分验证方式不是那么通用,我们不可能再去修改代码中的rules,那样这个rules校验的算法越来越多,并且很多不是很通用的,那么我们怎样来解决呢?

在验证函数中增加一个添加规则算法的方法,代码如下:

var validate = (function() {
// 校验规则的各种算法
var rules = {
// 判断非空
isNonEmpty: function(value,errorMsg) {
if(!value) {
return errorMsg;
}
},
// 判断最小长度
minLength: function(value,length,errorMsg) {
if(value.toString().length < length) {
return errorMsg;
}
},
// 判断最大长度
maxLength: function(value,length,errorMsg) {
if(value.toString().length > length) {
return errorMsg;
}
},
// 判断手机号
isMobile: function(value,errorMsg) {
if (!/(^1[0-9]{10}$)/.test(value)) {
return errorMsg;
}
},
// 判断座机电话
isTel: function(value,errorMsg) {
if(!/^\d{3}-d{8}|d{4}-d{7}|d{11}$/.test(value)) {
return errorMsg;
}
}
} return {
/** 校验方法
* @param {Array} arr
* @return {*}
* */
check: function(arr) {
var ruleMsg;
var checkRule;
var _rule;
for(var i = 0, len = arr.length; i < len; i++) {
// 没有当前校验字段
if(arr[i].el === undefined) {
return '没有当前字段'
}
for(var j = 0, ruleLen = arr[i].rules.length; j < ruleLen; j++) {
var ruleObj = arr[i].rules[j];
checkRule = ruleObj.rule.split(':'); // rule规则存在minLenth:6这样的校验
_rule = checkRule.shift(); // 获取校验算法名称
checkRule.unshift(arr[i].el); // checkRule首位存入校验的value值
checkRule.push(ruleObj.message); // checkRule末尾加入校验的message
ruleMsg = rules[_rule].apply(null,checkRule);
if(ruleMsg) {
return ruleMsg;
}
}
}
}, // 添加规则
addRule: function(ruleName,fn) {
rules[ruleName] = fn;
}
}
})();

比如用户名只能是字母跟数字的组合,那么我们就添加一个规则,代码如下:

validate.addRule('isAlphaNum', function(value, errorMsg) {
if (/[^a-zA-Z0-9]/.test(value)) {
return errorMsg;
}
})

submitValidate方法的代码修改为如下:

function submitValidate() {
var registerForm = document.getElementById("registerForm");
validate.addRule('isAlphaNum', function(value, errorMsg) {
if (/[^a-zA-Z0-9]/.test(value)) {
return errorMsg;
}
})
var rulesArr = [{
el: registerForm.userName.value,
rules: [{
rule: 'isNonEmpty',
message: '用户名不能为空'
}, {
rule: 'minLength:3',
message: '用户名长度不能小于3位'
}, {
rule: 'isAlphaNum',
message: '用户名只能是数字跟字母的组合'
}]
},
{
el: registerForm.password.value,
rules: [{
rule: 'isNonEmpty',
message: '密码不能为空'
}, {
rule: 'minLength:6',
message: '密码的长度不能小于6位'
}]
},
{
el: registerForm.phoneNumber.value,
rules: [{
rule: 'isNonEmpty',
message: '手机号不能为空'
}, {
rule: 'isMobile',
message: '手机号码格式不正确'
}]
}
]
var resultMsg = validate.check(rulesArr);
if (resultMsg) {
alert(resultMsg);
return false;
}
return true;
}

运行效果如图所示:

升级方案

如果我们想实现如图这样的验证结果:

那么我们就需要保存所有元素的错误信息,那么我们新添加一个checkAll的方法,代码如下:

var validate = (function() {
// 校验规则的各种算法
var rules = {
// 判断非空
isNonEmpty: function(value, errorMsg) {
if (!value) {
return errorMsg;
}
},
// 判断最小长度
minLength: function(value, length, errorMsg) {
if (value.toString().length < length) {
return errorMsg;
}
},
// 判断最大长度
maxLength: function(value, length, errorMsg) {
if (value.toString().length > length) {
return errorMsg;
}
},
// 判断手机号
isMobile: function(value, errorMsg) {
if (!/(^1[0-9]{10}$)/.test(value)) {
return errorMsg;
}
},
// 判断座机电话
isTel: function(value, errorMsg) {
if (!/^\d{3}-d{8}|d{4}-d{7}|d{11}$/.test(value)) {
return errorMsg;
}
}
} return {
/** 校验方法
* @param {Array} arr
* @return {*}
* */
check: function(arr) {
var ruleMsg;
var checkRule;
var _rule;
for (var i = 0, len = arr.length; i < len; i++) {
// 没有当前校验字段
if (arr[i].el === undefined) {
return '没有当前字段'
}
for (var j = 0, ruleLen = arr[i].rules.length; j < ruleLen; j++) {
var ruleObj = arr[i].rules[j];
checkRule = ruleObj.rule.split(':'); // rule规则存在minLenth:6这样的校验
_rule = checkRule.shift(); // 获取校验算法名称
checkRule.unshift(arr[i].el); // checkRule首位存入校验的value值
checkRule.push(ruleObj.message); // checkRule末尾加入校验的message
ruleMsg = rules[_rule].apply(null, checkRule);
if (ruleMsg) {
return ruleMsg;
}
}
}
}, // 校验所有接口
checkAll: function(arr) {
var ruleMsg;
var checkRule;
var _rule;
var reusltMsg = [];
for (var i = 0, len = arr.length; i < len; i++) {
// 没有当前校验字段
if (arr[i].el === undefined) {
return '没有当前字段'
}
for (var j = 0, ruleLen = arr[i].rules.length; j < ruleLen; j++) {
var ruleObj = arr[i].rules[j];
checkRule = ruleObj.rule.split(':'); // rule规则存在minLenth:6这样的校验
_rule = checkRule.shift(); // 获取校验算法名称
checkRule.unshift(arr[i].el); // checkRule首位存入校验的value值
checkRule.push(ruleObj.message); // checkRule末尾加入校验的message
ruleMsg = rules[_rule].apply(null, checkRule);
if (ruleMsg) {
reusltMsg.push({
el: arr[i].el,
rules: _rule,
message: ruleMsg,
alias: arr[i].alias // 绑定一个别名用处:绑定到具体的一个DOM元素上显示错误信息
})
break; // 跳出当前循环,不用把当前一个元素上多个验证不通过结果都存储起来
}
}
}
return reusltMsg.length > 0 ? reusltMsg : false;
}, // 添加规则
addRule: function(ruleName, fn) {
rules[ruleName] = fn;
}
}
})();

我们调整下html代码:

<form action="" id="registerForm" method="post" onsubmit="return submitValidate()">
<p>
<label>请输入用户名:</label>
<input type="text" name="userName" />
<span class="error"></span>
</p>
<p>
<label>请输入密码:</label>
<input type="text" name="password" />
<span class="error"></span>
</p>
<p>
<label>请输入手机号码:</label>
<input type="text" name="phoneNumber" />
<span class="error"></span>
</p>
<div>
<button type="submit">提交</button>
</div>
</form>

css样式:

<style>
.error {
color: red;
}
</style>

submitValidate方法的代码调整为:

function submitValidate() {
var registerForm = document.getElementById("registerForm");
validate.addRule('isAlphaNum', function(value, errorMsg) {
if (/[^a-zA-Z0-9]/.test(value)) {
return errorMsg;
}
})
var rulesArr = [{
el: registerForm.userName.value,
alias: 'userName',
rules: [{
rule: 'isNonEmpty',
message: '用户名不能为空'
}, {
rule: 'minLength:3',
message: '用户名长度不能小于3位'
}, {
rule: 'isAlphaNum',
message: '用户名只能是数字跟字母的组合'
}]
},
{
el: registerForm.password.value,
alias: 'password',
rules: [{
rule: 'isNonEmpty',
message: '密码不能为空'
}, {
rule: 'minLength:6',
message: '密码的长度不能小于6位'
}]
},
{
el: registerForm.phoneNumber.value,
alias: 'phoneNumber',
rules: [{
rule: 'isNonEmpty',
message: '手机号不能为空'
}, {
rule: 'isMobile',
message: '手机号码格式不正确'
}]
}
]
var resultMsg = validate.checkAll(rulesArr);
if (resultMsg) {
for(var re = 0, len = resultMsg.length; re < len; re++) {
var curResult = resultMsg[re];
var errorDom = document.querySelector('#registerForm p [name="'+curResult.alias+'"]').nextElementSibling;
errorDom.innerHTML = curResult.message;
} return false;
}
return true;
}

这样得到的结果就是我们刚才截图的结果了。

兼容失去焦点的方案

如果想兼容失去焦点也触发后面的错误信息提示,暂写了一个草稿代码如下:

var validate = (function() {
// 校验规则的各种算法
var rules = {
// 判断非空
isNonEmpty: function(value, errorMsg) {
if (!value) {
return errorMsg;
}
},
// 判断最小长度
minLength: function(value, length, errorMsg) {
if (value.toString().length < length) {
return errorMsg;
}
},
// 判断最大长度
maxLength: function(value, length, errorMsg) {
if (value.toString().length > length) {
return errorMsg;
}
},
// 判断手机号
isMobile: function(value, errorMsg) {
if (!/(^1[0-9]{10}$)/.test(value)) {
return errorMsg;
}
},
// 判断座机电话
isTel: function(value, errorMsg) {
if (!/^\d{3}-d{8}|d{4}-d{7}|d{11}$/.test(value)) {
return errorMsg;
}
}
} return {
/** 校验方法
* @param {Object} vertifyObj 验证结构如:{userName:[{rule: 'isNonEmpty',message: '用户名不能为空'},{rule: 'minLength:3',message: '用户名长度不能小于3位'}}
* @param {Array} arr
* @return {*}
* */
check: function(vertifyObj,arr) {
var ruleMsg;
var checkRule;
var _rule;
for (var i = 0, len = arr.length; i < len; i++) {
// 没有当前校验字段
if (arr[i].el === undefined) {
return '没有当前字段'
}
for (var j = 0, ruleLen = vertifyObj[arr[i].alias].length; j < ruleLen; j++) {
var ruleObj = vertifyObj[arr[i].alias][j];
checkRule = ruleObj.rule.split(':'); // rule规则存在minLenth:6这样的校验
_rule = checkRule.shift(); // 获取校验算法名称
checkRule.unshift(arr[i].el); // checkRule首位存入校验的value值
checkRule.push(ruleObj.message); // checkRule末尾加入校验的message
ruleMsg = rules[_rule].apply(null, checkRule);
if (ruleMsg) {
return ruleMsg;
}
}
}
}, // 校验所有接口
checkAll: function(vertifyObj,arr) {
var ruleMsg;
var checkRule;
var _rule;
var reusltMsg = [];
for (var i = 0, len = arr.length; i < len; i++) {
// 没有当前校验字段
if (arr[i].el === undefined) {
return '没有当前字段'
}
for (var j = 0, ruleLen = vertifyObj[arr[i].alias].length; j < ruleLen; j++) {
var ruleObj = vertifyObj[arr[i].alias][j];
checkRule = ruleObj.rule.split(':'); // rule规则存在minLenth:6这样的校验
_rule = checkRule.shift(); // 获取校验算法名称
checkRule.unshift(arr[i].el); // checkRule首位存入校验的value值
checkRule.push(ruleObj.message); // checkRule末尾加入校验的message
ruleMsg = rules[_rule].apply(null, checkRule);
if (ruleMsg) {
reusltMsg.push({
el: arr[i].el,
rules: _rule,
message: ruleMsg,
alias: arr[i].alias // 绑定一个别名用处:绑定到具体的一个DOM元素上显示错误信息
})
break; // 跳出当前循环,不用把当前一个元素上多个验证不通过结果都存储起来
}
}
}
return reusltMsg.length > 0 ? reusltMsg : false;
}, // 用户触发验证事件
trigger: function(params) {
var self = this;
for(var key in params.rules) {
if(params.rules.hasOwnProperty(key)) {
var requireEl = document.querySelector(params.el + ' [name="'+key+'"]');
var rulesArr = params.rules[key];
var resultRules = rulesArr.filter(function(rule) {
if(!rule.trigger || rule.trigger === '') return true;
if(Array.isArray(rule.trigger)) {
return rule.trigger.indexOf('blur') > -1
} else {
return rule.trigger === 'blur';
}
}).map(function(rule){return JSON.parse(JSON.stringify(rule))}); (function(dom,curDomRules){
dom.addEventListener('blur',function(event){
var val = dom.value;
var ruleMsg = '';
for (var j = 0, ruleLen = curDomRules.length; j < ruleLen; j++) {
var ruleObj = curDomRules[j];
var checkRule = ruleObj.rule.split(':'); // rule规则存在minLenth:6这样的校验
var _rule = checkRule.shift(); // 获取校验算法名称
checkRule.unshift(val); // checkRule首位存入校验的value值
checkRule.push(ruleObj.message); // checkRule末尾加入校验的message
ruleMsg = rules[_rule].apply(null, checkRule);
if (ruleMsg) {
var errorDom = dom.nextElementSibling;
errorDom.innerHTML = ruleObj.message;
break; // 跳出当前循环,不用把当前一个元素上多个验证不通过结果都存储起来
}
}
if(!ruleMsg) {
var errorDom = dom.nextElementSibling;
errorDom.innerHTML = '';
}
},false);
})(requireEl,resultRules);
}
}
}, // 添加规则
addRule: function(ruleName, fn) {
rules[ruleName] = fn;
}
}
})(); // 添加-自定义校验算法
validate.addRule('isAlphaNum', function(value, errorMsg) {
if (/[^a-zA-Z0-9]/.test(value)) {
return errorMsg;
}
}) var rules = {
userName: [
{rule: 'isNonEmpty',message: '用户名不能为空', trigger: 'blur'},
{rule: 'minLength:3',message: '用户名长度不能小于3位', trigger: 'blur'},
{rule: 'isAlphaNum',message: '用户名只能是数字跟字母的组合', trigger: 'blur'}
],
password: [
{rule: 'isNonEmpty',message: '密码不能为空', trigger: 'blur'},
{rule: 'minLength:6',message: '密码的长度不能小于6位', trigger: 'blur'}
],
phoneNumber: [
{rule: 'isNonEmpty',message: '手机号不能为空', trigger: 'blur'},
{rule: 'isMobile',message: '手机号码格式不正确', trigger: 'blur'}
]
} validate.trigger({
el: '#registerForm',
rules: rules
}) function submitValidate() {
var registerForm = document.getElementById("registerForm");
var rulesArr = [{
el: registerForm.userName.value,
alias: 'userName'
},
{
el: registerForm.password.value,
alias: 'password'
},
{
el: registerForm.phoneNumber.value,
alias: 'phoneNumber'
}
]
var resultMsg = validate.checkAll(rules,rulesArr);
if (resultMsg) {
for(var re = 0, len = resultMsg.length; re < len; re++) {
var curResult = resultMsg[re];
var errorDom = document.querySelector('#registerForm p [name="'+curResult.alias+'"]').nextElementSibling;
errorDom.innerHTML = curResult.message;
}
return false;
}
return true;
}

html代码:

<form action="" id="registerForm" method="post" onsubmit="return submitValidate()">
<p>
<label>请输入用户名:</label>
<input type="text" name="userName" />
<span class="error"></span>
</p>
<p>
<label>请输入密码:</label>
<input type="text" name="password" />
<span class="error"></span>
</p>
<p>
<label>请输入手机号码:</label>
<input type="text" name="phoneNumber" />
<span class="error"></span>
</p>
<div>
<button type="submit">提交</button>
</div>
</form>

CSS代码:

<style>
.error {
color: red;
}
</style>

参考地址

JS常见的API扩展形式(prototype、jquery、vue插件封装)以及怎样设计出易扩展的表单验证功能?的更多相关文章

  1. jquery validate表单验证插件-推荐

    1 表单验证的准备工作 在开启长篇大论之前,首先将表单验证的效果展示给大家.     1.点击表单项,显示帮助提示 2.鼠标离开表单项时,开始校验元素  3.鼠标离开后的正确.错误提示及鼠标移入时的帮 ...

  2. jquery validate表单验证插件

    1 表单验证的准备工作 在开启长篇大论之前,首先将表单验证的效果展示给大家.     1.点击表单项,显示帮助提示 2.鼠标离开表单项时,开始校验元素  3.鼠标离开后的正确.错误提示及鼠标移入时的帮 ...

  3. jquery validate表单验证插件的基本使用方法及功能拓展

    1 表单验证的准备工作 在开启长篇大论之前,首先将表单验证的效果展示给大家.    1.点击表单项,显示帮助提示 2.鼠标离开表单项时,开始校验元素 3.鼠标离开后的正确.错误提示及鼠标移入时的帮助提 ...

  4. 如何利用jQuery进行简单表单验证

    <!DOCTYPE html><html><head><meta charset="utf-8"><meta name=&qu ...

  5. jQuery框架学习第十一天:实战jQuery表单验证及jQuery自动完成提示插件

    jQuery框架学习第一天:开始认识jQueryjQuery框架学习第二天:jQuery中万能的选择器jQuery框架学习第三天:如何管理jQuery包装集 jQuery框架学习第四天:使用jQuer ...

  6. JS简单表单验证

    这里我是写了一个简单的注册表单验证功能,亲测有效,一起来看看吧! 首先我的HTML代码是这样的: class大家可以忽略一下,这里我项目使用的是bootstrap的样式. 输入用户名和密码用的是正则表 ...

  7. Angular JS 中的内置方法之表单验证

    angular js 结合html5 可以实现强大的表单验证功能 关闭html5自带的表单验证功能可以用

  8. Jquery.validate.js表单验证插件的使用

    作为一个网站web开发人员,以前居然不知道还有表单验证这样好呀的插件,还在一行行写表单验证,真是后悔没能早点知道他们的存在. 最近公司不忙,自己学习一些东西的时候,发现了validation的一个实例 ...

  9. jquery.validation.js 表单验证

    jquery.validation.js 表单验证   官网地址:http://bassistance.de/jquery-plugins/jquery-plugin-validation jQuer ...

  10. 【js类库AngularJs】学习angularJs的指令(包括常见表单验证,隐藏等功能)

    [js类库AngularJs]学习angularJs的指令(包括常见表单验证,隐藏等功能) AngularJS诞生于2009年,由Misko Hevery 等人创建,后为Google所收购.是一款优秀 ...

随机推荐

  1. Claude是否超过Chatgpt,成为生成式AI的一哥?

    Anthropic 周一推出了 Claude 3 ,据这家初创公司称,该系列中最有能力的 Claude 3 Opus 在各种基准测试中都优于 Openai 的竞争对手 GPT-4 和谷歌的 Gemin ...

  2. 一天快速入门Django:从0到1创建属于自己的Web应用

    DjangoWeb开发 Day1 1. Django的安装 pip install django 2. 创建项目 2.1 终端创建 "python环境路径\scripts\django-ad ...

  3. 历代iPhone及Android手机的屏幕参数对比

    手机逻辑分辨率Point,也就是CSS像素,是进行网页适配的关键,以下是平时整理的一些备忘录数据,可以收藏. 屏幕清晰度分类 SD标清 HD高清(2倍屏) FHD全高清(3倍屏) QHD倍高清(4倍屏 ...

  4. Error: Dynamic require of "path" is not supported

    failed to load config from D:\BaiduSyncdisk\vue3\sys-manager\vite.config.jserror when starting dev s ...

  5. 前端太卷了,不玩了,写写node.js全栈涨工资,赶紧学起来吧!!!!!

    首先聊下node.js的优缺点和应用场景 Node.js的优点和应用场景 Node.js作为后端开发的选择具有许多优点,以下是其中一些: 高性能: Node.js采用了事件驱动.非阻塞I/O模型,使得 ...

  6. scratch源码下载 | 飞天厨师

    程序说明: <飞天厨师>是一款使用Scratch平台制作的游戏程序.在这个游戏中,玩家将控制一名厨师角色,他在天空中不断掉落.玩家需要利用方向键左右移动厨师,以便他能够准确地踩在空中的食物 ...

  7. Jmeter循环控制器

    循环控制器(Loop Controller),循环控制器会将该控制器里面所有请求循环运行指定次数 循环次数:勾选"永远"则程序会一直循环运行不会停止,不勾选"永远&quo ...

  8. 【DataBase】MySQL 11 SQL函数 单行函数其五 流程控制函数 & 单行函数总结

    SQL函数其五 流程控制函数 & 单行函数总结 视频参考自:P43 - P52 https://www.bilibili.com/video/BV1xW411u7ax  单IF函数使用 -- ...

  9. 【Layui】16 表单元素 Form

    文档地址: https://www.layui.com/demo/form.html 表单元素: 1.输入框 2.密码框 3.下拉列表 4.单选框 5.复选框 6.文档域 7.富文本 8.开关 单行输 ...

  10. 如何配置域名的 CNAME —— 添加记录集时,为什么会提示“与已有解析记录冲突”?

    参考: https://support.huaweicloud.com/dns_faq/dns_faq_016.html https://developer.qiniu.com/fusion/kb/1 ...