Ajax三十六技 - 瞒天过海

转载请声明出处:http://janpoem.cnblogs.com
Ajax在国内十分流行,到今天,基本上没有那个网站不使用Ajax了。利用现成的开源框架,或者自己稍微动手写一个Ajax的接口,都能很随意的实现Ajax。然后目前市面上所能见到的大多数的Ajax,实现到何种程度,是不是足够灵活,仍有待商榷。Ajax三十六"技",旨在讨论其设计模式和实现细节,如何才能更快速的利用现有网站的后台功能,实现更多更复杂的Ajax应用。  

第一技 瞒天过海

网页的表单,一直是一个令人头疼的事情,尤其是当一个提交涉及到较多的SQL命令,在你post一个表单时,页面没有立即跳转到你设定的redirect到目标页面,而是看到浏览器底部的进度条在前进。有时候,基于服务器的综合性能考虑,会对数据库的响应进行一定的限制,加上国内网络环境的限制,这种延迟无法避免。   以下是一个基本的登录form:  
1 <form action="/sign_in" method="post">
2     <div>
3         <label for="login_name">用户名</label><input type="text" id="login_name" />
4     </div>
5     <div>
6         <label for="login_pwd">用户名</label><input type="password" id="login_pwd" />
7     </div>
8     <input type="submit" value="登录" />
9 </form>
  接着是sign_in的后台,首先要找到该用户,其次,也许你需要一个log,记录下用户登录的状况,比如ip,客户端状况等等,最后,当不存在该用户,你还必须朝客户端返回一定的信息,提示用户接续操作。

接着是利用js对上述form的提交进行稍微的改造(js框架使用Prototype 1.6_rc1):

< form  id ="sign_form"  action ="/sign_in"  method ="post" >
    
< div >
        
< label  for ="login_name" > 用户名 </ label >< input  type ="text"  id ="login_name"   />
    
</ div >
    
< div >
        
< label  for ="login_pwd" > 用户名 </ label >< input  type ="password"  id ="login_pwd"   />
    
</ div >
    
< div  id ="sign_error" ></ div >
    
< input  type ="submit"  value ="登录"   />
</ form >

< script >
var  isPost  =   false ;                                      //  判断用户是否已经提交了登录
$( ' sign_form ' ).onsubmit  =   function () {
    $(
" sign_error " ).innerHTML  =   " 服务器正在验证数据,请稍候 " ;
    
if  (isPost)                                          //  避免用户重复提交
        $( " sign_error " ).innerHTML  =   " 数据已提交,请等待服务器验证! " ;
    
else  {
        
var  params  =  { name: $( " login_name " ).value, pwd: $( " login_pwd " ).value };
        $(
" login_pwd " ).value  =   "" ;                       //  将用户密码保存在局部变量中,并清空密码输入框的值
        isPost  =   ! isPost;                                //  set isPost = true
         new  Ajax.Request( this .action, {                  //  请求的地址即为 form 的 action
            method:  ' post ' ,
            parameters: params,
            onComplete: 
function (request) {
                isPost 
=   ! isPost;                        //  set isPost = false
                 var  content  =  request.responseText;
                
if  ( /*  当成功的状态  */ ) {
                    $(
" sign_error " ).innerHTML  =   " 登录成功! " ;
                    setTimeout(
function () { location.reload( true ); },  100 );
                }
                
else  {                                   //  失败的请求
                     var  msg  =  content;                   //  捕获错误的提示信息,如"不存在该用户"等
                    $( " sign_error " ).innerHTML  =  msg;     //  对页面输出错误信息
                     /*  以下添加错误状态的客户端前台控制  */
                    $(
" login_name " ).focus();
                    $(
" login_name " ).select();
                }
            }
        });
    }
    
return   false ;                                        //  取消该 form 的提交
}
</ script >

首先,区别第一段代码,我们为form捆绑了id:sign_form,以及添加了一个错误提示层:sign_error。

其次,在js中:

  1. 显式的声明了一个变量isPost来限制用户重复post
  2. 通过对客户端的状态输出以及DOM控制,对用户行为进行引导,比:基于页面redirect的方式对用户操作进行提示,前者体验性更佳。网站的风险,往往来自前端的引导不足和流程繁琐,因为这些因素会让用户生出反感,而进行一些超出网站设计意图的操作,比如不断按“提交”,进行一些恶性的行为,比如故意漏填表单中的某个项,或者刻意提交非法字符,“以挑战网页制作人员的专业程度和耐性”。
  3. 对一个form事件实现初步的多态控制,这个世界是纷繁复杂的,基于服务器端的多态控制会让人抓狂的,倒不如通过前台实现来的快捷。
  4. 最关键的是,通过信息的及时反馈,隐匿了post操作的等待与延迟。实际上,我们需要的仅仅是通过登录,让客户端持有一个session,然后让页面reload,或者redirect到其他地方去。

以上的示例,可以进行一个简单的封装:

< script >
var  isPost  =   false ;    

/*  * * * * * * * * * * * * * * * * * *
 * An Ajax post method sample.
 * Created by Janpoem 2008.3.1
 * * * * * * * * * * * * * * * * * * 
*/

ajaxPost 
=   function (params, callback) {
    
var  form  =   this ;
    
if  (callback  &&  callback.before) callback.before.call();
    
if  (isPost) {
        
if  (callback  &&  callback.onPosted) callback.onPosted.call();
    }
    
else  {
        isPost 
=   ! isPost;
        
new  Ajax.Request(form.action, {
            method: form.method,
            parameters: params,
            onComplete: 
function (request) {
                isPost 
=   ! isPost;
                
var  content  =  request.responseText;
                
if  (callback  &&  callback.roundback) callback.roundback.call(form, content);
            }
        })
        
if  (callback  &&  callback.after) callback.after.call();
    }
    
return   false ;
}
</ script >

< form  id ="sign_form"  action ="/sign_in"  method ="post" >
    
< div >
        
< label  for ="login_name" > 用户名 </ label >< input  type ="text"  id ="login_name"   />
    
</ div >
    
< div >
        
< label  for ="login_pwd" > 用户名 </ label >< input  type ="password"  id ="login_pwd"   />
    
</ div >
    
< div  id ="sign_error" ></ div >
    
< input  type ="submit"  value ="登录"   />
</ form >

< script >
$(
' sign_form ' ).onsubmit  =   function () {
    ajaxPost.call(
this , { name: $( " login_name " ).value, pwd: $( " login_pwd " ).value }, {
        before: 
function () { $( " sign_error " ).innerHTML  =   " 服务器正在验证数据,请稍候 " ; },
        onPosted: 
function () { $( " sign_error " ).innerHTML  =   " 数据已发送,请等到服务验证! " ; },
        roundback: 
function (msg) {
            
if  ( /*  当成功的状态  */ ) {
                $(
" sign_error " ).innerHTML  =   " 登录成功! " ;
                setTimeout(
function () { location.reload( true ); },  100 );
            }
            
else  {
                $(
" sign_error " ).innerHTML  =  msg;
                $(
" login_name " ).focus();
                $(
" login_name " ).select();
            }
        },
        after: 
function () { $( " login_pwd " ).value  =   "" ; }
    })
};
</ script >

怎么样,还没晕头吧?好吧,今天的讲解到此为止啦!

瞒天过海者,原计释:备周则意怠,常见则不疑。阴在阳之内,不在阳之对。太阳,太阴。这就是今天的全部精髓了。

转载于:https://www.cnblogs.com/janpoem/archive/2008/03/01/1087285.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值