zoukankan      html  css  js  c++  java
  • 验证控件网页代码分析

    建立一个简单的网页,一个文本框,一个按钮,一个禁止空白的验证控件.网页打开时,传到客户端有三个文件,我们用M表示主页,W1表示从1,W2表示从2,网页的执行过程如下:
    先设置变量theForm为页面的表单

    var theForm = document.forms['form1'];
    if (!theForm)
      theForm 
    = document.form1;
    为什么用两种方法呢?因为在netscape中不支持document.form1的方式,也有这样的写法
    if (window.navigator.appName.toLowerCase().indexOf("netscape"> -1)
      theform 
    = document.forms["Form1"];
    else
      theform 
    = document.Form1;
    在我系统中,只有IE,因此这段代码可简化为
    var theForm = document.forms['form1'];

    接着转到附带的两个JS文件中执行变量的赋值及初使的代码
    W1
    var __pendingCallbacks = new Array();
    var __synchronousCallBackIndex = -1;
    //判断是不是IE,是IE,返回false,变量的本意是"不是微软DOM浏览器"
    var __nonMSDOMBrowser = (window.navigator.appName.toLowerCase().indexOf('explorer'== -1);
    var __theFormPostData = "";
    var __theFormPostCollection = new Array();
    var __disabledControlArray = new Array();
    var __defaultFired = false;
    W2
    var Page_ValidationVer = "125";
    var Page_IsValid = true;
    var Page_BlockSubmit = false;
    var Page_InvalidControlToBeFocused = null;

    再回到主页继续执行
    //定义数组变量为本页的验证控件组
    var Page_Validators =  new Array(document.getElementById("RequiredFieldValidator1"));
    //定义变量为本页的验证控件,netscape不支持document.all,因此还要用document.getElementById
    var RequiredFieldValidator1 = document.all ? document.all["RequiredFieldValidator1"] : 

    document.getElementById(
    "RequiredFieldValidator1");
    //验证控件的一些属性,JS中属性是可以随时增加的
    RequiredFieldValidator1.controltovalidate = "TextBox1";
    RequiredFieldValidator1.errormessage 
    = "RequiredFieldValidator";
    RequiredFieldValidator1.evaluationfunction 
    = "RequiredFieldValidatorEvaluateIsValid";
    RequiredFieldValidator1.initialvalue 
    = "";

    var Page_ValidationActive = false;
    //如果ValidatorOnLoad是函数的话,则执行该函数.这种写法在以下出现过很多次.
    if (typeof(ValidatorOnLoad) == "function")
      ValidatorOnLoad();

    接着跳转到W2中执行ValidatorOnLoad.它的作用就是在装载时就“挂钩”.
    function ValidatorOnLoad()
    {
      
    //如果本页没有任何验证控件的话,就不必执行了
      if (typeof(Page_Validators) == "undefined")
        
    return;
      
    var i, val;
      
    //对每个验证控件都进行设置
      for (i = 0; i < Page_Validators.length; i++)
      
    {
        val 
    = Page_Validators[i];
        
    //如果验证控件有设evaluationfunction属性的话 **详见说明**
        if (typeof(val.evaluationfunction) == "string")
          eval(
    "val.evaluationfunction = " + val.evaluationfunction + ";");
          
    //实际执行 val.evaluationfunction = RequiredFieldValidatorEvaluateIsValid;
          //RequiredFieldValidatorEvaluateIsValid是在W2中的具体函数
        if (typeof(val.isvalid) == "string")
        
    {
          
    if (val.isvalid == "False")
          
    {
            val.isvalid 
    = false;
            Page_IsValid 
    = false;
          }

          
    else
            val.isvalid 
    = true;
        }

        
    else
          val.isvalid 
    = true;
        
    if (typeof(val.enabled) == "string")
          val.enabled 
    = (val.enabled != "False");
        
    if (typeof(val.controltovalidate) == "string")
          ValidatorHookupControlID(val.controltovalidate, val);
        
    if (typeof(val.controlhookup) == "string")
          ValidatorHookupControlID(val.controlhookup, val);
      }

      Page_ValidationActive 
    = true;
    }
    以上子程序是完成对页面所有验证控件的参数进行正确的设置,其中有一段代码,想法太利害了:
        if (typeof(val.evaluationfunction) == "string")
          eval(
    "val.evaluationfunction = " + val.evaluationfunction + ";");

    如果验证控件的某个属性还是字符串的话,则用eval对其进行设置,使其变成指向这个函数。这样,我们在设置属性时,可以使用字符串,而实际中又转为指向该名称的函数。后面的几个也使用了类似的代码来实现对属性的设置。

    evaluationfunction:?用于计算待验证控件的值,前面有赋string类型的值
    isvalid:返回待验证控件是否符合要求
    enabled:验证控件是否激活
    controltovalidate:侍验证的控件,前面有赋string类型的值
    controlhookup:?
    由于isvalid之前没有赋值,因此代码是走到else的,val.isvalid = true;,即默认是符合要求的,而之前,我
    们也有对Page_IsValid设为true,即整个页面也是符合要求的。
    enabled也是没有赋值,这里就跳过,可能靠控件的默认值来保证它是true的。如果有赋一个字符串的值的话,

    (val.enabled != "False") 则是为"true"时返回true,为"False"时返回false。

    这里有一个子程序ValidatorHookupControlID,它的入口参数是待验证的控件名(字符串型),与验证控件本身(对象)。

    function ValidatorHookupControlID(controlID, val)
    {
      
    //如果第一个参数不是字符串,就不再继续,立即返回
      if (typeof(controlID) != "string")
        
    return;
      
    //设置对象为待验证的控件
      var ctrl = document.getElementById(controlID);
      
    //该待验证的控件必须存在,并且不能为空,则进行“挂钩”
      if ((typeof(ctrl) != "undefined"&& (ctrl != null))
        ValidatorHookupControl(ctrl, val);
      
    else
      
    {
        
    //否则禁用验证控件
        val.isvalid = true;
        val.enabled 
    = false;
      }

    }
    这里又引出“挂钩”函数ValidatorHookupControl
    function ValidatorHookupControl(control, val)
    {
      
    //如果控件不存在则返回
      if (typeof(control.tagName) != "string")
        
    return;  
      
    if (control.tagName != "INPUT" && control.tagName != "TEXTAREA" && control.tagName != "SELECT")
      
    {
        
    //如果控件不是INPUT/TEXTAREA/SELECT这些控件,则看这个控件的子控件
        var i;
        
    for (i = 0; i < control.childNodes.length; i++)
          ValidatorHookupControl(control.childNodes[i], val);
          
    //这里使用了递归
        return;
      }

      
    else
      
    {
        
    //如果待验证控件的Validators还没定义的话,先要去定义
        if (typeof(control.Validators) == "undefined")
        
    {
          control.Validators 
    = new Array;
          
    var eventType;
          
    if (control.type == "radio")
            eventType 
    = "onclick";
          
    else
          
    {
            eventType 
    = "onchange";
            
    if (typeof(val.focusOnError) == "string" && val.focusOnError == "t")
              ValidatorHookupEvent(control, 
    "onblur""ValidatedControlOnBlur(event); ");
              
    //修改得到焦点事件的处理程序
          }

          
    //修改改变事件的处理程序
          ValidatorHookupEvent(control, eventType, "ValidatorOnChange(event); ");
          
    //对于文本框、密码框、文件文本框
          if (control.type == "text" ||
              control.type 
    == "password" ||
              control.type 
    == "file")
            ValidatorHookupEvent(control, 
    "onkeypress""if (!ValidatedTextBoxOnKeyPress(event)) 

    return false; 
    ");
            
    //修改按键事件的处理程序
        }

        
    //待验证控件的验证控件指向本验证控件
        control.Validators[control.Validators.length] = val;
      }

    }

    还有修改某个控件的某个事件处理程序
    function ValidatorHookupEvent(control, eventType, functionPrefix)
    {
      
    var ev;
      
    //设置ev为待验证控件的对应事件
      eval("ev = control." + eventType + ";");
      
    //其类型一般是"object"
      if (typeof(ev) == "function")
      
    {
        ev 
    = ev.toString();
        ev 
    = ev.substring(ev.indexOf("{"+ 1, ev.lastIndexOf("}"));
      }

      
    else
        ev 
    = "";
      
    var func;
      
    if (navigator.appName.toLowerCase().indexOf('explorer'> -1)
        
    //如果是IE浏览器
        func = new Function(functionPrefix + " " + ev);
      
    else
        func 
    = new Function("event", functionPrefix + " " + ev);
      
    //待验证控件的事件处理设置为指定的函数
      eval("control." + eventType + " = func;");
    }
    这些执行完成后,页面也就装载好了。
    未完,待继
  • 相关阅读:
    dsp与sem的互补以及技术实现
    SmartAssembly 6 + ClickOnce 混淆发布,妈妈再也不用担心程序裸奔了
    IL学习,使用Emit动态创建一个委托
    DataReader扩展方法
    已安装 SQL Server 2005 Express 工具。若要继续,请删除 SQL Server 2005 Express 工具
    仿163网盘无刷新多文件上传系统
    asdf
    闽江学院2015-2016学年下学期《软件测试》课程-第一次作业(个人作业)
    闽江学院2015-2016学年下学期《软件测试》课程-第三次博客作业
    闽江学院2015-2016学年下学期《软件测试》课程-第二次作业(个人作业)
  • 原文地址:https://www.cnblogs.com/yzx99/p/1169778.html
Copyright © 2011-2022 走看看