zoukankan      html  css  js  c++  java
  • 自定义控件:广告内容后期加载。以及NamingContainer层次的应用

    《转》http://www.pin5i.com/showtopic-11037.html

    网站上的广告内容可能会因加载过慢而导致整个网页加载过慢,我们可以考虑将广告内全部放在网页最底部,等整个页面加载完毕後再采用javascript使其显示,考虑给控件一个TargetContainerID标识,控件广告内容将要被显示的容器ID,然后从控件自己所处的 开始向上查找该ID所指定的控件,(我们只向上找而没有向下找,并且没有处理某层次的子NamingContainer,所以不一定能够找到,这里没有考虑从Page对象向下递归查找主要考虑为了提高性能),如果没有找到,则考虑给用户一个事件让用户自己处理TargetContainer。

    下面的自定义控件对此实现了封装:
    namespace HBZ.Ads.Controls
    {
        using System;
        using System.ComponentModel;
        using System.Web;
        using System.Web.UI;
        using System.Web.UI.WebControls;
        using HBZ.Ads;
        using System.Collections.Generic;
        using System.Text;

        [Designer( typeof( HBZ.Ads.Controls.AdRotatorDesigner ) )]
        public class AdRotator : WebControl
        {
            private Dictionary<string , Control> findControlHelperCacheList = new Dictionary<string , Control>( );
            private readonly string scriptFormat = "var {0}_target = document.getElementById(\"{0}\"); var {1}_base = document.getElementById(\"{1}\"); if ({0}_target) {{ {0}_target.innerHTML = {1}_base.innerHTML; {1}_base.innerHTML = \"\"; }}";

            private static readonly object eventObj = new object( );
            public event FindTargetContainerEventHandler FindTargetContainer
            {
                add
                {
                    Events.AddHandler( eventObj , value );
                }
                remove
                {
                    Events.RemoveHandler( eventObj , value );
                }
            }

            public AdRotator( )
                : base( HtmlTextWriterTag.Span )
            {
            }

            [TypeConverter( typeof( ValidatedControlConverter ) )]
            [DefaultValue( "" ) , Category( "Data" ) , Description( "广告位后期加载后显示的位置的控件ID" )]
            [IDReferenceProperty]
            public string TargetContainerID
            {
                get
                {
                    return (string)this.ViewState[ "TargetContainerID" ] ?? string.Empty;
                }
                set
                {
                    this.ViewState[ "TargetContainerID" ] = value;
                }

            }       


            [Bindable( true ) , Category( "Data" ) , DefaultValue( "" ) , Description( "广告位的默认内容" )]
            public string DefaultContent
            {
                get
                {
                    return (string)this.ViewState[ "DefaultContent" ] ?? "广告位招租";
                }
                set
                {
                    this.ViewState[ "DefaultContent" ] = value;
                }
            }
            protected override void OnPreRender( EventArgs e )
            {
                base.OnPreRender( e );

                if ( !string.IsNullOrEmpty( TargetContainerID ) )
                {
                    this.Style.Add( HtmlTextWriterStyle.Display , "none" );

                    ClientScriptManager cs = Page.ClientScript;
                    if ( !cs.IsStartupScriptRegistered( this.ClientID ) )
                    {
                        cs.RegisterStartupScript( this.GetType( ) , this.ClientID , GetLazyLoadingScript( ) , true );
                    }
                }
            }

            protected virtual string GetLazyLoadingScript( )
            {
                Control target = FindControlHelper( TargetContainerID );
                if ( target == null )
                {
                    throw new TargetContainerNotFoundException( );
                }

                StringBuilder sb = new StringBuilder( );
                sb.AppendFormat( scriptFormat , target.ClientID , this.ClientID );

                return sb.ToString( );
            }

            protected virtual void RenderAdvertisement( Advertisement ad , HtmlTextWriter writer )
            {
                // 广告内容
            }

            protected override void RenderContents( HtmlTextWriter writer )
            {

                // call RenderAdvertisement method
            }

            protected Control FindControlHelper( string id )
            {
                Control c = null;
                if ( findControlHelperCacheList.ContainsKey( id ) )
                {
                    c = findControlHelperCacheList[ id ];
                }
                else
                {
                    c = base.FindControl( id );  // 注意:我们从自己开始向上沿NamingContainer层次查找
                    Control nc = NamingContainer;
                    while ( ( null == c ) && ( null != nc ) )
                    {
                        c = nc.FindControl( id );
                        nc = nc.NamingContainer;
                    }
                    if ( null == c )
                    {
                        // 因为我们是从自己开始向上沿NamingContainer层次查找,而没有向下找,
                        // 并且没有找每一层NamingContainer内的其他NamingContainer,
                        // 所以这种查找有可能出现没有找到id对应的控件

                        // 当没此时有找到时,激发FindTargetContainer事件交给用户自己设定Target Container Control
                        FindTargetContainerEventArgs args = new FindTargetContainerEventArgs( id );

                        OnFindTargetContainer( args );

                        c = args.Control;

                    }
                    if ( null != c )
                    {
                        findControlHelperCacheList[ id ] = c;
                    }
                }

                return c;
            }

            protected virtual void OnFindTargetContainer( FindTargetContainerEventArgs e )
            {
                FindTargetContainerEventHandler hander = Events[ eventObj ] as FindTargetContainerEventHandler;
                if ( hander != null )
                {
                    hander( this , e );
                }
            }
        }

        public delegate void FindTargetContainerEventHandler( object src , FindTargetContainerEventArgs e );

        public class FindTargetContainerEventArgs : EventArgs
        {
            private string controlID;
            private Control control;

            public FindTargetContainerEventArgs( string controlId )
            {
                controlID = controlId;
            }

            public string ControlID
            {
                get
                {
                    return controlID;
                }
            }

            public Control Control
            {
                get
                {
                    return control;
                }
                set
                {
                    control = value;
                }
            }
        }

        public class TargetContainerNotFoundException : Exception
        {
            string exceptionMessage = string.Empty;
            public TargetContainerNotFoundException( )
                : this( "TargetContainerID所指定的控件没有找到!您或许应该处理一下FindTargetContainer事件" )
            {
            }

            public TargetContainerNotFoundException( string message )
                : base( message )
            {
                this.exceptionMessage = message;
            }
            public override string Message
            {
                get
                {
                    if ( exceptionMessage != null )
                    {
                        return exceptionMessage;
                    }
                    return base.Message;
                }
            }

        }
    }
    http://www.cn-web.com/cnweb/0/411/article/

    看不懂的话,先看下asp.net中的NamingContainer详解
    文章来源(WEB开发技术知识库):http://www.cn-web.com/cnweb/0/411/article/

  • 相关阅读:
    Shiro 学习笔记(Realm)
    Shiro 学习笔记(Authentication)
    Shiro 学习笔记(基本结构)
    POI 示例(导入,导出)
    SpringBoot 整合POI
    解决使用drf-haystack报错ImportError: cannot import name get_count
    python实现冒泡排序和插入排序
    九大排序算法总结(转)
    Djaong 数据库查询
    django session 和cookie的设置,获取和删除
  • 原文地址:https://www.cnblogs.com/sainaxingxing/p/1282401.html
Copyright © 2011-2022 走看看