投递文章投递文章 投稿指南投稿指南 RSS订阅RSS订阅

控件开发:JavaScript的呈现逻辑和方法

来源:iT堂整理 发布时间:2008-05-17 收藏 投稿 字体:【

我们在写自定义控件的时候,避免不了不用JavaScript,而怎么在控件中使用并且高效的呈现到客户端,是我们要考虑的问题,所以我在下面结合一个简单的CusterHyperLink控件,来介绍我们的控件怎么去加载并呈现到客户端的过程。
1.  首先我们要实现这个控件,大致要怎样的步骤呢?

当我们开发这样的控件的时候,主要涉及到以下的内容:
     (1)    使用该控件,并封装实现Html和客户端脚本;
     (2)    确定如何将客户端脚本呈现包含在页面中(控件从Control 和WebControl继承,会有不同)
     (3)    控件应该包括一个确定合适呈现脚本的程序逻辑,不必总是呈现客户端脚本
     (4)    当所请求的浏览器不支持客户端能力的时候,允许控件退回执行服务器端代码

2.呈现方式

   2.1 将脚本呈现为Html属性值
        这个比较简单,我们可以考虑这样一个例子,一个超级链接,鼠标移出或移上去,会有不同的背景。
        Html代码1如下:
         <a href="Http://xbf321.cnblogs.com" onmouseover="this.style.backgroundColor='Blue';this.style.color='yellow';this.style.fontSize='xx-large';this.style.fontWeight='bold';" onmouseout="this.style.backgroundColor='White';this.style.color='Blue';this.style.fontSize='small';this.style.fontWeight='normal';" style="background-color:Write;color:Blue;font-size:small;font-weight:normal;">点我</a>
      下面将开发一个自定义控件CustomHyperLinkAttr。该控件可自动完成上述两个步骤。
      因为我们只给链接加上属性,所以我们选择一个现成的.Net 控件HyperLink,作为这个控件的基类,我们重写此控件的AddAttributesToRender方法,该方法呈现包含Html元素的属性,代码2如下:
      我们在页面上,只要使用这个控件的就可以了,而不必写上一大堆的Html代码

Code
 namespace CustomComponents
{

    public class CustomHyperLinkAttr : System.Web.UI.WebControls.HyperLink

    {

        protected override void AddAttributesToRender(System.Web.UI.HtmlTextWriter writer)

        {

            base.AddAttributesToRender(writer);

            writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor,"Write");

            writer.AddStyleAttribute(HtmlTextWriterStyle.Color,"Blue");

            writer.AddStyleAttribute(HtmlTextWriterStyle.FontSize,"small");

            writer.AddStyleAttribute(HtmlTextWriterStyle.FontWeight,"normal");

            writer.AddAttribute("onmouseover","this.style.backgroundColor='Blue';this.style.color='yellow';this.style.fontSize='xx-large';this.style.fontWeight='bold';");

            writer.AddAttribute("onmouseout", "this.style.backgroundColor='White';this.style.color='Blue';this.style.fontSize='small';this.style.fontWeight='normal';");

        }

    }

}
<form id="form1" runat="server"> <custom:CustomHyperLinkAttr runat="server" NavigateUrl="Http://xbf321.cnblogs.com" Text="点我"></custom:CustomHyperLinkAttr></form>,
      一定要在页面或Web.Config中引用以下哦,我想这是最基本的,不用我在详细的说了吧。呵呵,可以参考ClingingBoy的http://www.cnblogs.com/Clingingboy/archive/2006/07/30/463471.html

   2.2 在<script></script>中呈现脚本块
       在上面的代码1种,我们的链接包含Css样式属性和Js代码,如果我们的页面上有好多这样的链接,那我们的页面,就会非常的臃肿,维护也是个问题,所以我们把js部分提炼出来用JavaScript来对链接操作,并在元素<a>的onmouseover 和onmouseout属性中调用这两个个函数即可
     代码3

Code
<script type="text/javascript">

    function MouseOverCallback(aElement)

{

   aElement.style.backgroundColor = 'Blue';

   aElement.style.color = 'Yellow';

   aElement.style.fontSize = 'xx-large';

   aElement.style.fontWeight = 'bold';

}

function MouseOutCallback(aElement)

{

   aElement.style.backgroundColor = 'White';

   aElement.style.color = 'Blue';

   aElement.style.fontSize = 'small';

   aElement.style.fontWeight = 'normal';

}

    </script>

          接下来,我们修改一下上面的那个自定义控件,我们在此控件的Render方法中把这些的JavaScript函数给输出来,而在AddAttributesToRender方法中修改onmouseover和onmouseout二个属性。
        代码4

Code
namespace CustomComponents

{

    public class CustomHyperLinkAttr : System.Web.UI.WebControls.HyperLink

    {

        protected override void AddAttributesToRender(System.Web.UI.HtmlTextWriter writer)

        {

            base.AddAttributesToRender(writer);

            writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor,"Write");

            writer.AddStyleAttribute(HtmlTextWriterStyle.Color,"Blue");

            writer.AddStyleAttribute(HtmlTextWriterStyle.FontSize,"small");

            writer.AddStyleAttribute(HtmlTextWriterStyle.FontWeight,"normal");

            //writer.AddAttribute("onmouseover","this.style.backgroundColor='Blue';this.style.color='yellow';this.style.fontSize='xx-large';this.style.fontWeight='bold';");

            //writer.AddAttribute("onmouseout", "this.style.backgroundColor='White';this.style.color='Blue';this.style.fontSize='small';this.style.fontWeight='normal';");

            writer.AddAttribute("onmouseover", "MouseOverCallback(this)");

            writer.AddAttribute("onmouseout", "MouseOutCallback(this)");

        }

        protected override void Render(HtmlTextWriter writer)

        {

            string strJs = @"   <script type=""text/javascript"">

    function MouseOverCallback(aElement)

{

   aElement.style.backgroundColor = 'Blue';

   aElement.style.color = 'Yellow';

   aElement.style.fontSize = 'xx-large';

   aElement.style.fontWeight = 'bold';

}

function MouseOutCallback(aElement)

{

   aElement.style.backgroundColor = 'White';

   aElement.style.color = 'Blue';

   aElement.style.fontSize = 'small';

   aElement.style.fontWeight = 'normal';

}

    </script>";

            writer.Write(strJs);

            base.Render(writer);

        }

    } 

}

 注意注释掉的部分
       如上代码所示,该控件重写了Render方法,以便将客户端脚本呈现为一个脚本快,同时还重写了AddAttributesRender方法,将其呈现为包含Html元素<a>的onmouseover和onmouseout 的属性值。
       如果页面开发人员在同一个页面上使用两个或多个这样的控件,会发生什么呢?
       如你所想,页面上就会有多个像代码3这样的脚本快。
       这就意味着自定义控件的每个事例都会调用一次Render方法,所以就会在页面上重复这样的脚本块,那我们怎么才能避免这种问题呢?
       Page类提供了这样一种机制,其允许在包含页面的Render方法中注册并判断是否已经注册脚本块,代码5如下
        Public void RegisterClientScriptBlock(Type type,string key,string script,bool addTag)
       该方法中type和key共同形成关键字,并通过这个关键字来注册脚本快,在呈现的过程中,页面将检查所注册的脚本快内部列表中是否包括该关键字的脚本快,如果包括,则不会创建该脚本块,否则反之。最后的一个参数,让你决定自己呈现像<script>这样的标签,如果false,自己必须写<script>,反之,他们自动对脚本添加上<script>和</script>
       如果控件呈现的Html代码需要访问Javascript,那么就必须使用RegisterClientScriptBlock方法注册,因为只有呈现呈现在脚本快后面的Html才能访问该脚本,如果脚本需要访问Html那么只有使用RegisterStartupScript方法。这两个的参数都是一样的。可以举一反三明白其他的。
       在控件尝试注册脚本快之前,可以调用IsClientScriptBlockRegistered/IsClientStartScriptRegister方法来检测该脚本是否已经注册过,在相同的关键字下,对相同的客户端进行多次注册时允许的,这是因为该操作,并没有将相同脚本的多个副本添加到页面的注册脚本内部列表中。因此控件应该调用IsClientScriptBlockRegistered/IsClientStartScriptRegister方法。那么应该在什么时候调用该方法呢?
       如果控件必须花费大量的时间来生成已注册过的脚本,那么有可能会降低性能,在这种情况下,就首先调用IsClientScriptBlockRegistered/IsClientStartScriptRegister方法,以便脚本是没有经过注册的:
       Public bool IsClientScriptBlockRegisted(String key)
       在内部,该方法会调用以下方法的重写,并将包含页面的System.Type对象和key作为参数传递给该方法:
       Public void RegisterStartupScript(Type type ,string key,string script,bool addScriptTags)
       并和key形成关键字,来确保脚本是否已经注册。
        回顾一下代码4,该代码直接在Render方法中直接呈现控件的脚本快,上面我们说过,该控件不应该直接呈现脚本块,而是应该向包含页面注册脚本块,以便让页面自己呈现脚本块,以下是新版本的CustomHyperLinkAttr控件代码,该控件重写了OnPreRender方法,以便向页面注册客户端脚本代码5

最新5条评论 查看所有评论
评论内容:请自觉遵守互联网相关政策法规。
用户名: 密码: 匿名 注册
热门文章
随机推荐
About iTtang - 联系方法  - 专题列表 - 友情链接  -  高级搜索   -  帮助中心  -