在开发Web应用程序时,经常需要实现内容的动态滚动效果。本文将介绍如何在ASP.NET中创建一个可以滚动HTML或ASP控件的内容滚动控件。
在寻找滚动功能的过程中,发现了一些JavaScript示例代码,但它们需要完全定制以适应ASP.NET服务器端开发。也发现了一些商业产品,但它们需要通过产品生成HTML和CSS,然后将这些内容复制到页面中。决定利用ASP.NET服务器端控件的强大功能,动态地实现这一切。
最初,考虑使用Silverlight来实现这个功能,但后来意识到,为了实现滚动这样的基本功能,要求用户下载并安装Silverlight是不合理的。因此,决定使用JavaScript。以下是与垂直和水平滚动相关的主要脚本部分:
        function populate() {
            if (iedom) {
                cross_scroller = document.getElementById ? document.getElementById("[$ieScroller$]") : document.all.[$ieScroller$];
                if (scrollDirection == 'Vertical') {
                    cross_scroller.style.top = parseInt(scrollerHeight) + 8 + "px";
                } else if (scrollDirection == 'Horizontal') {
                    cross_scroller.style.left = parseInt(scrollerWidth) / 2 + 8 + "px";
                }
                // 错误的获取内容尺寸方式
                actualheight = cross_scroller.offsetHeight;
                actualwidth = cross_scroller.offsetWidth;
                // 正确的获取实际内容尺寸方式
                actualheight = getContentHeight(cross_scroller);
                actualwidth = getContentWidth(cross_scroller);
            } else if (document.layers) {
                ns_scroller = document.[$nsScroller0$].document.[$nsScroller1$];
                if (scrollDirection == 'Vertical') {
                    ns_scroller.top = parseInt(scrollerHeight) + 8;
                } else if (scrollDirection == 'Horizontal') {
                    ns_scroller.left = parseInt(scrollerWidth) + 8;
                }
                ns_scroller.document.close();
                actualheight = ns_scroller.document.height;
                actualwidth = ns_scroller.document.width;
            }
            // 如果没有设置为None,则从这里开始滚动
            if (scrollDirection == 'Vertical') {
                lefttime = setInterval("scrollVertical()", 20);
            } else if (scrollDirection == 'Horizontal') {
                lefttime = setInterval("scrollHorizontal()", 20);
            }
        }
        window.onload = populate;
        function scrollVertical() {
            if (iedom) {
                if (parseInt(cross_scroller.style.top) > (actualheight * (-1) + 8)) {
                    cross_scroller.style.top = parseInt(cross_scroller.style.top) - copyspeed + "px";
                } else {
                    cross_scroller.style.top = parseInt(scrollerHeight) + 8 + "px";
                }
            } else if (document.layers) {
                if (ns_scroller.top > (actualheight * (-1) + 8)) {
                    ns_scroller.top -= copyspeed;
                } else {
                    ns_scroller.top = parseInt(scrollerHeight) + 8;
                }
            }
        }
        function scrollHorizontal() {
            if (iedom) {
                if (parseInt(cross_scroller.style.left) > (actualwidth * (-1) + 8)) {
                    cross_scroller.style.left = parseInt(cross_scroller.style.left) - copyspeed + "px";
                } else {
                    cross_scroller.style.left = parseInt(scrollerWidth) + 8 + "px";
                }
            } else if (document.layers) {
                if (ns_scroller.left > (actualwidth * (-1) + 8)) {
                    ns_scroller.left -= copyspeed;
                } else {
                    ns_scroller.left = parseInt(scrollerWidth) + 8;
                }
            }
        }
        function getContentWidth(el) {
            var tmp = el.style.overflow;
            el.style.overflow = 'auto';
            var w = el.scrollWidth;
            el.style.overflow = tmp;
            return w;
        }
        function getContentHeight(el) {
            var tmp = el.style.overflow;
            el.style.overflow = 'auto';
            var w = el.scrollHeight;
            el.style.overflow = tmp;
            return w;
        }
    
脚本已经进行了文档化,因此应该相当清晰。但是,它包含的标记会被控件动态替换。
该控件使用ASP.NET模板控件技术,允许定义要滚动的内容。因此,可以为滚动提供几乎任何东西。主要操作发生在控件的PreRender事件中,标记被替换。它们(标记)主要与提供宽度、高度和动态生成的div的Ids有关。然后实例化ContentTemplate并将其添加到这些div中。JS通过它们的id获取这些div,并在屏幕上移动它们(left=left-2)或垂直(top=top-2)。因此,控件本身相当简单。
代码本身非常容易使用。请看以下示例:
        <%@ Register Namespace="Rahul" TagPrefix="cs" %>
        <cs:ContentScroller runat="server" Width="300" Height="200" scrollDirection="BottomToTop" scrollSpeed="2">
            <ContentTemplate>
                <pre>
                    在这里放置任何HTML或ASP.NET控件。
                    无论它变得多长或多高,它都能工作。
                </pre>
                <asp:Label runat="server" BorderStyle="Dashed" BorderWidth="2px" Text="Sample">
                </asp:Label>
                <pre>
                    在这里放置任何HTML或ASP.NET控件。
                    无论它变得多长或多高,它都能工作。
                </pre>
                <asp:Label runat="server" BorderStyle="Dashed" BorderWidth="2px" Text="Sample">
                </asp:Label>
                <pre>
                    在这里放置任何HTML或ASP.NET控件。
                    无论它变得多长或多高,它都能工作。
                </pre>
                <asp:Label runat="server" BorderStyle="Dashed" BorderWidth="2px" Text="Sample">
                </asp:Label>
                <pre>
                    在这里放置任何HTML或ASP.NET控件。
                    无论它变得多长或多高,它都能工作。
                </pre>
                <asp:Label runat="server" BorderStyle="Dashed" BorderWidth="2px" Text="Sample">
                </asp:Label>
            </ContentTemplate>
        </cs:ContentScroller>
    
在ContentTemplate中放置的任何内容都将由控件滚动。已经利用ASP.NET控件模板的强大功能,允许在ContentTemplate内部嵌入任何内容。这也需要调整JavaScript(基本上需要动态生成一些控件,并让JavaScript引用它们以进行滚动)。
scrollDirection属性是关键。将其设置为LeftToRight、RightToLeft、BottomToTop或TopToBottom以控制滚动方向,或者将其设置为None以完全关闭滚动(如果需要)。内容仍然会静止显示在屏幕上。
scrollSpeed是另一个有趣的部分。将其设置在1到10之间以控制滚动速度,其中数值越高滚动速度越快。默认值为2。
这里有一个示例场景,使用这个控件来滚动动态生成的内容:
        <%@ Register Namespace="Rahul" TagPrefix="cs" %>
        <cs:ContentScroller runat="server" ID="scrollerAlert" scrollDirection="RightToLeft" Height="<%# Me.alertController.scrollHeight %>" Width="<%# Me.alertController.scrollWidth %>">
            <ContentTemplate>
                <table cellpadding="0" cellspacing="0">
                    <tr valign="top">
                        <asp:Repeater runat="server" ID="rptAlert">
                            <ItemTemplate>
                                <td valign="top" style="padding-right: 30px">
                                    <a href="#" style="cursor: hand">
                                        <asp:Label runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "lcNumber") %>' />
                                        <br />
                                        <asp:Label runat="server" Text='<%# Me.formatDocuments(Container.DataItem) %>' />
                                        <br />
                                    </a>
                                </td>
                            </ItemTemplate>
                        </asp:Repeater>
                    </tr>
                </table>
            </ContentTemplate>
        </cs:ContentScroller>
    
2008年12月15日:初次发布