65.9K
CodeProject 正在变化。 阅读更多。
Home

仅使用 HTML、CSS、JavaScript 和 SVG 的轻量级轮播图

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.67/5 (5投票s)

2022年7月6日

CPOL

8分钟阅读

viewsIcon

9867

downloadIcon

166

描述了无需第三方软件即可实现的轻量级动态轮播图。

1. 简介 目录

我最近决定为某个组织修改即将发生的事件轮播图。轮播图出现在两个地方

  • 作为一系列幻灯片,由 Raspberry Pi 4 在组织休息室的电视显示器上播放。每张幻灯片显示 10 秒。当所有幻灯片都显示完毕后,幻灯片放映会重复。
  • 作为组织网站上的轮播图。网站轮播图是休息室幻灯片放映的副本,带有允许暂停幻灯片放映、更改幻灯片显示时间和反转显示方向的控件。

实施网站轮播图的决定是由于一些幻灯片内容庞大,在分配的 10 秒内难以阅读。由于幻灯片已经放在网站上供 Raspberry Pi 4 下载,因此构建一个轮播图来在网站上显示幻灯片的决定是一项很容易完成的任务——我是这么认为的。

似乎实现轮播图的方法和使用它们的网站一样多。本文描述了另一种可能对某些读者有用的方法。它还描述了一些设计决策和在实施过程中出现的一些反复。

2. 要求 目录

对网站轮播图的要求是

  • 能够显示至少 30 张幻灯片(此实现将显示多达 32 张幻灯片)。
  • 从网站上的一个目录获取幻灯片。
  • 允许用户控制幻灯片移动方向(即向右或向左)。
  • 允许用户暂停和重新启动显示移动。
  • 允许用户显示特定幻灯片。
  • 允许用户修改每张幻灯片将显示的时间。

3. 设计 目录

轮播图的原始设计使用了 <input type="range"...> HTML 元素。然而,出现了一些问题

  • 尝试将刻度线与范围滑块的位置对齐,充其量是“接近”但不是“精确”。无法预测范围滑块从一步移动到下一步时停在哪里。
  • 浏览器实现者在解释 <input type="range"...> [^] HTML 元素的 W3c 草案方面存在显著差异。这意味着需要 大量 CSS [^] 才能使该元素在不同浏览器中看起来一致。

这些问题导致了第二个设计,其中 <input type="range"...> HTML 元素被一组可选择的刻度线取代,如下图所示。

overview

除了 carousel_container <div> 之外,还有三个主要的 <div>。

  1. left_slide_right <div> 显示一个左移控制、一张幻灯片和一个右移控制。每个组件都包含在自己的 <div> 中。箭头指向单击时幻灯片将移动的方向。
  2. pause_continue_dots <div> 包含暂停/继续控制和表示将显示幻灯片数量的小圆圈(在此示例中为 20 张幻灯片)。暂停/继续控制和未填充/填充圆圈组件都包含在各自的 <div> 中。填充的圆圈表示当前正在显示的幻灯片。通过单击未填充的点,将显示该点所代表的幻灯片。在此图中,幻灯片移动已暂停,继续箭头出现在点的左侧。单击继续箭头后,移动再次开始,继续箭头被暂停指示器替换(在此图中显示在 carousel_container <div> 的左侧)。
  3. ticks_and_delay <div> 包含用户更改幻灯片显示时间的方法。它包含可选择的刻度线,允许用户单击刻度线来设置所需的延迟。

实现后,轮播图显示为

4. 实现 目录

本文描述的实现使用了 HTML、CSS、原生 JavaScript 和 SVG。没有使用第三方软件。

4.1. HTML 目录

left_slide_right <div>、pause_continue_dots <div> 和 ticks_and_delay <div> 定义了 flex 盒子。我可以向我的读者保证,没有修饰的 <div>(不使用 flex)或 <table> 并不是解决方案(它们被尝试过!)。

4.2. CSS 目录

flex 盒子在 CSS 中定义。

      .carousel_container,
      .left_slide_right_container {
        display:flex;
        justify-content:center;
        align-items:flex-start;
        }

      .left_slide_right {
        height:300px;
        display:flex;
        justify-content:center;
        align-items:center;
        }

      .pause_continue_dots_container,
      .time_ticks_div,
      .ticks {
        display:flex;
        justify-content:center;
        align-items:center;
        }

      #pause_continue_button,
      #dots {
        display:flex;
        justify-content:center;
        }

点,包括填充和未填充的,也在 CSS 中定义。

      .dot {
        width:10px;
        height:10px;
        margin-right:2px;
        border:solid 1px Black;
        border-radius:50%;
        }

      .dot:hover {
        border-color:Red;
        }

      .unfilled {
        background:White;
        border-color:Black;
        }

      .filled {
        background:CornflowerBlue;
        border-color:CornflowerBlue;
        }

前面的 CSS 作为内部 CSS 出现在 carousel.html 文档的 style 元素中。内部 CSS 中提供的 CSS 特定于此轮播图实现。

尽管轮播图的某些 CSS 部分出现在内部 CSS 中,但也使用了内联 CSS。这种形式的 CSS 通常设置 widthheight 的值,因为此样式仅适用于特定的 HTML 元素。

carousel.js 中的 JavaScript 中生成了额外的 CSS。

可能有趣的是,一个 dot 仅通过 CSS 定义。特定的 dot 是否被填充或未填充由 JavaScript 函数 set_active_dot 决定。

pause_continue_dots

这些点与其左侧邻居之间相隔 2 像素;控制部分与 dots <div> 之间相隔 5 像素。这些值是通过实验选择的,以找到可接受的平衡。

4.3. Javascript 目录

到目前为止,最复杂的代码是项目的 Javascript 模块,包含在 carousel.js 中,其“命名空间”是“Carousel”。

JavaScript 的执行由一个 JSON 对象控制。

    <script>
      var CAROUSEL_COMPONENTS =
            {
            "slides_directory":"./Slides30",

            "timer_default_value":2,
            "timer_minimum":1,
            "timer_maximum":20,
            "timer_step":1,

            "chosen":"Red",
            "hover":"DodgerBlue",
            "normal":"LightSkyBlue",

            "debug_json":false

            }; // CAROUSEL_COMPONENTS
    </script>

此 JSON 对象应在 carousel.html 的 <head> 中定义。

要显示的幻灯片应位于 CAROUSEL_COMPONENTS.slides_directory 中命名的单个目录中。幻灯片本身使用以下形式命名

     Slide1.png,Slide2.png, ....  

使用 XMLHttpRequest 恢复目录中的幻灯片列表。返回的列表包含的信息不仅仅是幻灯片的名称。XMLHttp.responseText 中的每一行都以 '\n' 结尾,因此可以通过该字符 split XMLHttp.responseText 来创建文件列表。要提取实际的幻灯片列表,必须考虑执行环境。这通过以下方式实现。

                                        // The strings returned in the 
                                        // XMLHttp.responseText differ 
                                        // between the localhost 
                                        // environment (used in test 
                                        // and debug) and the 
                                        // production environment
    var LOCAL_DOMAINS = &lsqb; "localhost", "127.0.0.1" &rsqb;;
    var IS_LOCALHOST = 
          LOCAL_DOMAINS.includes ( window.location.hostname );

JavaScript 函数 extract_slides_from_file_list 负责生成幻灯片列表。如果幻灯片的命名方式与 上面 描述的不同,则此函数需要更改。

此实现中可以显示的幻灯片数量有限(受幻灯片图像下方可容纳的填充/空点数量限制)。

                                        // maximum number of slides: 
                                        //    width of carousel 400 px
                                        //       width of a dot  10 px
                                        //     dot right margin   2 px
                                        //      total dot width  12 px
                                        //     width of control  10 px
                                        // control right margin   5 px
                                        //  total control width  15 px
                                        // ( 400 - 15 ) / 12 = 32.08
                                        //                   ≈ 32

                                        // MORE THAN 32 SLIDES WILL BE 
                                        // TRUNCATED TO 32 WITHOUT 
                                        // WARNING UNLESS THE DISPLAY 
                                        // IS ON LOCALHOST WHEN A 
                                        // WARNING WILL BE GIVEN
    var MAXIMUM_SLIDES_ALLOWED = 32;

此实现中可以显示的刻度线数量也有限(受刻度线数量和可容纳在 carousel_container 中的图例限制)。

                                        // maximum number of ticks
                                        // width of carousel 
                                        //            container 450 px
                                        //   width of tick mark   5 px
                                        //    tick right margin   5 px
                                        //     total tick width  10 px
                                        //     width of "delay"  50 px
                                        //   width of "seconds"  50 px
                                        //   total legend width 100 px
                                        //  ( 450 - 100 ) / 10 = 35
                                        
                                        // MORE THAN 35 TICKS WILL BE 
                                        // TRUNCATED TO 35 WITHOUT 
                                        // WARNING UNLESS THE DISPLAY 
                                        // IS ON LOCALHOST WHEN A 
                                        // WARNING WILL BE GIVEN
    var MAXIMUM_TICK_MARKS_ALLOWED = 35;

由于 JavaScript 和 HTML 之间的交互非常重要,因此需要实例化大量的 document ids

                                        // document ids
    var carousel = document.getElementById ( "carousel" );
    var dots = document.getElementById ( "dots" );
    var left_side_BUT = document.getElementById ( "left_side_BUT" );
    var pause_continue_button = document.getElementById ( 
                                            "pause_continue_button" );
    var right_side_BUT = document.getElementById ( "right_side_BUT" );
    var right_text  = document.getElementById ( "right_text" );
    var temporary_dot = document.getElementById ( "temporary_dot" );
    var ticks = document.getElementById ( "ticks" );

Javascript 为所有轮播图事件提供事件处理程序,包括

    dot_clicked
    move_left
    move_right
    pause_continue_clicked
    tick_clicked
    tick_mouseout
    tick_mouseover

有五个状态变量

                                        // state variables
    var current_active_dot = 0;
    var current_seconds = 0;
    var current_tick_mark_border_color;
    var moving_leftward = true;
    var paused = false;

这些变量要么保存/恢复关键执行状态,要么控制 GUI 如何显示其内容。

4.4. 可伸缩矢量图形 (SVG) 目录

SVG [^] 用于生成 GUI 中出现的图像(除了点)。

four_svgs

例如,暂停和继续图像是使用 JavaScript 函数 assign_pause_or_continue_image 中的 SVG 生成的。

    // ******************************** assign_pause_or_continue_image

    // local entry point

    function assign_pause_or_continue_image ( )
      {

      pause_continue.innerHTML = "";
      if ( paused )
        {
        pause_continue.innerHTML =
          "<svg class='continue_icon'" +
          "     width='10' " +
          "     height='10'" +
          "     viewBox='0 0 10 10'" +
          "     overflow='visible'>" +
          "  <path d='M 0 0 L 10 5 L 0 10 L 0 0' " +
          "        fill='" + COMPONENTS.normal + "'" +
          "        stroke='" + COMPONENTS.normal + "'/>" +
          "</svg>";
        }
      else 
        {
        pause_continue.innerHTML =
          "<svg class='pause_icon' " +
          "     width='10'" +
          "     height='10'" +
          "     viewBox='0 0 10 10'>" +
          "  <path d='M 0 0 h 4 v 10 h -4 v -10 m 6 0 h 4 v 10 h -4 v -10'" +
          "        fill='" + COMPONENTS.normal + "'" +
          "        stroke='" + COMPONENTS.normal + "'/>" +
          "</svg>";
        }

      } // assign_pause_or_continue_image

这段代码使用状态变量 paused 来确定绘制哪个图形。图形轮廓是使用 path 创建的。在 continue_icon 中,“M”将笔移动到绝对位置,“L”从当前位置绘制一条线到绝对位置。然后路径被关闭。在 pause_icon 中,“m”将笔从当前位置移动到相对位置,“h”绘制指定长度的水平线,“v”绘制指定长度的垂直线。由于它们是动态的,这两个图形是用 JavaScript 绘制的。左右移动箭头是使用嵌入在 HTML 中的 SVG 绘制的。

                                    <!-- left_side -->
      <div class="left_slide_right"
           style="width:25px;" >
        <button id="left_side_BUT"
                style="background:transparent;">
          <svg version="1.1"
               width="20" 
               height="23"
               xmlns="http://www.w3.org/2000/svg">
            <polygon id="left_pointing_arrow"
                     points="0,11 20,0 20,23"
                     fill="CornflowerBlue"
                     stroke="CornflowerBlue"/>
          </svg>
        </button>
      </div>
      &vellip;
                                    <!-- right_side -->
      <div class="left_slide_right"
           style="width:25px;
                  margin-left:1px;" >
        <button id="right_side_BUT"
                style="background:transparent;
                       float:left;
                       vertical-align:middle;">
          <svg version="1.1"
               width="20" 
               height="23"
               xmlns="http://www.w3.org/2000/svg">
            <polygon id="right_pointing_arrow"
                     points="0,0 20,11 0,23"
                     fill="CornflowerBlue"
                     stroke="CornflowerBlue"/>
          </svg>
        </button>
      </div>

 

图形轮廓是使用 polygon 创建的,它被定义为一系列点。SVG polygon 会自动闭合。

5. 下载 目录

carousel.zip 文件包含以下目录中的以下文件(目录为粗体

    Carousel_Project
        carousel.html       Project HTML
        carousel.js         Project JavaScript
        favicon.ico         Project Icon 
      Slides30              Slide directory derived from Slides30.ppt
        Slide1.png
        &vellip;
        Slide30.png
    Carousel_Sources
        BW_Slides30.ppt
        Initial_Design.ppt
        Miscellaneous.ppt
        Slides20.ppt
        Slides30.ppt
        Slides40.ppt
    Carousel_Paper
        Carousel.html       This article
        carousel.png
        Carousel.TOC.html   This article with a TOC
        Chrome.png
        Edge.png
        Firefox.png
        Firefox_Developer.png
        four_svgs.PNG
        Internet_Explorer.png
        Opera.png
        overview.png
        pause_continue_dots.png
        range_vs_div.png
        ReturnToTOC.png
        Safari.png

对于打算下载 ZIP 文件的读者,我建议如下:

  • 创建目录 Carousel
  • 将 ZIP 文件下载到 Carousel 中。
  • 将 ZIP 文件的内容解压到 Carousel 目录中。请注意,有些 ZIP 文件解压程序希望将内容解压到 Carousel 下新创建的目录中。
  • 使用您喜欢的浏览器,打开 Carousel_Project/carousel.html。

请告知我任何建议、评论或批评。它们都同样受欢迎。

6. 参考 目录

7. 总结 目录

本文描述了一个无需第三方软件即可实现的轻量级动态轮播图。

8. 开发环境 目录

轮播图项目是在以下环境中开发的

Microsoft Windows 7 专业版 SP 1
Microsoft Visual Studio 2008 专业版 SP1
Microsoft Visual C# 2008
Microsoft .Net Framework Version 3.5 SP1

9. 支持的浏览器 目录

以下描述了支持此轮播图实现的浏览器。

Chrome Edge Firefox Firefox_Developer Internet_Explorer Opera Safari
Chrome
103
Edge
91.0.625
Firefox
95.0.2
Firefox
开发版
103.0b3
互联网
Explorer 11
Opera
88.0.4412.40
Safari
5.1.7

Internet Explorer 和 Safari 都没有 Windows 7 的修订版。

10. 历史 目录

07/04/2022 原文
© . All rights reserved.