文章浏览 复制本页面地址

Jquery 关联绑定模型,JQ封装模型

下面对这个JQ的关联模型逐步解说

1. 看HTML, 首先在HTML上面绑定 model-node  的名称. 这是为了下面的 JS模型 做铺垫的,便于后面查找
[code]

<div id="page-wrap">
		<div class="reg-wrap">	
			<div class="reg-main">
				<!--注册步骤-->
				<form model-node="normal_form" method="POST" action="./test.php" name="ajax_register_form" id="ajax_register_form">
				<input type="hidden" name="invate" value="" />
				<input type="hidden" name="invate_key" value="" />
				<div class="article boxShadow">
					<div class="title">注册帐号</div>
										<dl class="item">
						<dd>
							<div class="form-tt"><i class="text-required">*</i>登录邮箱:</div>
							<div class="form-row" style="z-index:99">
								<input event-node="email" event-args="suffix=" name="email" checkurl="./test.php?act=isEmail" autocomplete="off" type="text" value="" />
							</div>
						</dd>
						<dd>
							<div class="form-tt"><i class="text-required">*</i>登录密码:</div>
							<div class="form-row psd">
                            	<div style="overflow:hidden;*zoom:1">
                                    <input event-node="password" name="password" type="password" value=""/>
                                    <div model-node="password_weight" class="psw-state-empty">
                                        <div class="progress progress-green-transition"><div class="bar"></div></div>
                                        <div class="txt"><span>弱</span><span>中</span><span>强</span></div>
                                    </div>
                                </div>
                                <div class="txt-info">密码由字母,数字,符号组成,6-15个字符,区分大小写</div>
							</div>
						</dd>
						<dd>
							<div class="form-tt"><i class="text-required">*</i>确认密码:</div>
							<div class="form-row">
								<input event-node="repassword" name="repassword" type="password" />
							</div>
						</dd>
						<dd>
							<div class="form-tt"><i class="text-required">*</i>昵称:</div>
							<div class="form-row">
								<div style="overflow:hidden;*zoom:1">
                                <input event-node="uname" name="uname" checkurl="http://myadminsystem.com/index.php?app=public&mod=Register&act=isUnameAvailable" autocomplete="off" type="text" value="" />
                                </div>
								<div event-node="uname_tips" class="txt-info">昵称长度为2-10个汉字,仅支持中英文,数字,下划线,不允许重名。</div>
							</div>
						</dd>
						<dd>
							<div class="form-tt"><i class="text-required">*</i>性别:</div>
							<div class="form-row">
								<label><input name="sex" type="radio" class="s-radio" value="1" checked="checked" event-node="radio" event-args="error=请选择性别" />男</label>
								<label><input event-node="radio" type="radio" name="sex" value="2" class="s-radio"  />女</label>
							</div>
						</dd>
						<dd>
							<div class="form-tt"><i class="text-required">*</i>地区:</div>

[/code]

2、jquery-1.7.js (网上自己下载) ,

这里是 model.js 的JS 代码

[code type='javascript']

/****************************************************
*                                                     *
*             Sociax HTML 标签关联模型              *
*                                                  *
****************************************************/

/**
* HTML 标签关联模型
* @model-node 模型节点的标签属性标记
* @event-node 模型下事件节点的标签属性标记
* @author _慢节奏
*/
(function(window) {

var document = window.document;

/**
* 激活模型
*
* @param node 元素节点
* @param node 父模型节点,若为空则将node 作为父模型节点
* @param fns  挂载到标签上的事件方法,格式说明如下:
* {
*     model: {
*         method1 : {
*                click     : function(){},
*                mouseover : function(){},
*               mouseout  : function(){},
*                load      : function(){}
*            },
*            method2 : {
*             blur   : function(){},
*             focus  : function(){},
*             submit : function(){}
*            }
*     },
*     event: {
*         method1 : {
*                click     : function(){},
*                mouseover : function(){},
*               mouseout  : function(){},
*                load      : function(){}
*            },
*            method2 : {
*             blur   : function(){},
*             focus  : function(){},
*             submit : function(){}
*            }
*     }
* }
*/
var module = function( node, fns ) {
module.addFns(fns);
if ( node ) {
// 预清除,防止重复模型化引起的双重缓存
module.nodes.init( node );
}
};

/**
* 保存事件的方法
*
* @param fns  挂载到标签上的事件方法,格式说明同module 函数的fns 参数
*/
module.addFns = function( fns ) {
if ( !fns ) return module;
if ( fns.model ) {
module.addModelFns( fns.model );
}
if ( fns.event ) {
module.addEventFns( fns.event );
}
return module;
};

/**
* 保存模型事件的方法
*
* @param fns  挂载到模型上的事件方法,格式说明如下:
* {
*     method1 : {
*         click     : function(){},
*         mouseover : function(){},
*         mouseout  : function(){},
*         load      : function(){}
*     },
*     method2 : {
*         blur   : function(){},
*         focus  : function(){},
*         submit : function(){}
*     }
* }
*/
module.addModelFns = function( fns ) {
if ( "object" != typeof fns ) return module;
var name;
for ( name in fns ) {
module.nodes.models.fns[name] = fns[name];
}
return module;
};

/**
* 保存模型下事件节点的方法
*
* @param fns  挂载到模型上的事件方法,属性说明同module.addModelFns 的fns 参数
*/
module.addEventFns = function( fns ) {
if ( "object" != typeof fns ) return module;
var name;
for ( name in fns ) {
module.nodes.events.fns[name] = fns[name];
}
return module;
};

/**
* 获取节点的参数
*
* @param node 模型/事件节点
*/
module.getArgs = function( node ) {
return node.getAttribute( "model-node" ) ? module.getModelArgs( node ) : module.getEventArgs( node );
};

/**
* 设置节点的参数
*
* @param node 模型/事件节点
* @param uri URI 格式的参数
*/
module.setArgs = function( node, uri ) {
return node.getAttribute( "model-node" ) ? module.setModelArgs( node, uri ) : module.setEventArgs( node, uri );
};

/**
* 获取模型节点的参数
*
* @param node 模型节点
*/
module.getModelArgs = function( node, uri ) {
node.args || ( node.args = module.URI2Obj( node.getAttribute( "model-args" ) ) );
return node.args;
};

/**
* 设置模型节点的参数
*
* @param node 模型节点
*/
module.setModelArgs = function( node, uri ) {
node.args = undefined;
node.setAttribute( "model-args", uri );
return module;
};

/**
* 获取事件节点的参数
*
* @param node 事件节点
*/
module.getEventArgs = function( node ) {
node.args || ( node.args = module.URI2Obj( node.getAttribute( "event-args" ) ) );
return node.args;
};

/**
* 设置事件节点的参数
*
* @param node 事件节点
*/
module.setEventArgs = function( node, uri ) {
node.args = undefined;
node.setAttribute( "event-args", uri );
return module;
};

/**
* 将uri转换为对象格式
*
* @param uri URI 格式的数据
*/
module.URI2Obj = function( uri ) {
if ( ! uri ) return {};
var obj = {},
args = uri.split( "&" ),
l, arg;
l = args.length;
while ( l -- > 0 ) {
arg = args[l];
if ( ! arg ) {
continue;
}
arg = arg.split( "=" );
obj[arg[0]] = arg[1];
}
return obj;
};

/**
* 获取全局内指定的模型节点
*
* @param name 模型节点的命名
*/
module.getModels = function( name ) {
return module.nodes.models[name];
};

/**
* 获取全局内指定的事件节点
*
* @param name 事件节点的命名
*/
module.getEvents = function( name ) {
return module.nodes.events[name];
}

/**
* 删除节点上的监听
*
* @param object node 节点对象
*/
module.removeListener = function( node ) {
module.nodes.removeListener( node );
return module;
};

/**
* 为节点添加监听
*
* @param object node 节点对象
* @param object events 监听的事件
* {
*     click     : function(){},
*     mouseover : function(){},
*     mouseout  : function(){}
* }
*/
module.addListener = function( node, events ) {
module.nodes.addListener( node, events );
return module;
};

module.getPreviousModel = function( node, siblingName ) {
return module.nodes.getPreviousModel( node, siblingName );
};

module.getNextModel = function( node, siblingName ) {
return module.nodes.getNextModel( node, siblingName );
};

module.getPreviousEvent = function( node, siblingName ) {
return module.nodes.getPreviousEvent( node, siblingName );
};

module.getNextEvent = function( node, siblingName ) {
return module.nodes.getNextEvent( node, siblingName );
};

/**
* 模型化节点对象
*
* @property function init 初始化模型
* @property function _init 逐级扫描指定节点下的各级子元素的模型结构,并缓存模型和事件的DOM对象
* @property function clear 清楚元素节点的子模型节点和子事件节点合集对象
* @property function getParentModel
* @property function addListener 为模型和事件节点附加事件方法
* @property object _onload 自定义onload 事件
* @property object _onload.execute 执行onload 事件队列
* @property object _onload.queue onload 事件队列
* @property object models 罗列并缓存模型节点
* @property object events 罗列并缓存事件节点
* @property object models.fns 存放模型节点的事件方法
* @property object events.fns 存放事件节点的事件方法
*/
module.nodes = {
init: function( node ) {
// 初始化模型
this._init( node );
// 执行onload 事件
this._onload.execute();
return this;
},
_init: function( node, parentModel ) {
var childNode = node.firstChild,
childParentModel,
model_name,
event_name;

! parentModel && ( parentModel = this.getParentModel( node ) );

switch ( node.nodeName ) {
case "DIV": case "UL":case "DL":
case "FORM":case "LI":case "DD":
model_name = node.getAttribute( "model-node" );
if ( model_name ) {
this._clearModel( node );

node.modelName = model_name;

this.addListener( node, this.models.fns[model_name] );

node.parentModel = parentModel;

( parentModel.childModels[model_name] = parentModel.childModels[model_name] || [] ).push( node );

( this.models[model_name] = this.models[model_name] || [] ).push( node );

childParentModel = node;
}
break;
case "A": case "SPAN": case "LABEL":
case "STRONG": case "INPUT": case "SELECT":
case "BUTTON": case "IMG": case "TEXTAREA":
case "H1": case "H2": case "H3": case "H4":case "I":
event_name = node.getAttribute( "event-node" );
if ( event_name ) {
this._clearEvent(node);

node.eventName = event_name;

this.addListener( node, this.events.fns[event_name] );

node.parentModel = parentModel;
( parentModel.childEvents[event_name] = parentModel.childEvents[event_name] || [] ).push( node );

( this.events[event_name] = this.events[event_name] || [] ).push( node );
}
break;
case "HEAD": case "BODY":
this[node.nodeName.toLowerCase()] = node;
break;
case "#document":
this._clearModel(node);
break;
}

! childParentModel && ( childParentModel = parentModel );
while ( childNode ) {
(1 == childNode.nodeType ) && this._init( childNode, childParentModel );
childNode = childNode.nextSibling;
}
},
_clearModel: function( node ) {
node.modelName   = undefined;
node.parentModel = undefined;
node.childModels = {};
node.childEvents = {};
node.args = undefined;
return this;
},
_clearEvent: function( node ) {
node.eventName   = undefined;
node.parentModel = undefined;
node.args = undefined;
return this;
},
getParentModel: function( node ) {
var parentNode = node.parentNode,
parentModel;
if ( parentNode && 1 === parentNode.nodeType ) {
parentModel = parentNode.getAttribute('model-node') ? parentNode : this.getParentModel( parentNode );
}
return parentModel || document;
},
getPreviousModel: function( node, siblingName ) {
return this._getSiblingNode( node, { siblingType: "model", siblingName: siblingName }, "previous" );
},
getNextModel: function( node, siblingName ) {
return this._getSiblingNode( node, { siblingType: "model", siblingName: siblingName }, "next" );
},
getPreviousEvent: function( node, siblingName ) {
return this._getSiblingNode( node, { siblingType: "event", siblingName: siblingName }, "previous" );
},
getNextEvent: function( node, siblingName ) {
return this._getSiblingNode( node, { siblingType: "event", siblingName: siblingName }, "next" );
},
_getSiblingNode: function( node, siblingArgs, direction ) {
var sibling;
if ( !node ) return null;
sibling = node[ [ direction, "Sibling" ].join("") ];
return ( sibling && ( siblingArgs.siblingName === sibling[ [ siblingArgs.siblingType, "Name" ].join("") ] ) ) ? sibling : this._getSiblingNode( sibling, siblingArgs, direction );
},
addListener: function( node, events ) {
if ( "object" == typeof events ) {
var event;
for ( event in events ) {
switch ( event ) {
case "load":
node[event] = events[event];
// 添加到队列
this._onload.queue.push( node );
break;
case "callback":
node[event] = events[event];
break;
case "mouseenter": case "mouseleave":
// 兼容非IE
if ( document.addEventListener ) {
var refer = {mouseenter: "mouseover", mouseleave: "mouseout"};
node["on" + refer[event]] = (function( event, fn ){
return function( e ) {
// 上一响应mouseover/mouseout 事件的元素
var parent = e.relatedTarget;
// 假如存在这个元素并且这个元素不等于目标元素
while( parent && parent != this ){
try {
//上一响应的元素开始往上寻找目标元素
parent = parent.parentNode;
} catch( e ) {
break;
}

}
// 假如找不到,表明当前事件触发点不在目标元素内
if ( parent != this ) {
//运行目标方法,否则不运行
node[event] = fn;
node[event]();
}
};
})( event, events[event] );
} else {
node["on" + event] = events[event];
}
break;
default :
node["on" + event] = events[event];
}
}
}
},
removeListener: function( node ) {
node.onclick = node.onfocus = node.onblur = node.onmouseout
= node.onmouseover = node.onmouseenter = node.onmouserleave
= node.onchange = null;
return this;
},
_onload: {
execute: function() {
var l = this.queue.length,
i;
for ( i = 0; i < l; i ++ ) {

this.queue[i]["load"]();
this.queue[i]["load"] = undefined;

}
// 重置队列
this.queue = [];
},
queue: []
},
models: {
fns: {

}
},
events: {
fns: {
}
},
getHead: function() {
this.head || (this.head = document.getElementsByTagName("head")[0]);
return this.head;
},
getBody: function() {
this.body || (this.body = document.getElementsByTagName("body")[0]);
return this.body;
}
};

/**
* 加载CSS 文件
*
* @param string url CSS 文件URL
*/
module.getCSS = (function() {
var temp = [];
//返回内部包函数,供外部调用并可以更改temp的值
return function( url ){
var    head = module.nodes.getHead(),
flag = 0,
link,
i = temp.length - 1;
// 第二次调用的时候就不=0了
for ( ; i >= 0; i -- ) {
flag = ( temp[i] == url ) ? 1 : 0;
}

if ( flag == 0 ) {
// 未载入过
link  = document.createElement( "link" );
link.setAttribute( "rel", "stylesheet" );
link.setAttribute( "type", "text/css" );
link.setAttribute( "href", url );
head.appendChild( link );
temp.push( url );
}
};
})();

/**
* 加载js 文件
*
* @param string url js 文件URL
* @param function fn 执行函数
*/
module.getJS = (function() {
var temp = [];
//返回内部包函数,供外部调用并可以更改temp的值
return function( url, fn ){
// 第二次调用的时候就不=0了
var    head,
script,
onload,
flag = 0,
i = temp.length - 1;
// 第二次调用的时候就不=0了
for ( ; i >= 0; i -- ) {
flag = ( temp[i] == url ) ? 1 : 0;
}

if ( flag == 0 ) {
// 未载入过
// 记录url
temp.push( url );
// 载入
head = module.nodes.getHead();
script = document.createElement( "script" );
script.setAttribute( "src", url );

if ( "function" == typeof fn ) {
script.onload = script.onreadystatechange = function() {
// FF 下没有readyState 值,IE 有readyState 值,需加以判断
if( ! this.readyState || "loaded" == this.readyState || "complete" == this.readyState ) {
this.onload = this.onreadystatechange = null;

fn();

fn = undefined;

script = undefined;
}
};
}

head.appendChild( script );
} else {
if("function" == typeof fn){
fn();
fn = undefined;
}
}
};
})();

/**
* Execute functions when the DOM is ready
*
* @param function fn 格式的数据
*/
module.ready = function( fn ) {
if ( "function" !== typeof fn ) {
return;
}

if ( document.addEventListener ) {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", fn, false );
// If IE event model is used
} else if ( document.attachEvent ) {
// maybe late but safe also for iframes
document.attachEvent( "onreadystatechange", fn );
}
};
//初始化M
window.M = module;

M.ready(function() {
    M(document);
});

})(window);

[/code]

3、这里是 model-form.js 的代码

[code type='javascript']

/**
* 异步提交表单
* @param object form 表单DOM对象
* @return void
*/
var ajaxSubmit = function(form) {
var args = M.getModelArgs(form);
M.getJS(THEME_URL + '/js/jquery.form.js', function() {
var options = {
dataType: "json",
success: function(txt) {
if(1 == txt.status) {
if("function" ===  typeof form.callback) {
form.callback(txt);
} else {
if("string" == typeof(args.callback)) {
eval(args.callback+'()');
} else {
ui.success(txt.info);
}
}
} else {
ui.error(txt.info);
}
}
};
$(form).ajaxSubmit(options);
});
};

(function(){
// 是否点击了发送按钮
var isSubmit = 0;
// 块状模型监听
M.addModelFns({
account_save:{
callback:function(){
ui.success(L('PUBLIC_ADMIN_OPRETING_SUCCESS'));
setTimeout(function() {
location.href = location.href;
}, 1500);
}
},
verify_apply:{
callback:function(){
ui.success('申请成功,请等待审核');
setTimeout(function() {
location.href = U('public/Account/authenticate');
}, 1500);
}
},
// 普通表单发送验证 ,匹配静态页面里面的 节点。
 normal_form: {
submit: function() {
isSubmit = 1;
var oCollection = this.elements;
var nL = oCollection.length;
var bValid = true;
var dFirstError;

for(var i = 0; i < nL; i++) {
var dInput = oCollection[i];
var sName = dInput.name;
// 如果没有事件节点,则直接略过检查
if(!sName || !dInput.getAttribute("event-node")) {
continue;
}

("function" === typeof(dInput.onblur)) && dInput.onblur();

if(!dInput.bIsValid) {
bValid = false;
if(dInput.type != 'hidden') {
dFirstError = dFirstError || dInput;
}
}
}

dFirstError && dFirstError.focus();
setTimeout(function() {
isSubmit = 0;
}, 1500);

return bValid;
}
}
});
// 事件模型监听,调用 model.js 绑定坚挺方法
M.addEventFns({
// 文本框输入文本验证
input_text: {
focus: function() {
this.className='s-txt-focus';
return false;
},
blur: function() {
this.className = 's-txt';
// 设置文本框的最大与最小输入限制
var oArgs = M.getEventArgs( this );
var    min = oArgs.min ? parseInt( oArgs.min ) : 0;
var    max = oArgs.max ? parseInt( oArgs.max ) : 0;
// 最大和最小长度均小于或等于0,则不进行长度验证
if(min <= 0 && max <= 0) {
return false;
}

var dTips = (this.parentModel.childEvents[this.getAttribute( "name" ) + "_tips"] || [])[0];
var sValue = this.value;
sValue = sValue.replace(/(^\s*)|(\s*$)/g, "");
var nL = sValue.replace(/[^\x00-\xff]/ig,'xx').length / 2;

if(nL <= min-1 || ( max && nL > max)) {
dTips && (dTips.style.display = "none");
tips.error(this, oArgs.error);
this.bIsValid = false;
} else {
tips.success(this);
dTips && (dTips.style.display = "");
this.bIsValid = true;
}
return false;
},
load: function() {
this.className='s-txt';
}
},
// 文本框输入纯数字文本验证
input_nums: {
focus: function() {
this.className = 's-txt-focus';
return false;
},
blur: function() {
this.className = 's-txt';
// 设置文本框的最大与最小输入限制
var oArgs = M.getEventArgs(this);
var min = oArgs.min ? parseInt( oArgs.min ) : 0;
var max = oArgs.max ? parseInt( oArgs.max ) : 0;
// 最大和最小长度均小于或等于0,则不进行长度验证
if(min <= 0 && max <= 0) {
return false;
}

var dTips = (this.parentModel.childEvents[this.getAttribute( "name" ) + "_tips"] || [])[0];
var sValue = this.value;

// 纯数字验证
var re = /^[0-9]*$/;
if(!re.test(sValue)) {
dTips && (dTips.style.display = "none");
tips.error(this, L('PUBLIC_TYPE_ISNOT'));        // 格式不正确
this.bIsValid = false;
return false;
}

sValue = sValue.replace(/(^\s*)|(\s*$)/g, "");
var nL = sValue.replace(/[^\x00-\xff]/ig, 'xx').length / 2;

if(nL <= min-1 || (max && nL > max)) {
dTips && (dTips.style.display = "none");
tips.error(this, oArgs.error);
this.bIsValid = false;
} else {
tips.success(this);
dTips && (dTips.style.display = "");
this.bIsValid = true;
}

return false;
},
load: function() {
this.className = 's-txt';
}
},
// 文本域验证
textarea: {
focus: function() {
this.className = 's-textarea-focus';
},
blur: function() {
this.className = 's-textarea';
// 设置文本框的最大与最小输入限制
var oArgs = M.getEventArgs(this);
var min = oArgs.min ? parseInt( oArgs.min ) : 0;
var max = oArgs.max ? parseInt( oArgs.max ) : 0;
// 最大和最小长度均小于或等于0,则不进行长度验证
if(min <= 0 && max <= 0) {
return false;
}

if($.trim(this.value)) {
tips.success(this);
this.bIsValid = true;
} else {
if("undefined" != typeof(oArgs.error )) {
tips.error(this, oArgs.error);
this.bIsValid = false;
}
}
},
load: function() {
this.className = 's-textarea';
}
},
// 部门信息验证
input_department: {
blur: function() {
var sValue = this.value;
sValue && (sValue = parseInt(sValue));

var dLastEmlement = this.nextSibling;
(1 !== dLastEmlement.nodeType) && (dLastEmlement = dLastEmlement.nextSibling);
if(sValue) {
tips.success(dLastEmlement);
this.bIsValid = true;
} else {
tips.error(dLastEmlement, L('PUBLIC_SELECT_DEPARTMENT'));
this.bIsValid = false;
}
},
load:function(){
if("undefined" != typeof(core.department)) {
delete core.department;
}
core.plugInit('department', $(this), $(this));
}
},
input_verify: {
focus: function() {
this.className='s-txt-focus';
return false;
},
blur: function() {
this.className='s-txt';

var dVerify = this;
var sUrl = dVerify.getAttribute('checkurl');
var sValue = dVerify.value;
var oArgs = M.getEventArgs(dVerify);

if(!sUrl || (this.dSuggest && this.dSuggest.isEnter)) return;

$.post(sUrl, {verify:sValue}, function(oTxt) {
if(oTxt.status) {
'false' == oArgs.success ? tips.clear(dVerify) : tips.success(dVerify);
dVerify.bIsValid = true;
} else {
'false' == oArgs.error ? tips.clear(dVerify) : tips.error(dVerify, oTxt.info);
dVerify.bIsValid = false;
}
return true;
}, 'json');
$(this.dTips).hide();
},
load: function() {
this.className='s-txt';
}
},
// 地区信息验证
input_area: {
blur: function() {
// 获取数据
var sValue = $.trim(this.value);
var sValueArr = sValue.split(",");
// 验证数据正确性
if(sValue == "" || sValueArr[0] == 0) {
tips.error(this, "请选择地区");
this.bIsValid = false;
this.value = '0,0,0';
} else if(sValueArr[1] == 0 || sValueArr[2] == 0) {
tips.error(this, "请选择完整地区信息");
this.bIsValid = false;
} else {
tips.success(this);
this.bIsValid = true;
}
},
load: function() {
// 获取参数信息
var _this = this;
// 验证数据正确性
setInterval(function() {
// 获取数据
var sValue = $.trim(_this.value);
var sValueArr = sValue.split(",");
// 验证数据正确性
if(sValue == "" || sValueArr[0] == 0) {
tips.error(_this, "请选择地区");
_this.bIsValid = false;
} else if(sValueArr[1] == 0 || sValueArr[2] == 0) {
tips.error(_this, "请选择完整地区信息");
_this.bIsValid = false;
} else {
tips.success(_this);
_this.bIsValid = true;
}
}, 200);
}
},
// 时间格式验证
input_date: {
focus: function() {
this.className = 's-txt-focus';

var dDate = this;
var oArgs = M.getEventArgs(this);

M.getJS(THEME_URL + '/js/rcalendar.js', function() {
rcalendar(dDate, oArgs.mode);
});
},
blur: function() {
this.className = 's-txt';

var dTips = (this.parentModel.childEvents[this.getAttribute( "name" ) + "_tips"] || [])[0];
var oArgs = M.getEventArgs(this);
if(oArgs.min == 0) {
return true;
}
var _this = this;
setTimeout(function() {
sValue = _this.value;
if(!sValue) {
dTips && (dTips.style.display = "none");
tips.error(_this, oArgs.error);
this.bIsValid = false;
} else {
tips.success(_this);
dTips && (dTips.style.display = "");
_this.bIsValid = true;
}
}, 250);
},
load: function() {
this.className = 's-txt';
}
},
// 邮箱验证,跟html 里面定义的 node 匹配
 email: {
focus: function() {
this.className = 's-txt-focus';
var x = $(this).offset();
$(this.dTips).css({'position':'absolute','left':x.left+'px','top':x.top+$(this).height()+12+'px','width':$(this).width()+10+'px'});
},
blur: function() {
this.className = 's-txt';

var dEmail = this;
var sUrl = dEmail.getAttribute("checkurl");
var sValue = dEmail.value;

if(!sUrl || (this.dSuggest && this.dSuggest.isEnter)) {
return false;
}

$.post(sUrl, {email:sValue}, function(oTxt) {
var oArgs = M.getEventArgs(dEmail);
if(oTxt.status) {
"false" == oArgs.success ? tips.clear( dEmail ) : tips.success( dEmail );
dEmail.bIsValid = true;
} else {
"false" == oArgs.error ? tips.clear( dEmail ) : tips.error( dEmail, oTxt.info );
dEmail.bIsValid = false;
}
return true;
}, 'json');
$(this.dTips).hide();
},
load: function() {
this.className = 's-txt';

var dEmail = this;
var oArgs = M.getEventArgs(this);

if(!oArgs.suffix) {
return false;
}

var aSuffix = oArgs.suffix.split( "," );
var dFrag = document.createDocumentFragment();
var dTips = document.createElement( "div" );
var dUl = document.createElement( "ul" );

this.dTips = $(dTips);
$('body').append(this.dTips);

dTips.className = "mod-at-wrap";
dDiv = dTips.appendChild(dTips.cloneNode(false));
dDiv.className = "mod-at";
dDiv = dDiv.appendChild(dTips.cloneNode(false));
dDiv.className = "mod-at-list";
dUl = dDiv.appendChild(dUl);
dUl.className = "at-user-list";
dTips.style.display = "none";
dEmail.parentNode.appendChild(dFrag);

M.addListener(dTips, {
mouseenter: function() {
this.isEnter = 1;
},
mouseleave: function() {
this.isEnter = 0;
}
});

// 附加到Input DOM 上
dEmail.dSuggest = dTips;

setInterval(function() {
var sValue = dEmail.value;
var sTips = dEmail.dSuggest;
if(dEmail.sCacheValue === sValue) {
return false;
} else {
// 缓存值
dEmail.sCacheValue = sValue;
}
// 空值判断
if(!sValue) {
dTips.style.display = "none";
return ;
}
var aValue = sValue.split("@");
var dFrag = document.createDocumentFragment();
var l = aSuffix.length;
var sSuffix;

sInputSuffix = ["@",aValue[1]].join(""); // 用户输入的邮箱的后缀

for(var i = 0; i < l; i ++) {
sSuffix = aSuffix[i];
if(aValue[1] && ( "" != aValue[1] ) && (sSuffix.indexOf(aValue[1]) !== 1 ) || (sSuffix === sInputSuffix)) {
continue;
}
var dLi = dLi ? dLi.cloneNode(false) : document.createElement("li");
var dA = dA ? dA.cloneNode(false) : document.createElement("a");
var dSpan = dSpan ? dSpan.cloneNode(false) : document.createElement("span");
var dText = dText ? dText.cloneNode(false) : document.createTextNode("");

dText.nodeValue = [aValue[0], sSuffix].join("");

dSpan.appendChild(dText);

dA.appendChild(dSpan);

dLi.appendChild(dA);

dLi.onclick = (function(dInput, sValue, sSuffix) {
return function(e) {
dInput.value = [ sValue, sSuffix ].join( "" );
// 选择完毕,状态为离开选择下拉条
dTips.isEnter = 0;
// 自动验证
dInput.onblur();
return false;
};
})(dEmail, aValue[0], sSuffix);

dFrag.appendChild(dLi);
}
if(dLi) {
dUl.innerHTML = "";
dUl.appendChild( dFrag );
dTips.style.display = "";
$(dUl).find('li').hover(function() {
$(this).addClass('hover');
},function() {
$(this).removeClass('hover');
});

} else {
dTips.style.display = "none";
}
}, 200);
}
},
// 密码验证
password: {
focus: function() {
this.className = 's-txt-focus';
},
blur: function() {
this.className = 's-txt';
var dWeight = this.parentModel.childModels["password_weight"][0];
var sValue = this.value + "";
var nL = sValue.length;
var min = 6
var max = 15;
if ( nL < min ) {
dWeight.style.display = "none";
tips.error( this, L('PUBLIC_PASSWORD_TIPES_MIN',{'sum':min}));
this.bIsValid = false;
} else if ( nL > max ) {
dWeight.style.display = "none";
tips.error( this, L('PUBLIC_PASSWORD_TIPES_MAX',{'sum':max}) );
this.bIsValid = false;
} else {
tips.clear( this );
dWeight.style.display = "";
this.bIsValid = true;
this.parentModel.childEvents["repassword"][0].onblur();
}
},
keyup:function(){
this.value = this.value.replace(/^\s+|\s+$/g,"");
},
load: function() {
this.value = '';
this.className='s-txt';

var dPwd = this,
dWeight = this.parentModel.childModels["password_weight"][0],
aLevel = [ "psw-state-empty", "psw-state-poor", "psw-state-normal", "psw-state-strong" ];

setInterval( function() {
var sValue = dPwd.value;
// 缓存值
if ( dPwd.sCacheValue === sValue ) {
return ;
} else {
dPwd.sCacheValue = sValue;
}
// 空值判断
if ( ! sValue ) {
dWeight.className = aLevel[0];
dWeight.setAttribute('className',aLevel[0]);
return ;
}
var nL = sValue.length;

if ( nL < 6 ) {
dWeight.className = aLevel[0];
dWeight.setAttribute('className',aLevel[0]);
return ;
}

var nLFactor = Math.floor( nL / 10 ) ? 1 : 0;
var nMixFactor = 0;

sValue.match( /[a-zA-Z]+/ ) && nMixFactor ++;
sValue.match( /[0-9]+/ ) && nMixFactor ++;
sValue.match( /[^a-zA-Z0-9]+/ ) && nMixFactor ++;
nMixFactor > 1 && nMixFactor --;

dWeight.className = aLevel[nLFactor + nMixFactor];
dWeight.setAttribute('className',aLevel[nLFactor + nMixFactor]);

}, 200 );
}
},
repassword: {
focus: function() {
this.className='s-txt-focus';
},
keyup:function(){
this.value = this.value.replace(/^\s+|\s+$/g,"");
},
blur: function() {
this.className='s-txt';

var sPwd = this.parentModel.childEvents["password"][0].value,
sRePwd = this.value;

if ( ! sRePwd ) {
tips.error( this, L('PUBLIC_PLEASE_PASSWORD_ON') );
this.bIsValid = false;
} else if ( sPwd !== sRePwd ) {
tips.error( this, L('PUBLIC_PASSWORD_ISDUBLE_NOT') );
this.bIsValid = false;
} else {
tips.success( this );
this.bIsValid = true;
}
},
load: function() {
this.className='s-txt';
}
},
// 昵称验证
uname: {
focus: function() {
this.className='s-txt-focus';
return false;
},
blur: function() {
this.className='s-txt';

var dUname = this;
var sUrl = dUname.getAttribute('checkurl');
var sValue = dUname.value;
var oArgs = M.getEventArgs(dUname);
var oValue = oArgs.old_name;

if(!sUrl || (this.dSuggest && this.dSuggest.isEnter)) return;

$.post(sUrl, {uname:sValue, old_name:oValue}, function(oTxt) {
if(oTxt.status) {
'false' == oArgs.success ? tips.clear(dUname) : tips.success(dUname);
dUname.bIsValid = true;
} else {
'false' == oArgs.error ? tips.clear(dUname) : tips.error(dUname, oTxt.info);
dUname.bIsValid = false;
}
return true;
}, 'json');
$(this.dTips).hide();
},
load: function() {
this.className='s-txt';
}
},
radio: {
click: function() {
this.onblur();
},
blur: function() {
var sName  = this.name,
oRadio = this.parentModel.elements["sex"],
oArgs  = M.getEventArgs( oRadio[0] ),
dRadio, nL = oRadio.length, bIsValid = false,
dLastRadio = oRadio[nL - 1];

for ( var i = 0; i < nL; i ++ ) {
dRadio = oRadio[i];
if ( dRadio.checked ) {
bIsValid = true;
break;
}
}

if ( bIsValid ) {
tips.clear( dLastRadio.parentNode );
} else {
tips.error( dLastRadio.parentNode, oArgs.error );
}

for ( var i = 0; i < nL; i ++ ) {
oRadio[i].bIsValid = bIsValid;
}
}
},
checkbox: {
click: function() {
this.onblur();
},
blur: function() {
var oArgs = M.getEventArgs( this );
if ( this.checked ) {
tips.clear( this.parentNode );
this.bIsValid = true;
} else {
tips.error( this.parentNode, oArgs.error );
this.bIsValid = false;
}
}
},
submit_btn: {
click: function(){
var args  = M.getEventArgs(this);
if ( args.info && ! confirm( args.info )) {
return false;
}
try{
(function( node ) {
var parent = node.parentNode;
// 判断node 类型,防止意外循环
if ( "FORM" === parent.nodeName ) {
if ( "false" === args.ajax ) {
( ( "function" !== typeof parent.onsubmit ) || ( false !== parent.onsubmit() ) ) && parent.submit();
} else {
ajaxSubmit( parent );
}
} else if ( 1 === parent.nodeType ) {
arguments.callee( parent );
}
})(this);
}catch(e){
return true;
}
return false;
}
},
sendBtn: {
click: function() {
var parent = this.parentModel;
return false;
}
}
});
/**
* 提示语Js对象
*/
var tips = {
/**
* 初始化,正确与错误提示
* @param object D DOM对象
* @return void
*/
init: function(D) {
this._initError(D);
this._initSuccess(D);
},
/**
* 调用错误接口
* @param object D DOM对象
* @param string txt 显示内容
* @return void
*/
error: function(D, txt) {
this.init(D);
if($(D).val() == '' && isSubmit != 1) {
D.dError.style.display = "none";
D.dSuccess.style.display = "none";
} else {
D.dSuccess.style.display = "none";
D.dError.style.display = "";
D.dErrorText.nodeValue = txt;
}
},
/**
* 调用成功接口
* @param object D DOM对象
* @return void
*/
success: function(D) {
this.init(D);
D.dError.style.display = "none";
D.dSuccess.style.display = "";
},
/**
* 清除提示接口
* @param object D DOM对象
* @return void
*/
clear: function(D) {
this.init(D);
D.dError.style.display = "none";
D.dSuccess.style.display = "none";
},
/**
* 初始化错误对象
* @param object D DOM对象
* @return void
* @private
*/
_initError: function(D) {
if (!D.dError || !D.dErrorText) {
// 创建DOM结构
var dFrag = document.createDocumentFragment();
var dText = document.createTextNode("");
var dB = document.createElement("b");
var dSpan = document.createElement("span");
var dDiv = document.createElement("div");
// 组装HTML结构 - DIV
D.dError = dFrag.appendChild(dDiv);
dDiv.className = "box-ver";
dDiv.style.display = "none";
// 组装HTML结构 - SPAN
dDiv.appendChild( dSpan );
// 组装HTML结构 - B
dSpan.appendChild( dB );
dB.className = "ico-error";
D.dErrorText = dSpan.appendChild(dText);
// 插入HTML
var dParent = D.parentNode;
var dNext = D.nextSibling;
if(dNext) {
dParent.insertBefore(dFrag, dNext);
} else {
dParent.appendChild(dFrag);
}
}
},
/**
* 初始化成功对象
* @param object D DOM对象
* @return void
* @private
*/
_initSuccess: function(D) {
if(!D.dSuccess) {
// 创建DOM结构
var dFrag = document.createDocumentFragment();
var dSpan = document.createElement("span");
// 组装HTML结构 - SPAN
D.dSuccess = dFrag.appendChild(dSpan);
dSpan.className = "ico-ok";
dSpan.style.display = "none";
// 插入HTML
var dParent = D.parentNode;
var dNext = D.nextSibling;
if(dNext) {
dParent.insertBefore(dFrag, dNext);
} else {
dParent.appendChild(dFrag);
}
}
}
};
// 定义Window属性
window.tips = tips;
})();

[/code]

标签:
上一篇:
下一篇: