Bootstrap-实践指南-四-

130 阅读40分钟

Bootstrap 实践指南(四)

原文:Practical Bootstrap

协议:CC BY-NC-SA 4.0

八、表单

您已经学习了 HTML 表单和每个表单控件。Twitter Bootstrap 以类的形式给了你一些额外的工具,这将允许你非常容易地设计你的表单。

你将能够构建一个如图 8-1 所示的基本表单

img/497763_1_En_8_Fig1_HTML.jpg

图 8-1

登录表单示例

或类似图 8-2 中的表单。

img/497763_1_En_8_Fig2_HTML.jpg

图 8-2

注册表单示例

您还可以非常直观地显示哪些字段已经成功填写,哪些字段没有填写(图 8-3 )。

img/497763_1_En_8_Fig3_HTML.jpg

图 8-3

有错误的注册表单

学习目标

  1. 了解如何实现 Twitter Bootstrap 基本表单。

  2. 了解 Twitter 引导水平表单。

  3. 了解水平表单如何使用网格类将标签和输入控件布置到不同的列,但在同一行上。

  4. 了解 Twitter Bootstrap 内嵌表单。

  5. 了解如何在输入控件下显示帮助文本。

  6. 了解只读控件。

  7. 了解如何使用 Twitter Bootstrap 显示选择框。

  8. 了解验证。

  9. 了解如何更改输入控件的大小。

  10. 了解如何将两个控件组合在一起并创建一个输入组。

介绍

Twitter Bootstrap 提供了一系列影响表单和表单控件样式的类。在这一章中,你将设计一个 Twitter Bootstrap 表单参考页面,其中你将展示 Twitter Bootstrap 为你提供的关于这个主题的所有主要工具。

我们开始吧。

空的 Twitter 引导页面

您将从标准的空 Twitter 引导页面开始(清单 8-1 )。

<!DOCTYPE html>
<html lang="en">
<head>
  <!-- Required meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

  <!-- Custom CSS -->
  <link rel="stylesheet" href="stylesheets/main.css" type="text/css">

  <title>Twitter Bootstrap Forms Reference Page</title>
  <link rel="stylesheet" href="stylesheets/main.css">
</head>
<body>

  <div id="main-container" class="container">
    <!-- Content will be inserted here -->

  </div>

  <!-- Optional JavaScript -->
  <!-- jQuery first, then Popper.js, then Bootstrap JS -->
  <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>
</html>

Listing 8-1Empty Bootstrap Page

将前面的 HTML 内容保存在index.html文件中。另外,准备一个空的stylesheets/main.css文件来存储你的 CSS 规则。如果您保存这些文件并在浏览器上加载页面,您将看不到任何内容,因为正文不包含任何内容。

目的是将页面的全部内容添加到一个container div中。这就是为什么你能在身体内部看到带有container类的div

基本表单

您将从基本的 Twitter 引导表单开始。在main-container元素中添加以下内容(清单 8-2 )。

<div class="row">
    <div class="col-12 col-lg-6">
        <h3>Sign In</h3>
        <p>Sign in today for better experience.</p>

        <form>
            <div class="form-group">
                <label for="email">Email</label>
                <input type="email" id="email" placeholder="Enter email" class="form-control">
            </div>

            <div class="form-group">
                <label for="password">Password</label>
                <input type="password" id="password" placeholder="Password" class="form-control">
            </div>

            <div class="d-flex justify-content-between align-items-center">
                <div class="form-check">
                    <input type="checkbox" class="form-check-input" id="remember-me-checkbox">
                    <label class="form-check-label" for="remember-me-checkbox">Remember Me</label>
                </div>

                <button class="btn btn-sm btn-primary" type="submit">
                    <strong>Log in</strong>
                </button>
            </div>

        </form>
    </div> <!-- left column -->

    <div class="col-12 col-lg-6">

    </div> <!-- right column -->

</div> <!-- row inside main container -->

Listing 8-2Basic Form

正如您在前面的代码中所看到的,您将首先创建一个两列布局。右栏暂时是空的。左栏包含一个标题h3和一个小段落p。但是这里重要的东西是form元素。

这是一个简单的form元素,没有附加任何类。这是 Twitter Bootstrap 提供的基本表单样式。

这里需要指出的是:

  1. 标签和输入在div中组合在一起。每个div都有一个form-group类。但是,与复选框相关的div有一个例外。它没有这个类。稍后我会解释原因。

  2. 每个输入控件都有类form-control,除了checkbox输入,它有类form-check-input

  3. 使用与 flexbox 相关的类justify-content-betweenalign-items-center将复选框和登录按钮放在同一行。更多的解释将在下面提供。

  4. 类别form-check用在包含复选框的div上。

  5. 类别form-check-label用在复选框的标签上。

否则,前面代码中的任何其他内容都非常简单,不使用任何新内容。

如果您保存前面的代码并在浏览器上加载页面,您将看到以下内容(图 8-4 )。

img/497763_1_En_8_Fig4_HTML.jpg

图 8-4

在表单中签名

如您所见,在标准表单上增加一点 HTML,您会得到很多东西。查看输入获得焦点时是如何突出显示的。看看使用 flexbox 实用程序类左右移动东西是多么容易(图 8-5 )。

img/497763_1_En_8_Fig5_HTML.jpg

图 8-5。

当输入获得焦点时突出显示

现在,我将对您在前面的代码片段中使用的一些类进行更多的解释:

  • 这个类form-group做一些非常简单的事情。它增加了值1rem的底部边距。因此,如果您有一个垂直表单,就像示例中那样,输入和它们的标签在垂直方向上流动,这是很有用的。

  • form-check已经用于与复选框相关的输入和标签。这个类应用的最重要的规则是值1.25rem的左填充。这使得复选框在垂直方向上与表单的其他元素很好地左对齐。如果你愿意,你也可以应用form-group类,特别是当其他控件跟在你的第一个复选框下面的时候。

  • form-control对于附加到input元素非常重要。它负责宽度、高度、颜色、背景色、边框和其他样式属性。

  • 然而,不要将这个类(form-control)用于类型checkbox的输入。这些是完全不同的视觉方式。他们需要被赋予自己特别设计的名为form-check-input的职业。这个类将位置absolute赋予复选框输入,没有具体的坐标。因此,它是相对于其最近的定位的 1 祖先绘制的。因为您将输入放在一个带有类form-checkdiv中,所以它是相对于那个div绝对定位的。

  • Labels除了伴随checkbox输入的标签,不要选择任何特殊的类。这就需要有阶级form-check-label。它消除了底部空白。这使它更好地与实际输入保持一致。

  • 附加在包含复选框和登录按钮的div上的类d-flexdiv转化为 flexbox 容器。这意味着它在行方向上布局其元素。如果您临时移除它,您将看到登录按钮出现在复选框输入的下方。

  • justify-content-between获取 flexbox div的两个子元素,并在行方向上对齐它们,以便它们之间有空白空间。因此,一个子对象左对齐,另一个子对象右对齐。

  • align-items-center对齐 flex div的子对象,但是在非主轴方向。默认主轴是行(x, horizontal)。因此,align-items-*类在列(y, vertical)轴方向对齐子元素。这个特别的把它们排列在中间。

水平表单

以前的表单有一行是标签,在标签下面有一行是输入控件。在这里,您可以选择实现一个水平表单。该表单的标签和输入控件在同一行,占据相邻的列。HTML 标记更加复杂,并且使用与网格相关的类。让我们看看怎么做。

在右栏div(列表 8-3 )中增加以下内容。

<div class="col-12 col-lg-6">
    <h3>Sign In</h3>
    <p>Sign in today for better experience.</p>

    <form>
      <div class="form-group row">
        <label class="col-lg-2 col-form-label" for="email2">Email</label>
        <div class="col-lg-10">
          <input type="email" placeholder="Email" class="form-control" id="email2">
          <small class="form-text text-muted">Example block-level help text here.</small>
        </div>
      </div>

      <div class="form-group row">
        <label class="col-lg-2 col-form-label" for="password2">Password</label>
        <div class="col-lg-10">
          <input type="password" placeholder="Password" class="form-control" id="password2">
        </div>
      </div>

      <div class="form-group row justify-content-end">
        <div class="col-lg-10">
          <div class="form-check">
            <input type="checkbox" class="form-check-input" id="remember-me-checkbox-2">
            <label class="form-check-label" for="remember-me-checkbox-2">Remember Me</label>
          </div>
        </div>
      </div>

      <div class="form-group row justify-content-end">
        <div class="col-lg-10">
          <button class="btn btn-sm btn-secondary" type="submit">Sign in</button>
        </div>
      </div>
    </form>
  </div> <!-- right column -->

Listing 8-3Right Column div with Horizontal Form

在我解释清单 8-3 的 HTML 标记之前,让我们保存 HTML 页面并将其加载到您的浏览器上。您应该看到以下内容(图 8-6 )。

img/497763_1_En_8_Fig6_HTML.jpg

图 8-6

右列上的水平窗体

如图 8-6 所示,水平表单将每一行分成两列,一列用于标签,一列用于输入控件本身。以下是您需要从代码中了解的内容:

  1. 每个表单组(div和类form-group)现在都有一个额外的类row。这将允许我们使用 Bootstrap 的网格特性来布置每个组中的孩子。

  2. 电子邮件和密码这两个标签占据了两列的宽度。这就是为什么他们有col-lg-2。注意,它们还需要有 c 类ol-form-label。这个类是专门设计来垂直对齐标签的。

  3. 电子邮件和密码这两个输入被打包到一个带有类col-lg-10div中,这使得它们占据了剩余的可用水平空间。

  4. 包含复选框的行占据 10 的列宽,右对齐。这是在类justify-content-end和类col-lg-10的帮助下发生的,类justify-content-end使div的子元素位于 flex 容器的右侧,类div使div占据了十列。

  5. 最后,请注意我们如何在电子邮件输入下方创建帮助文本。这是通过一个拥有类form-texttext-mutedsmall元素来完成的。

内嵌表单

有些情况下,您只有一行来显示表单的所有输入控件。下面是这种表单的一个例子(图 8-7 )。

img/497763_1_En_8_Fig7_HTML.jpg

图 8-7

内嵌表单示例

您将在这两个表单下面创建这样一个表单。使用清单 8-4 ,并将其添加为 id 为#main-containerdiv的最后一个子节点。

<div id="inline-form-container">
    <hr class="m-4">
    <form class="form-inline">
        <div class="form-group mr-sm-2">
            <label for="email3" class="mr-sm-2">Email address</label>
            <input type="email" placeholder="Enter email" id="email3" class="form-control">
        </div>

        <div class="form-group mr-sm-2">
            <label for="password3" class="mr-sm-2">Password</label>
            <input type="password" placeholder="Password" id="password3" class="form-control">
        </div>

        <div class="form-check mr-sm-2">
            <input type="checkbox" id="checkbox1" class="form-check-input">
            <label for="checkbox1" class="form-check-label">
                Remember me
            </label>
        </div>

        <button class="btn btn-primary" type="submit">Sign in</button>
    </form>
</div>

Listing 8-4Inline Form HTML Fragment

如果您保存前面的代码并在浏览器上重新加载页面,您将看到以下内容(图 8-8 )。

img/497763_1_En_8_Fig8_HTML.jpg

图 8-8

底部的自举内嵌表单

form标签需要有类form-inline。这就完全不同了。否则,除了您已经知道的类之外,不会添加任何与表单相关的类。你只使用了一些保证金实用程序类,如类mr-sm-2。这些类所做的唯一事情就是添加一些边距,以使表单的元素周围有一些自由空间。

帮助文本

很多时候,输入控件需要用户输入一条不常见的信息。用户界面需要确保用户理解他们必须输入的内容。标签有帮助。占位符也有帮助。但是有时候,为了提供更详细的解释,需要额外的帮助。在这种情况下,您可能想要使用名为Help Text的工具。

帮助文本通常出现在输入控件的下方;它是一个短语,向用户解释他们必须键入的内容。

让我们将下面这段 HTML 代码作为最后的元素添加到主容器 div 中(清单 8-5 )。

<h3 class="mt-4">Other Form Elements</h3>
<hr class="my-4">

<form>
    <div>
        <em>Help Text</em>
        <hr class="my-3">
    </div>

    <div class="form-group row">
        <label for="help-text" class="col-lg-2 col-form-label">VAT number</label>
        <div class="col-lg-10">
            <input type="text" class="form-control" id="help-text" placeholder="Key in your VAT number"/>
            <small class="form-text text-muted">Give your company VAT number. Enter the VIES VAT number with the two char prefix indicating your country.</small>
        </div>
    </div>
</form>

Listing 8-5Page with Help Text

以下是对上述 HTML 片段的解释:

  1. 您添加了一个标题为Other Form Elements的页眉。这基本上是通过一个带有顶部边距的h3元素(类mt-4)和一个带有垂直边距的hr元素(类my-4)来完成的。

  2. 您正在页面上引入一个新表单。这将是一个水平的表单,将用于封闭一系列的表单元素,我想跟你谈谈。

  3. Help Text开始。这是用一个简单的small元素实现的,该元素有form-texttext-muted类。它正好位于它所伴随的输入控件之后。除此之外,前面这段代码没有什么特别之处。

如果您保存前面的代码并在浏览器上加载页面,您将看到以下内容(图 8-9 )。

img/497763_1_En_8_Fig9_HTML.jpg

图 8-9

页面的其他表单元素部分的开始

只读纯文本

纯文本输入控件用于表示标签旁边的只读信息。让我们添加下面的 HTML 片段作为最后一个表单的一部分(清单 8-6 )。

<div>
    <em>Readonly Plain Text</em>
    <hr class="my-3">
</div>

<div class="form-group row">
    <label class="col-sm-2 col-form-label" for="readonly-email">Email:</label>
    <div class="col-sm-10">
        <input type="text" readonly class="form-control-plaintext" id="readonly-email" value="foo@bar.com">
    </div>
</div>

Listing 8-6Input Control as Read-Only Plain Text

如果保存前面的代码并在浏览器上加载页面,您将看到图 8-10 。

img/497763_1_En_8_Fig10_HTML.jpg

图 8-10

作为只读纯文本的输入控件

你看到了吗?值为 foo@bar.com 的电子邮件输入被设计成不同于普通的输入控件。这是在类form-control-plaintext的帮助下完成的。否则,所有剩下的 HTML 标记都是您所知道的。

选择框

选择框和 Twitter Bootstrap 没有什么特别的。您唯一要做的事情就是将类form-control附加到select元素上。让我们添加下面的 HTML 代码作为最后一个表单的一部分(清单 8-7 )。

<div>
    <em>Select Boxes</em>
    <hr class="my-3">
</div>

<div class="form-group row">
    <label class="col-lg-2 col-form-label" for="select-1">Single</label>

    <div class="col-lg-10">
        <select class="form-control" name="account" id="select-1">
            <option>option 1</option>
            <option>option 2</option>
            <option>option 3</option>
            <option>option 4</option>
        </select>
    </div>
</div>

<div class="form-group row flex-justify-end">
    <label class="col-lg-2 col-form-label" for="select-2">Multiple</label>

    <div class="col-lg-10">
        <select class="form-control" multiple="multiple" id="select-2">
            <option>option 1</option>
            <option>option 2</option>
            <option>option 3</option>
            <option>option 4</option>
        </select>
    </div>
</div>

Listing 8-7Single and Multiple Select Box

这很简单。除了select元素附加了类form-control之外,这里没有什么新的东西。如果您保存页面并在浏览器上重新加载,您将看到以下内容(图 8-11 )。

img/497763_1_En_8_Fig11_HTML.jpg

图 8-11

带有选择框的页面部件

form-control设计选择框的样式,类似于其他输入控件用这个类得到的样式。

输入验证

很多时候,人们希望突出显示用户已经给出错误输入的输入控件。或者可能想要突出显示具有正确输入的那些。一种方法是对输入控件进行相应的着色,例如,用红色表示错误的输入。

Twitter Bootstrap 提供了一组专门用来处理这个问题的类。这些类别是

  1. is-valid

  2. is-invalid

  3. valid-feedback

  4. invalid-feedback

您将类is-validis-invalid分别附加到您想要样式化为有效或无效的input上。

您将valid-feedbackinvalid-feedback类附加到一个保存反馈消息的div上,分别用于有效和无效的情况。这个div需要存在于 input 元素的正下方,作为第一个直接兄弟。

让我们在您正在处理的表单的末尾添加以下 HTML 代码(清单 8-8 )。

<div>
    <em>Input Validation</em>
    <hr class="my-4">
</div>

<div class="form-group row">
    <label class="col-lg-2 col-form-label" for="valid-input">Email</label>
    <div class="col-lg-10">
        <input type="email" class="form-control is-valid" id="valid-input" placeholder="Your username" value="foo@bar.com" required/>
        <div class="valid-feedback">
            Nice!
        </div>
    </div>
</div>

<div class="form-group row">
    <label class="col-lg-2 col-form-label" for="invalid-input">Password</label>
    <div class="col-lg-10">
        <input type="password" class="form-control is-invalid" id="invalid-input" placeholder="Your password" required>
        <div class="invalid-feedback">
            You have to give your password
        </div>
    </div>
</div>

Listing 8-8Input Validation

如果您保存前面的代码并在浏览器上加载页面,您将看到以下内容(图 8-12 )。

img/497763_1_En_8_Fig12_HTML.jpg

图 8-12

输入验证

您看到有效和无效输入是如何设计的了吗?在一小部分类的帮助下,Bootstrap 允许你在样式上做惊人的工作。

输入控件的大小

Twitter Bootstrap 提供了一些非常方便的与输入控件大小相关的类。您可以使用大型控件,将类form-control-lg附加到输入控件。或者你可以使用小控件,用类form-control-sm代替。让我们在表单的末尾添加下面这段 HTML 代码(清单 8-9 )。

<div>
    <em>Size of Input Controls</em>
    <hr class="my-4">
</div>

<div class="form-group row">
    <label class="col-lg-2 col-form-label" for="large-size-input">Large</label>

    <div class="col-lg-10">
        <input type="text" class="form-control form-control-lg" id="large-size-input"/>
    </div>
</div>

<div class="form-group row">
    <label class="col-lg-2 col-form-label" for="default-size-input">Default</label>

    <div class="col-lg-10">
        <input type="text" class="form-control" id="default-size-input"/>
    </div>
</div>

<div class="form-group row">
    <label class="col-lg-2 col-form-label" for="small-size-input">Small</label>

    <div class="col-lg-10">
        <input type="text" class="form-control form-control-sm" id="small-size-input"/>
    </div>
</div>

Listing 8-9Different Input Control Sizes

如果您保存此文件并在浏览器上重新加载页面,您将看到以下内容(图 8-13 )。

img/497763_1_En_8_Fig13_HTML.jpg

图 8-13

不同的输入控件大小

如果你尝试添加一些输入,尺寸的差异会变得更加明显(图 8-14 )。

img/497763_1_En_8_Fig14_HTML.jpg

图 8-14

某些输入的不同输入控件大小

输入组

有时候你想制造出如下效果(图 8-15 )。

img/497763_1_En_8_Fig15_HTML.jpg

图 8-15

输入组示例

这是一个输入组示例。其他示例如下两个(图 8-16 和图 8-17 )。

img/497763_1_En_8_Fig17_HTML.jpg

图 8-17

美元和小数输入组示例

img/497763_1_En_8_Fig16_HTML.jpg

图 8-16

小数输入组示例

这里有一个小标签和一个文本输入控件的组合(图 8-18 )。

img/497763_1_En_8_Fig18_HTML.jpg

图 8-18

标签和输入控件组合在一起

将这两个(在第三个例子中是三个)控件组合成一个称为输入分组。

让我们在您的表单中添加以下代码(清单 8-10 )。

<div>
    <em>Input Groups</em>
    <hr class="my-4">
</div>

<div class="row justify-content-end" id="input-groups-container">
    <div class="col-lg-10">

        <div class="input-group">
            <div class="input-group-prepend">
                <span class="input-group-text">@</span>
            </div>
            <input type="text" placeholder="Username" class="form-control"/>
        </div>

        <div class="input-group">
            <input type="text" class="form-control"/>
            <div class="input-group-append">
                <span class="input-group-text">.00</span>
            </div>
        </div>

        <div class="input-group">
            <div class="input-group-prepend">
                <span class="input-group-text">$</span>
            </div>
            <input type="text" class="form-control">
            <div class="input-group-append">
                <span class="input-group-text">.00</span>
            </div>
        </div>

        <div class="input-group">
            <div class="input-group-prepend">
                <div class="input-group-text">
                    <input type="checkbox">
                </div>
            </div>
            <input type="text" class="form-control">
        </div>

        <div class="input-group">
            <div class="input-group-prepend">
                <div class="input-group-text">
                    <input type="radio">
                </div>
            </div>
            <input type="text" class="form-control">
        </div>
    </div>
</div>

Listing 8-10Examples of Input Groups

另外,在stylesheets/main.css文件中添加以下 CSS 规则:

#input-groups-container .input-group {
    margin-bottom: 1.2rem;
}

保存前面的所有代码,并在浏览器上重新加载页面。您将看到以下内容(图 8-19 )。

img/497763_1_En_8_Fig19_HTML.jpg

图 8-19

输入组

让我们看看 HTML 代码中的输入组是由什么组成的。我分析第一个输入组,它是:

  1. input-group需要是一个带有类input-groupdiv

  2. div需要包含input元素。在我们的例子中,这是用户输入用户名的地方。

  3. 视觉装饰在实际input之前。因此,input需要在前面加上一个具有类input-group-prependdiv

  4. 这个div,带input-group-prepend的,需要有一个带input-group-textspan里面的装饰。

<div class="input-group">

  <div class="input-group-prepend">

    <span class="input-group-text">@</span>

  </div>

  <input type="text" placeholder="Username" class="form-control"/>

</div>

非常容易!

那么你需要注意以下几点:

  1. 如果视觉装饰需要放在input元素之后,那么它的div类需要写在input元素之后,它的类需要是input-group-append(而不是input-group-prepend)。

  2. 你可以有两个视觉装饰——一个在主input控件之前,一个在主input控件之后。您只需在主input控件之前使用一个带有类input-group-prependdiv,在它之后使用另一个带有类input-group-appenddiv

  3. 对组的 prepend 或 append 部分中的复选框和单选按钮进行特殊设置。它们不应该被包裹在一个span里,而应该被包裹在一个div里。

前面分组的另一个变化是一个input控件和一个按钮的分组。在表单的末尾添加以下 HTML 代码(清单 8-11 )。

<div>
    <em>Input & Button Groups</em>
    <hr class="my-4">
</div>

<div class="row justify-content-end">
    <div class="col-lg-10">
        <div class="input-group">
            <input type="text" class="form-control"/>
            <div class="input-group-append">
                <button type="button" class="btn btn-primary">Go!</button>
            </div>
        </div>
    </div>
</div>

Listing 8-11Input Group with a Button

如果您保存前面的代码并在浏览器上重新加载页面,您将看到以下内容(图 8-20 )。

img/497763_1_En_8_Fig20_HTML.jpg

图 8-20

输入和按钮组

正如您在 HTML 代码中看到的,实现与前面的情况非常相似。唯一的区别是,你没有用类input-group-textbutton包装在任何spandiv中。您将button作为带有类input-group-prepend(或input-group-append)的div的直接且唯一的子元素。

任务和测验

TASK DETAILS

img/497763_1_En_8_Fig21_HTML.jpg

图 8-21

任务:登录表单

  1. 你需要创建一个 Twitter 引导页面,上面有三个表单。

  2. 第一个表单需要是如下表单中的一个标志(图 8-21 )。

img/497763_1_En_8_Fig22_HTML.jpg

图 8-22

任务:注册表单

  1. 在您的项目中导入/引用带有字体的 FontAwesome 库。FontAwesome 项目解释了如何做到这一点。

  2. 添加将表示图标的 HTML 片段。它可能是这样的:

    <i class="fas fa-asterisk"></i>
    
    
  3. 接下来需要第二个表单,即注册表单,如下所示(图 8-22 )。

  4. 这是一个基本的 Twitter 自举表单。您可能遇到的唯一困难是密码输入组中的符号。为了添加这些内容,您需要

img/497763_1_En_8_Fig23_HTML.jpg

图 8-23

任务:注册表单并进行验证

  1. 这里没有什么新东西。确保在密码和名称字段中使用正确的字体图标。

  2. 注意输入控件很大。

  3. 第三个表单与第二个表单相同,但是所有的输入字段都被标记为有效或无效。其实除了密码确认无效外都是有效的(图 8-23 )。

  4. 请注意,在第三个表单中,所有输入字段都填充了一个值。你必须这么做。提示:设置input HTML 元素的value属性。

  5. 此外,红色信息“它不匹配你的密码”是一个无效的反馈。这需要是一个div元素,紧挨着它所伴随的输入控件,也就是密码确认输入控件。

关键要点

  • 如何创造惊人的表单

  • 如何水平和垂直布局表单输入

  • 如何将标签和输入字段组合在一起并设计它们的样式

  • 如何将输入与其他视觉装饰组合在一起

  • 如何制作小型和大型输入控件

  • 如何在输入控件下方显示帮助文本

  • 如何显示验证成功和错误输入

  • 如何给出验证反馈

  • 如何设置只读输入控件的样式

在下一章中,我将介绍更多的动态页面。您将学习如何创建模态对话框。

Footnotes 1

定位的元素是没有位置static的任何元素。

 

九、模态对话框

在这一章中,您开始将 JavaScript 应用于 Twitter Bootstrap。您将看到 Bootstrap 如何提供非常有用的 JavaScript 库来帮助您尽可能轻松地向 web 应用程序添加动态行为。

你从模态开始,模态是试图吸引用户注意力的对话窗口,如图 9-1 所示。

img/497763_1_En_9_Fig1_HTML.jpg

图 9-1

模态对话框示例

然后我将解释如何将 Twitter Bootstrap JavaScript 库与您自己的 HTML 页面集成在一起。

您将了解模态 HTML 标记及其主要部分,以及如何使用图片创建令人印象深刻的模态,如下所示(图 9-2 )。

img/497763_1_En_9_Fig2_HTML.jpg

图 9-2

带图片的示例模型

最后,您学习了与模态相关的所有事件,并被要求构建一个处理相关事件的模态。您将构建一个如下所示的模型(图 9-3 )。

img/497763_1_En_9_Fig3_HTML.jpg

图 9-3

有两个城市可供选择

学习目标

  1. 学习情态动词。

  2. 了解如何引用 Twitter Bootstrap JavaScript 文件。

  3. 了解引入模态功能的最简单的 HTML 标记。

  4. 了解哪些 Twitter 引导类与模态功能有关。

  5. 了解 Twitter Bootstrap HTML 标记的主要部分。

  6. 了解如何使用数据属性来触发模式。

  7. 了解如何对按钮进行编程,使其在被单击时打开一个模态。

  8. 了解如何在模式的右上角有一个关闭按钮。

  9. 了解如何使用 FontAwesome 作为关闭按钮的图标。

  10. 了解如何在模态上显示图像。

  11. 了解如何在模型上显示 YouTube 视频。

  12. 了解如何在模态上显示其他/外部页面。

  13. 了解如何显示大模态和小模态。

  14. 了解如何在模型体内使用 Twitter Bootstrap 网格系统。

  15. 了解如何使用 JavaScript 激活模态。

  16. 了解如何通过使用 JavaScript 设置各种选项来自定义模态行为。

  17. 了解各种可用的模态方法。

  18. 了解可以挂接事件处理程序的各种模式事件。

介绍

情态动词是一种非常用户友好的向用户展示信息或要求提供信息的方式。模态是覆盖页面的窗口,不允许用户与页面的其他部分进行交互。换句话说,用户必须在返回主页之前关闭模态:

  1. 用户可以阅读信息,然后关闭模式。一个模态可以在右上角有一个Close按钮或者一个[X]按钮来关闭它。

  2. 用户可以填写一些表单,然后单击表单的提交按钮。这通常会关闭模式并将用户返回到主页。

让我们来看一个实际的模态(图 9-4 )。

img/497763_1_En_9_Fig4_HTML.jpg

图 9-4

模态示例

Twitter Bootstrap 免费提供模态,作为 JavaScript 集成的一部分。让我们看看怎么做。

引导 JavaScript 文件

为了能够使用模态,您需要引用 Twitter 引导 JavaScript 文件。这些需要在 jQuery JavaScript 文件的后引用**。**

下面是一个引用 Twitter Bootstrap 和 jQuery 的最简单的 HTML 页面(清单 9-1 )。

<!DOCTYPE html>
<html lang="en">
<head>
  <!-- Required meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

  <title>Modal Dialogs</title>

</head>
<body>

  <!-- Optional JavaScript -->
  <!-- jQuery first, then Popper.js, then Bootstrap JS -->
  <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>
</html>

Listing 9-1Empty Twitter Bootstrap Page with JavaScript

从前面的代码中可以看出,为了使用 Twitter Bootstrap JavaScript 库和组件,您必须加载三个外部文件。参见图 9-5 中装载它们的正确顺序。

img/497763_1_En_9_Fig5_HTML.jpg

图 9-5

加载外部 JavaScript 库的正确顺序

正如你在图 9-5 中看到的,我引用了 Twitter Bootstrap JavaScript 文件的 CDN 版本。我在 jQuery 和 Popper 文件之后加载它,因为 Twitter Bootstrap JavaScript 依赖于 jQuery 和 Popper。

请注意,如果您想要添加自定义的,也就是您自己的 JavaScript 文件,您必须将它们放在正确的位置。您自己的定制 JavaScript 文件需要放在第三方 JavaScript 文件之后,也就是 Twitter 引导 JavaScript 引用之后(图 9-6 )。

img/497763_1_En_9_Fig6_HTML.jpg

图 9-6

自定义 JavaScript 文件正确位置

模态标记

准备好最基本的 HTML 页面后,让我们在上面添加一些模态功能。将列表 9-2 的内容添加到页面的body中,作为body元素的第一个子元素。

<div class="modal fade" tabindex="-1" role="dialog">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">

                <h4 class="modal-title">This is an h4 inside Modal Header</h4>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
            </div>

            <div class="modal-body">

                <p>This is a paragraph inside Modal Body</p>

            </div>
            <div class="modal-footer">

                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                <button type="button" class="btn btn-primary">Save changes</button>

            </div>
        </div>
    </div>
</div>

Listing 9-2HTML Markup for a Modal

如果您在浏览器上保存并加载该页面,您将看到一个空白页。这是因为模态不应该被显示,除非用户选择这样做,或者他们执行了触发模态显示的动作。

使模态内容不可见的类是类modalfademodal加一个display:none;,fade加一个opacity: 0

在下图中可以看到禁用这两个属性是如何让模态出现在页面上的(图 9-7 )。

img/497763_1_En_9_Fig7_HTML.jpg

图 9-7

禁用属性以显示模式

所有的模态都有相同的 HTML 标记。其主要零件如图 9-8 所示。

img/497763_1_En_9_Fig8_HTML.jpg

图 9-8

模态 HTML 标记的主要部分

  • 在同一个嵌套级别中,有三个兄弟节点div,它们都是具有类modal-content的 div 的子节点:

    1. 类别为modal-header的模态头的div

    2. A div用于具有类别modal-body的模态体

    3. 一个div用于带有类modal-footer的模态页脚

  • 三个div相互串联,它们包含了情态的实际内容:

    1. 一个带有类modalfadediv

    2. 一个div在前一个modal fade在后一个modal-dialog

    3. 一个div在前一个modal-dialog在后一个modal-content

请注意,最后三个部分是可选的。同样,在它们里面,你可以放置(几乎)任何你喜欢的 HTML 标记。

触发模式

模态是隐藏的,直到用户采取行动显示它们,或者直到 web 应用程序决定必须显示它们。这种触发是如何发生的?

您将通过引入一个允许用户打开模式对话框的按钮来继续这个示例。让我们将 HTML 主体内容修改如下:

<button class="btn btn-lg btn-success" data-toggle="modal" data-target=".modal">Open Modal</button>

将前面的标记添加到模式开始标记div之前,开始标记<body>之下。

保存 HTML 页面并在浏览器上重新加载。您将看到以下内容(图 9-9 )。

img/497763_1_En_9_Fig9_HTML.jpg

图 9-9

带有打开模式按钮的页面

如果您点击按钮Open Modal,,您将看到以下内容(图 9-10 )。

img/497763_1_En_9_Fig10_HTML.jpg

图 9-10

单击按钮后显示的模式

完美!这就是模态。

让我们解释一下关于button标记的一些重要细节:

  1. 它具有值为modal的属性data-toggle。这是必要的,以向 Bootstrap 表明这是一个按钮,单击它将打开一个模式对话框。

  2. 它有一个属性data-target,该属性的值是一个 CSS 选择器,并且需要唯一地选择保存模式 HTML 标记的 HTML 元素。在您正在开发的模态中,您已经使用了值modal,因为这是唯一匹配保存您的模态标记的div的类。通常,在这里,您使用一个 CSS 选择器来表示一个 id,而不是一个类,以使标识唯一并避免歧义。

注意,通过这个小小的 HTML 标记和使用 Twitter Bootstrap 识别的数据属性,您已经成功地向页面添加了动态行为。您不必编写任何 JavaScript。所有这些模态 JavaScript 功能都由 Twitter Bootstrap JavaScript 库提供。

关于模态标记的更多信息

除了我之前谈到的标准 HTML 模态标记之外,上一个例子中还有一些其他元素值得你注意(图 9-11 )。

右上角的关闭[x]按钮

img/497763_1_En_9_Fig11_HTML.jpg

图 9-11

[x]按钮

用户可以单击右上角的[x]按钮来关闭模式对话框。它的标记被放在了modal-header div中,如下所示:

<button type="button" class="close" data-dismiss="modal" aria-label="Close">
  <span aria-hidden="true">&times;</span>
</button>

它是类closebutton,数据属性data-dismiss等于modal,指示 Twitter Bootstrap 在被点击时关闭模态。出现在那里的真正图标是<span aria-hidden="true">&times;</span>&times;实体元素是一个特殊字符,显示为十字[x]。

button中,您可以使用任何适合的 HTML,它可以向用户指示关闭模态的能力。例如,你可以使用一个字体牛逼图标。让我们试着用其中的一个。将 HTML 标记<span aria-hidden="true">&times;</span>替换为

<i aria-hidden="true" class="fas fa-window-close"></i>.

此外,在页面底部,在引用 Bootstrap JavaScript 文件之前,添加一个对为您的帐户设计的 FontAwesome 特殊工具包的引用。应该是这样一行:

<script src="https://kit.fontawesome.com/<your-account-kid-id>.js" crossorigin="anonymous"></script>

保存,重新加载页面,并打开模式。您将看到以下内容(图 9-12 )。

img/497763_1_En_9_Fig12_HTML.jpg

图 9-12

FontAwesome 图标用作模式关闭按钮

Note

在 FontAwesome 上创建一个帐户非常简单。你访问页面 https://fontawesome.com ,然后注册。然后你需要创建一个工具包。该网站将指导您如何获取套件标识符,以便在您的 HTML 页面中引用/使用它。

底部的关闭[Close]按钮

modal-footer div里面有一个按钮,工作原理和右上角的那个一样。它关闭模式对话框。它的标记是

<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>

同样,重要的是它的数据属性data-dismiss等于modal,这使得它的功能相当于一个模态关闭按钮。

Note

Save changes是一个什么也不做的按钮。我没有给它附加任何功能。

添加图像

正如我前面说过的,您可以在模态中添加(几乎)任何 HTML 内容。让我们看看下面的 HTML 页面(清单 9-3 )。

<!DOCTYPE html>
<html lang="en">
<head>
  <!-- Required meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

  <!-- Custom CSS -->
  <link rel="stylesheet" href="stylesheets/main.css" type="text/css">

  <title>Modal Dialogs</title>
</head>
<body>

  <button class="btn btn-lg btn-success" data-toggle="modal" data-target=".modal">Open Modal</button>

  <div class="modal fade" tabindex="-1" role="dialog">
    <div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">

          <h4 class="modal-title">Zakynthos - Shipwreck</h4>
          <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span>&times;</span>
          </button>

        </div>

        <div class="modal-body">

          <img src="img/zakynthos-shipwreck.jpg" alt="Zakynthos Shipwreck"/>

        </div>
        <div class="modal-footer">

          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
          <button type="button" class="btn btn-primary">Save changes</button>

        </div>
      </div>
    </div>
  </div>

  <!-- jQuery first, then Popper.js, then Bootstrap JS -->
  <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>
</html>

Listing 9-3HTML for a Modal with Image

如果您阅读 HTML,您会看到modal-body div只包含一个img元素。

另外,请注意,有一个对名为stylesheets/main.css的外部定制样式表文件的引用。请在里面添加下面的 CSS 规则。它将在图像周围添加一个边框:

img {
    border: 1px solid Darkblue;
}

如果您在浏览器上保存并加载该页面,您将看到以下内容(图 9-13 )。

img/497763_1_En_9_Fig13_HTML.jpg

图 9-13

具有 img 元素的模式—宽图像的问题

如你所见,图像有问题。它超越了模态的界限。为了解决这个问题,您必须将类img-fluid附加到img元素上。这样做并重新加载页面。您将看到以下内容(图 9-14 )。

img/497763_1_En_9_Fig14_HTML.jpg

图 9-14

图像在模态中正确显示

添加 YouTube 视频

就像您对图像所做的那样,您可以类似地添加一个 YouTube 嵌入式视频参考。尝试下面的 HTML(清单 9-4 )。

<!DOCTYPE html>
<html lang="en">
<head>
  <!-- Required meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

  <!-- Custom CSS -->
  <link rel="stylesheet" href="stylesheets/main.css" type="text/css">

  <title>Modal Dialogs</title>
</head>
<body>

  <button class="btn btn-lg btn-success" data-toggle="modal" data-target=".modal">Open Modal</button>

  <div class="modal fade" tabindex="-1" role="dialog">
    <div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">

          <h4 class="modal-title">Zakynthos - Shipwreck</h4>
          <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span>&times;</span>
          </button>

        </div>

        <div class="modal-body">

          <iframe width="100%" height="315" src="https://www.youtube.com/embed/tqy0Uvw_bFU" frameborder="0" allowfullscreen></iframe>

        </div>
        <div class="modal-footer">

          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
          <button type="button" class="btn btn-primary">Save changes</button>

        </div>
      </div>
    </div>
  </div>

  <!-- jQuery first, then Popper.js, then Bootstrap JS -->
  <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>
</html>

Listing 9-4Embedding a YouTube Video

正如您在前面的代码中看到的,您可以使用iframe元素嵌入 YouTube 视频。确保width设置为 100%,并且height设置为合理的高度,这将保持您的视频以正确的纵横比显示。请注意,当您选择通过嵌入分享视频时,YouTube 会为您提供iframe元素的代码。您只需要调整宽度和高度属性,这样视频就可以很好地显示在您的模态中。

如果您保存前面的 HTML 并在浏览器上加载页面,您将看到以下内容(图 9-15 )。

img/497763_1_En_9_Fig15_HTML.jpg

图 9-15

有 YouTube 视频的模特

可选尺寸

Twitter Bootstrap 为您的模特提供三种可选尺寸:

  1. 超大模态:您需要在modal-dialog类后面追加modal-xl类。它基本上将模态max-width设置为1140px

  2. 大型模态:您需要在modal-dialog类后面追加modal-lg类。它将max-width设置为800px

  3. 小模态:您需要在modal-dialog类后面追加modal-sm类。它将max-width设置为300px

如果您没有指定任何前面的大小等级,那么默认设置为max-width500px

下一个是大尺寸的模态演示(清单 9-5 )。

<!DOCTYPE html>
<html lang="en">
<head>
  <!-- Required meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

  <!-- Custom CSS -->
  <link rel="stylesheet" href="stylesheets/main.css" type="text/css">

  <title>Modal Dialogs</title>
</head>
<body>

  <button class="btn btn-lg btn-success" data-toggle="modal" data-target=".modal">Open Modal</button>

  <div class="modal fade" tabindex="-1" role="dialog">
    <div class="modal-dialog modal-lg">
      <div class="modal-content">
        <div class="modal-header">

          <h4 class="modal-title">Zakynthos from Wikipedia</h4>
          <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span>&times;</span>
          </button>

        </div>

        <div class="modal-body">

          <iframe width="100%" height="400" src="https://en.wikipedia.org/wiki/Zakynthos" id="frame-in-modal"></iframe>

        </div>
        <div class="modal-footer">

          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
          <button type="button" class="btn btn-primary">Save changes</button>

        </div>
      </div>
    </div>
  </div>

  <!-- jQuery first, then Popper.js, then Bootstrap JS -->
  <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>
</html>

Listing 9-5Large Modal Demo

如果您保存该页面的文件并将其加载到您的浏览器上,您将看到以下内容(图 9-16 )。

img/497763_1_En_9_Fig16_HTML.jpg

图 9-16

大型模态演示

移除动画

如果你已经注意到,当你打开模态的时候,它从上到下的动画。您可以通过从顶层div容器中移除类fade来移除这个动画,并使模态立即出现。

试着从前面的例子中移除fade类。您将在动画中看到没有顶部淡入淡出的模态。

使用 Twitter 引导网格系统

您可以在 modal 的主体中使用 Twitter Bootstrap 网格系统。在modal-body div容器中适当地使用container-fluid,然后使用rowcolumn-xx-x类。

我们来看一个例子(清单 9-6 )。

<!DOCTYPE html>
<html lang="en">
<head>
  <!-- Required meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

  <!-- Custom CSS -->
  <link rel="stylesheet" href="stylesheets/main.css" type="text/css">

  <title>Modal Dialogs</title>
</head>
<body>

  <button class="btn btn-lg btn-success" data-toggle="modal" data-target=".modal">Open Modal</button>

  <div class="modal fade" tabindex="-1" role="dialog">
    <div class="modal-dialog modal-lg">
      <div class="modal-content">
        <div class="modal-header">

          <h4 class="modal-title">Zakynthos from Wikipedia</h4>
          <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span>&times;</span>
          </button>

        </div>

        <div class="modal-body">

          <div class="container-fluid">
            <div class="row">
              <div class="col-md-6">
                <img src="img/ithaki-1.jpg" alt="Ithaki"/>
              </div>
              <div class="col-md-6">
                <img src="img/elafonisos-2.jpg" alt="Elafonisos"/>
              </div>

            </div>

            <div class="row">
              <div class="col-md-6">
                <img src="img/karpathos-3.jpg" alt="Karpathos"/>
              </div>
              <div class="col-md-6">
                <img src="img/chios-4.jpg" alt="Chios"/>
              </div>
            </div>
          </div>

        </div> <!-- modal body -->

        <div class="modal-footer">

          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
          <button type="button" class="btn btn-primary">Save changes</button>

        </div>
      </div>
    </div>
  </div>

  <!-- jQuery first, then Popper.js, then Bootstrap JS -->
  <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>
</html>

Listing 9-6Grid System Inside the Modal Body

这是 CSS:

img {
    padding: 10px 10px;
    width: 100%;
    height: 250px;
}

如果您保存前面的代码并在浏览器上加载页面,当您打开模式时,您将看到以下内容(图 9-17 )。

img/497763_1_En_9_Fig17_HTML.jpg

图 9-17

模体内部使用的网格系统

垂直居中

模式的默认行为是出现在页面的顶部。如果你想让模态出现在中间,也就是垂直对齐,那么你就得在modal-dialog类旁边附加modal-dialog-centered类。

清单 9-7 展示了这一点。

<!DOCTYPE html>
<html lang="en">
<head>
  <!-- Required meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

  <title>Modal Dialogs</title>
</head>
<body>
  <button class="btn btn-lg btn-success" data-toggle="modal" data-target=".modal">Open Modal</button>

  <div class="modal fade" tabindex="-1" role="dialog">
    <div class="modal-dialog modal-dialog-centered">
      <div class="modal-content">
        <div class="modal-header">

          <h4 class="modal-title">This is an h4 inside Modal Header</h4>
          <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>

        </div>

        <div class="modal-body">

          <p>This is a paragraph inside Modal Body</p>

        </div>
        <div class="modal-footer">

          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
          <button type="button" class="btn btn-primary">Save changes</button>

        </div>
      </div>
    </div>
  </div>

  <!-- Optional JavaScript -->
  <!-- jQuery first, then Popper.js, then Bootstrap JS -->
  <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>

</body>
</html>

Listing 9-7Modal Vertically Centered

如果您保存此页面,将其加载到您的浏览器上,并打开模式,您将看到以下内容(图 9-18 )。

img/497763_1_En_9_Fig18_HTML.jpg

图 9-18

模态垂直居中

如您所见,模态出现在垂直居中位置。

用 JavaScript 激活模态

您已经看到,您可以在不使用任何 JavaScript 代码的情况下激活一个模态。您使用的按钮示例如下所示:

<button class="btn btn-lg btn-success" data-toggle="modal" data-target=".modal">Open Modal</button>

这里重要的位是data-toggle="modal"data-target=".modal"

你也可以用 JavaScript 打开一个模态对话框。让我们再次看看(清单 9-8 )希腊群岛的例子,但是这一次,您将不会像上一个例子那样使用按钮。

<!DOCTYPE html>
<html lang="en">
<head>
  <!-- Required meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

  <!-- Custom CSS -->
  <link rel="stylesheet" href="stylesheets/main.css" type="text/css">

  <title>Modal Dialogs</title>
</head>
<body>

  <button class="btn btn-lg btn-success" id="open-modal-button">Open Modal</button>

  <div class="modal fade" tabindex="-1" role="dialog">
    <div class="modal-dialog modal-lg">
      <div class="modal-content">
        <div class="modal-header">

          <h4 class="modal-title">Zakynthos from Wikipedia</h4>
          <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span>&times;</span>
          </button>

        </div>

        <div class="modal-body">

          <div class="container-fluid">
            <div class="row">
              <div class="col-md-6">
                <img src="img/ithaki-1.jpg" alt="Ithaki"/>
              </div>
              <div class="col-md-6">
                <img src="img/elafonisos-2.jpg" alt="Elafonisos"/>
              </div>
            </div>

            <div class="row">
              <div class="col-md-6">
                <img src="img/karpathos-3.jpg" alt="Karpathos"/>
              </div>
              <div class="col-md-6">
                <img src="img/chios-4.jpg" alt="Chios"/>
              </div>
            </div>
          </div>

        </div> <!-- modal body -->

        <div class="modal-footer">

          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
          <button type="button" class="btn btn-primary">Save changes</button>

        </div>
      </div>
    </div>
  </div>

  <!-- jQuery first, then Popper.js, then Bootstrap JS -->
  <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>

  <!-- Custom JavaScript -->
  <script src="javascripts/open-dialog.js"></script>
</body>
</html>

Listing 9-8Greek Islands with JavaScript to Open the Modal

前面的文件与以前的版本有两个不同之处:

  1. 它引用一个带有自定义 JavaScript 代码的 JavaScript 文件。文件是javascripts/open-dialog.js。参见文件底部的引用,在结束的body标签之前。

  2. 另一个是打开模态的按钮不再具有模态相关的data-属性。

在没有给出open-dialog.js内容的情况下,如果您保存前面的代码,在浏览器上加载页面,并尝试通过单击按钮打开对话框,什么都不会发生。

为了打开对话框,您现在需要提供相应的 JavaScript 命令:

$(document).ready(function() {
   $('#open-modal-button').on('click', function() {
      $('.modal').modal();
      return false;
   });
});

如果您将前面的代码保存在javascripts/open-dialog.js文件中并重新加载页面,那么当您单击Open Modal按钮时,模式对话框将会打开。

这里的新东西是:

$('.modal').modal();

它在按钮#open-modal-button的 click 处理程序的实现中。所以,当你点击这个按钮时,你调用了 Twitter Bootstrap JavaScript 库的modal()方法。这在选择与$('.modal');匹配的元素时调用,因此在模态div容器上调用。

模式和选项

当调用$(...).modal()方法时,你可以给一个 JavaScript 对象提供模态函数的选项。您可以提供的选项如下:

img/497763_1_En_9_Fig19_HTML.jpg

图 9-19

无背景模式

  1. backdrop:布尔值,默认值为true。它也可以是值为static的字符串。如果您将该值设置为false,那么模态将在没有背景的情况下打开,并且您将无法在模态之外点击来关闭它(图 9-19 )。

打开无背景模式的代码如下:

$(document).ready(function() {
   $('#open-modal-button').on('click', function() {
      $('.modal').modal({
          backdrop: false
      });
      return false;
   });
});

如果你将backdrop的值设置为static,,那么它将打开带有背景的模态,但是你不能通过点击模态区域之外来关闭模态。

如果您将backdrop设置为true,那么它将打开带有背景的模态,您可以通过在模态区域外单击来关闭模态。

  1. keyboard:布尔值,默认值为true。当true,时,点击<ESC>键关闭模态。

  2. show:布尔值,默认值为true。它显示了初始化时的模态。这是很有用的,因为你可能想要初始化一个模态,而不真正显示它,直到后来。将javascripts/open-dialog.js中的 JavaScript 代码修改如下(清单 9-9 )。

$(document).ready(function() {
    $('.modal').modal({
        backdrop: 'static',
        keyboard: false,
        show: false
    });

    $('#open-modal-button').on('click', function() {
        $('.modal').modal('show');
        return false;
   });
});

Listing 9-9Initialize Modal Without Opening

这和原版差别不大。但是它更好,因为它将功能一分为二。首先,它初始化模态;然后,当按钮被点击时,它就显示出来。

modal({....});初始化模态和用调用modal('show');显示已经初始化的模态都属于模态方法的范畴。让我们看看更多关于他们的细节。

模态方法

下面是模态方法的列表:

  1. .modal('show');
$('modal-selector').modal('show');

它用于显示一个初始化的模态。

  1. .modal('hide');
$('modal-selector').modal('hide');

它用于隐藏已初始化的模态。

  1. .modal('toggle');
$('modal-selector').modal('toggle');

它用于隐藏打开的模态或显示隐藏的模态。

模态事件

你可能已经知道 JavaScript 编程涉及到很多事件编程。很多 JavaScript 插件都定义了它们的自定义事件。Twitter Bootstrap 模型也是如此。

以下是针对模型本身触发的事件:

  1. show.bs.modal:当调用show方法时,该事件立即触发。如果由点击引起,被点击的元素可作为事件的relatedTarget属性。

    我们来做一个例子(列表 9-10 )。

<!DOCTYPE html>
<html lang="en">
<head>
  <!-- Required meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

  <!-- Custom CSS -->
  <link rel="stylesheet" href="stylesheets/main.css" type="text/css">

  <title>Modal Dialogs</title>
</head>
<body>

  <button class="btn btn-lg btn-success" data-toggle="modal" data-target=".modal">Open Modal 1</button>
  <button class="btn btn-lg btn-success" data-toggle="modal" data-target=".modal">Open Modal 2</button>
  <button class="btn btn-lg btn-success" data-toggle="modal" data-target=".modal">Open Modal 3</button>

  <div class="modal fade" tabindex="-1" role="dialog">
    <div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">

          <h4 class="modal-title">Modal Demo of relatedTarget</h4>
          <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true" class="glyphicon glyphicon-remove"></span></button>

        </div>

        <div class="modal-body text-center">

        </div>
        <div class="modal-footer">

          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>

        </div>
      </div>
    </div>
  </div>

  <!-- jQuery first, then Popper.js, then Bootstrap JS -->
  <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>

  <!-- Custom JavaScript -->
  <script src="javascripts/related-target.js"></script>
</body>
</html>

Listing 9-10Demo of the show.bs.modal Event

前面的 HTML 页面正在使用 JavaScript 文件javascripts/related-target.js。这在清单 9-11 中给出。

$(document).ready(function(){
    $('.modal').on('show.bs.modal', function(event){
       var $buttonClicked = $(event.relatedTarget);

       $(this).find('.modal-body').html("<h1>" + $buttonClicked.html() + " Clicked!</h1>");
    });
});

Listing 9-11JavaScript File for Listing 9-10

从 HTML 标记中可以看出,模式对话框的modal-body是空的。您将使用 JavaScript 动态添加内容,对show.bs.modal事件做出反应。此外,您将添加的内容将与触发模式打开的按钮相关。如您所见,有三个按钮都可以打开模式对话框。

关于 JavaScript 文件内容,我在模态(.modal)目标的show.bs.modal事件上附加了一个处理程序。我还声明了参数event,当处理程序被调用时,它将持有relatedTarget。我将relatedTarget保存到$buttonClicked,,然后使用。html() jQuery 函数设置modal-body div的 html 内容。使用 jQuery 方法选择modal-body div。find()

这将是下面三幅图中描绘的最终结果,图 9-20 ,图 9-21 ,图 9-22 :

img/497763_1_En_9_Fig22_HTML.jpg

图 9-22

点击Third按钮时的页面模式

img/497763_1_En_9_Fig21_HTML.jpg

图 9-21

点击Second按钮时的页面模式

img/497763_1_En_9_Fig20_HTML.jpg

图 9-20

单击第一个按钮时的页面模式

  1. shown.bs.modal:当模态对用户可见,并且所有的fade转换完成后,这个事件被触发。如果由点击引起,被点击的元素可作为事件的relatedTarget属性。

  2. hide.bs.modal:当hide实例方法被调用时,该事件立即被触发。当您想要编写一些需要在模态被隐藏时执行的动作时,这可能是有用的。

  3. hidden.bs.modal:当模式对用户隐藏完成时,触发该事件(将等待 CSS 转换完成)。

  4. hidden.Prevented.bs.modal:此事件在以下情况下触发

    1. 显示了模态。

    2. 其背景是static

    3. 在模态外点击或点击<ESC>键。

任务和测验

Task Details

您需要实现一个页面,让用户选择两个最喜欢的城市之一。实际上

  1. 用户应该能够点击其中一个图像。单击时,模式应该关闭,所选图像应该显示在主页上占位符的位置。

  2. 以下是一些帮助你完成任务的提示:

    1. 你可能想要一个自定义的 CSS 文件。这将需要样式内的模态图像,以及主页上的中心图像。

    2. 您将需要一个定制的 JavaScript 文件:

      1. 它的职责是响应在模态对话框中的两个图像中的任何一个上执行的点击。

      2. 图像上的点击处理器需要

        1. 关闭模态。

        2. 用点击图像的src属性替换中心图像的src

  3. When the user clicks the button to open the modal, the modal should appear as follows (Figure 9-24):

    img/497763_1_En_9_Fig24_HTML.jpg

    图 9-24

    任务-有城市可供选择的模式

  4. When the page loads, it has the button to open the modal and an image placeholder, like this (Figure 9-23):

    img/497763_1_En_9_Fig23_HTML.jpg

    图 9-23

    任务—带有打开模式按钮和图像占位符的页面

关键要点

  • 如何实现模式对话框

  • 模式对话框部分,页眉、正文和页脚

  • 模特的背景

  • 如何垂直居中模式

  • 如何在模体内部使用网格系统

  • 如何去除打开时的渐变效果

  • 如何显示模态体内部的图像

  • 如何在 modal 的主体中显示 YouTube 视频

  • 如何打开小模态和大模态

  • 如何使用其选项自定义模式

  • 如何使用模态的方法

  • 如何附加到不同的模态事件

在下一章中,你将学习如何创建一个有很长内容的页面,旁边有一个导航栏,它的活动菜单根据内容在窗口中的位置而变化。

十、ScrollSpy(滚动新闻)

长内容页面通常有顶部导航栏,允许用户快速导航到页面中的各个部分。这个特性伴随着这样一个事实,即突出显示为活动的菜单项根据页面的可见部分自动更新/改变。ScrollSpy 是一个 Twitter Bootstrap JavaScript 插件,在使用时,它会根据文档中的位置自动改变高亮显示的菜单项。

在这一章中,你将学习 Twitter Bootstrap 如何让你在你的长内容页面中快速加入这样一个特性。

学习目标

  1. 了解如何向长内容页面添加 scrollspying 功能。

  2. 了解应该如何设置 HTML 标记来支持 scrollspying。

  3. 了解如何调整滚动部分的偏移量和激活点。

有菜单的长页

让我们从一个带菜单的长 HTML 页面开始(清单 10-1 )。

<!DOCTYPE html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

    <!-- Custom CSS -->
    <link rel="stylesheet" href="stylesheets/main.css" type="text/css">

    <title>ScrollSpy</title>
</head>
<body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
        <div class="container">
            <a class="navbar-brand" href="main.html">Home</a>

            <button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar"
                    aria-controls="navbar"
                    aria-expanded="false"
                    aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>

            <div class="collapse navbar-collapse" id="navbar">
                <ul class="nav navbar-nav">
                    <li class="nav-item">
                        <a class="nav-link active" href="#introduction">Introduction<span class="sr-only">(current)</span></a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#origins">Origins</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#creating-new-state-constitutions">State Constitutions</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#military-hostilities-begin">Military Hostilities</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#independence-and-union">Independence And Union</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#more">More</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>

    <div class="container">
        <h1 id="introduction">American Revolution History</h1>

        <h2>Introduction</h2>

        <p>
            The American Revolution was a political upheaval that took place between 1765 and 1783 during which colonists in the Thirteen American Colonies rejected the British monarchy and aristocracy, overthrew the authority of Great Britain, and founded the United States of America.
        </p>

        <p>
            Starting in 1765, members of American colonial society rejected the authority of the British Parliament to tax them and create other laws affecting them, without colonial representatives in the government. During the following decade, protests by colonists—known as Patriots—continued to escalate, as in the Boston Tea Party in 1773 during which patriots destroyed a consignment of taxed tea from the Parliament-controlled and favored East India Company.[1] The British responded by imposing punitive laws—the Coercive Acts—on Massachusetts in 1774, following which Patriots in the other colonies rallied behind Massachusetts. In late 1774 the Patriots set up their own alternative government to better coordinate their resistance efforts against Great Britain, while other colonists, known as Loyalists, preferred to remain aligned to the British Crown.
        </p>
        <p>
            Tensions escalated to the outbreak of fighting between Patriot militia and British regulars at Lexington and Concord in April 1775\. The conflict then evolved into a global war, during which the Patriots (and later their French, Spanish, and Dutch allies) fought the British and Loyalists in what became known as the American Revolutionary War (1775–1783). Patriots in each of the thirteen colonies formed Provincial Congresses that assumed power from the old colonial governments and suppressed Loyalism, and from there built a Continental Army under the leadership of General George Washington. Claiming King George III's rule to be tyrannical and infringing the colonists' "rights as Englishmen", the Continental Congress declared the colonies free and independent states in July 1776\. The Patriot leadership professed the political philosophies of liberalism and republicanism to reject monarchy and aristocracy, and proclaimed that all men are created equal. Congress rejected British proposals requiring allegiance to the monarchy and abandonment of independence.
        </p>

        <p>
            The British were forced out of Boston in 1776, but then captured and held New York City for the duration of the war. The British blockaded the ports and captured other cities for brief periods, but failed to defeat Washington's forces. In early 1778, following a failed patriot invasion of Canada, a British army was captured at the Battle of Saratoga, following which the French openly entered the war as allies of the United States. The war later turned to the American South, where the British captured an army at South Carolina, but failed to enlist enough volunteers from Loyalist civilians to take effective control. A combined American–French force captured a second British army at Yorktown in 1781, effectively ending the war in the United States. The Treaty of Paris in 1783 formally ended the conflict, confirming the new nation's complete separation from the British Empire. The United States took possession of nearly all the territory east of the Mississippi River and south of the Great Lakes, with the British retaining control of Canada and Spain taking Florida.[2][3]
        </p>

        <p>
            Among the significant results of the revolution was the creation of a new Constitution of the United States. The 'Three-Fifths Compromise' allowed the southern slaveholders to consolidate power and maintain slavery in America for another eighty years,[4] but through the expansion of voting rights and liberties over subsequent decades the elected government became responsible to the will of the people.[5] The new Constitution established a relatively strong federal national government that included an executive, a national judiciary, and a bicameral Congress that represented both states in the Senate and population in the House of Representatives.[6][7]
        </p>

        <p>
            Among the significant results of the revolution was the creation of a new Constitution of the United States. The 'Three-Fifths Compromise' allowed the southern slaveholders to consolidate power and maintain slavery in America for another eighty years,[4] but through the expansion of voting rights and liberties over subsequent decades the elected government became responsible to the will of the people.[5] The new Constitution established a relatively strong federal national government that included an executive, a national judiciary, and a bicameral Congress that represented both states in the Senate and population in the House of Representatives.[6][7]
        </p>

        <h2 id="origins">Origins</h2>

        <p>
            Historians typically begin their histories of the American Revolution with the British victory in the French and Indian War in 1763, which removed France as a major player in North American affairs. Lawrence Henry Gipson, the historian of the British Empire, states:
        </p>

        <p>
            It may be said as truly that the American Revolution was an aftermath of the Anglo-French conflict in the New World carried on between 1754 and 1763.[8]
        </p>

        <p>
            The Royal Proclamation of 1763 may have played a role in the separation of the United States from Great Britain as colonists at the time wanted to continue in the economically beneficial cultural practice of taking land for one's own livelihood as part of the drive west. The lands west of Quebec and west of a line running along the crest of the Allegheny mountains became Indian territory, temporarily barred from settlement (to the great disappointment of the land speculators of Virginia and Pennsylvania, who had started the Seven Years' War to gain those territories).
        </p>

        <p>
            For the prior history see Thirteen Colonies.
        </p>

        <h3>1764–1766: Taxes imposed and withdrawn</h3>

        <p>
            In 1764 Parliament passed the Currency Act to restrain the use of paper money that British merchants saw as a means to evade debt payments.[original research?] Parliament also passed the Sugar Act imposing customs duties on a number of articles. That same year Prime Minister George Grenville proposed to impose direct taxes on the colonies to raise revenue, but delayed action to see if the colonies would propose some way to raise the revenue themselves.[citation needed] None did, and in March 1765 Parliament passed the Stamp Act which imposed direct taxes on the colonies for the first time. All official documents, newspapers, almanacs and pamphlets—even decks of playing cards—were required to have the stamps.
        </p>

        <p>
            The colonists objected chiefly on the grounds not that the taxes were high (they were low),[9] but because they had no representation in the Parliament. Benjamin Franklin testified in Parliament in 1766 that Americans already contributed heavily to the defense of the Empire. He said local governments had raised, outfitted and paid 25,000 soldiers to fight France—as many as Britain itself sent—and spent many millions from American treasuries doing so in the French and Indian War alone.[10][11] Stationing a standing army in Great Britain during peacetime was politically unacceptable. London had to deal with 1,500 politically well-connected British officers who became redundant; it would have to discharge them or station them in North America.[12]
        </p>

        <p>
            In 1765 the Sons of Liberty formed. They used public demonstrations, boycotts, violence and threats of violence to ensure that the British tax laws were unenforceable. While openly hostile to what they considered an oppressive Parliament acting illegally, colonists persisted in sending numerous petitions and pleas for intervention from a monarch to whom they still claimed loyalty. In Boston, the Sons of Liberty burned the records of the vice admiralty court and looted the home of the chief justice, Thomas Hutchinson. Several legislatures called for united action, and nine colonies sent delegates to the Stamp Act Congress in New York City in October 1765\. Moderates led by John Dickinson drew up a "Declaration of Rights and Grievances" stating that taxes passed without representation violated their rights as Englishmen. Colonists emphasized their determination by boycotting imports of British merchandise.[13]
        </p>

        <p>
            The Parliament at Westminster saw itself as the supreme law making authority throughout all British possessions and thus entitled to levy any tax without colonial approval.[14] They argued that the colonies were legally British corporations that were completely subordinate to the British parliament and pointed to numerous instances where Parliament had made laws binding on the colonies in the past.[15] They did not see anything in the unwritten British constitution that made taxes special[16] and noted that Parliament had taxed American trade for decades. Parliament insisted that the colonies effectively enjoyed a "virtual representation" like most British people did, as only a small minority of the British population elected representatives to Parliament.[17] Americans such as James Otis maintained the Americans were not in fact virtually represented.[18]
        </p>

        <p>
            In London, the Rockingham government came to power (July 1765) and Parliament debated whether to repeal the stamp tax or to send an army to enforce it. Benjamin Franklin made the case for repeal, explaining the colonies had spent heavily in manpower, money, and blood in defense of the empire in a series of wars against the French and Indians, and that further taxes to pay for those wars were unjust and might bring about a rebellion. Parliament agreed and repealed the tax (February 21, 1766), but in the Declaratory Act of March 1766 insisted that parliament retained full power to make laws for the colonies "in all cases whatsoever".[19] The repeal nonetheless caused widespread celebrations in the colonies.
        </p>

        <p>
            Briggs says unnamed modern American economic historians have challenged the view that Great Britain was placing a heavy burden on the North American colonies and have suggested the cost of defending them from the possibility of invasion by France or Spain was £400,000 – five times the maximum income from them. Briggs rejects the analysis, saying that issue was not invoked at the time.[20]
        </p>

        <h3>1767–1773: Townshend Acts and the Tea Act</h3>

        <p>
            In 1767 the Parliament passed the Townshend Acts, which placed duties on a number of essential goods including paper, glass, and tea and established a Board of Customs in Boston to more rigorously execute trade regulations. The new taxes were enacted on the belief that Americans only objected to internal taxes and not external taxes like custom duties. The Americans, however, argued against the constitutionality of the act because its purpose was to raise revenue and not regulate trade. Colonists responded by organizing new boycotts of British goods. These boycotts were less effective, however, as the Townshend goods were widely used.
        </p>

        <p>
            In February 1768 the Assembly of Massachusetts Bay issued a circular letter to the other colonies urging them to coordinate resistance. The governor dissolved the assembly when it refused to rescind the letter. Meanwhile, in June 1768 a riot broke out in Boston over the seizure of the sloop Liberty, owned by John Hancock, for alleged smuggling. Custom officials were forced to flee, prompting the British to deploy troops to Boston. A Boston town meeting declared no obedience was due to parliamentary laws and called for the convening of a convention. A convention assembled but only issued a mild protest before dissolving itself. In January 1769 Parliament responded to the unrest by reactivating the Treason Act 1543 which permitted subjects outside the realm to face trials for treason in England. The governor of Massachusetts was instructed to collect evidence of said treason, and although the threat was not carried out it caused widespread outrage.
        </p>

        <p>
            On March 5, 1770 a large mob gathered around a group of British soldiers. The mob grew more and more threatening, throwing snowballs, rocks and debris at the soldiers. One soldier was clubbed and fell.[21] There was no order to fire but the soldiers fired into the crowd anyway. They hit 11 people; three civilians died at the scene of the shooting, and two died after the incident. The event quickly came to be called the Boston Massacre. Although the soldiers were tried and acquitted (defended by John Adams), the widespread descriptions soon became propaganda to turn colonial sentiment against the British. This in turn began a downward spiral in the relationship between Britain and the Province of Massachusetts.[21]
        </p>

        <p>
            A new ministry under Lord North came to power in 1770 and Parliament withdrew all taxes except the tax on tea, giving up its efforts to raise revenue while maintaining the right to tax. This temporarily resolved the crisis and the boycott of British goods largely ceased, with only the more radical patriots such as Samuel Adams continuing to agitate.
        </p>

        <p>
            Two ships in a harbor, one in the distance. On board, men stripped to the waist and wearing feathers in their hair are throwing crates into the water. A large crowd, mostly men, is standing on the dock, waving hats and cheering. A few people wave their hats from windows in a nearby building.
            This 1846 lithograph by Nathaniel Currier was entitled "The Destruction of Tea at Boston Harbor"; the phrase "Boston Tea Party" had not yet become standard.[22]
        </p>

        <p>
            In June 1772, in what became known as the Gaspee Affair, American patriots including John Brown burned a British warship that had been vigorously enforcing unpopular trade regulations. The affair was investigated for possible treason, but no action was taken.
        </p>

        <p>
            In 1772 it became known that the Crown intended to pay fixed salaries to the governors and judges in Massachusetts. Samuel Adams in Boston set about creating new Committees of Correspondence, which linked Patriots in all 13 colonies and eventually provided the framework for a rebel government. In early 1773 Virginia, the largest colony, set up its Committee of Correspondence, on which Patrick Henry and Thomas Jefferson served.[23]
        </p>

        <p>
            A total of about 7000 to 8000 Patriots served on "Committees of Correspondence" at the colonial and local levels, comprising most of the leadership in their communities — Loyalists were excluded. The committees became the leaders of the American resistance to British actions, and largely determined the war effort at the state and local level. When the First Continental Congress decided to boycott British products, the colonial and local Committees took charge, examining merchant records and publishing the names of merchants who attempted to defy the boycott by importing British goods.[24]
        </p>

        <p>
            In 1773 private letters were published where Massachusetts Governor Thomas Hutchinson claimed the colonists could not enjoy all English liberties, and Lieutenant Governor Andrew Oliver called for the direct payment of colonial officials. The letters, whose contents were used as evidence of a systematic plot against American rights, discredited Hutchinson in the eyes of the people the Assembly petitioned for his recall. Benjamin Franklin, postmaster general for the colonies, acknowledged that he leaked the letters which led to him being berated by British officials and fired from his job.
        </p>

        <p>
            Meanwhile, Parliament passed the Tea Act to lower the price of taxed tea exported to the colonies in order to help the East India Company undersell smuggled Dutch tea. Special consignees were appointed to sell the tea in order to bypass colonial merchants. The act was opposed not only by those who resisted the taxes but also by smugglers who stood to lose business. In most instances the consignees were forced to resign and the tea was turned back, but Massachusetts governor Hutchinson refused to allow Boston merchants to give into pressure. A town meeting in Boston determined that the tea would not be landed, and ignored a demand from the governor to disperse. On December 16, 1773 a group of men, led by Samuel Adams and dressed to evoke the appearance of American Indians, boarded the ships of the British East India Company and dumped £10,000 worth of tea from their holds (approximately £636,000 in 2008) into Boston Harbor. Decades later this event became known as the Boston Tea Party and remains a significant part of American patriotic lore.[25]
        </p>

        <h3>1774–1775: Intolerable Acts and the Quebec Act</h3>

        <p>
            The British government responded by passing several Acts which came to be known as the Intolerable Acts, which further darkened colonial opinion towards the British. They consisted of four laws enacted by the British parliament.[26] The first, the Massachusetts Government Act, altered the Massachusetts charter and restricted town meetings. The second Act, the Administration of Justice Act, ordered that all British soldiers to be tried were to be arraigned in Britain, not in the colonies. The third Act was the Boston Port Act, which closed the port of Boston until the British had been compensated for the tea lost in the Boston Tea Party. The fourth Act was the Quartering Act of 1774, which allowed royal governors to house British troops in the homes of citizens without requiring permission of the owner.[27]
        </p>

        <p>
            In response, Massachusetts patriots issued the Suffolk Resolves and formed an alternative shadow government known as the "Provincial Congress" which began training militia outside British-occupied Boston.[28] In September 1774, the First Continental Congress convened, consisting of representatives from each of the colonies, to serve as a vehicle for deliberation and collective action. During secret debates conservative Joseph Galloway proposed the creation of a colonial Parliament that would be able to approve or disapprove of acts of the British Parliament but his idea was not accepted. The Congress instead endorsed the proposal of John Adams that Americans would obey Parliament voluntarily but would resist all taxes in disguise. Congress called for a boycott beginning on 1 December 1774 of all British goods; it was enforced by new committees authorized by the Congress.[29]
        </p>

        <p>
            The Quebec Act of 1774 extended Quebec's boundaries to the Ohio River, shutting out the claims of the 13 colonies. By then, however, the Americans had little regard for new laws from London; they were drilling militia and organizing for war.[30]
        </p>

        <p>
            The British retaliated by confining all trade of the New England colonies to Britain and excluding them from the Newfoundland fisheries. Lord North advanced a compromise proposal in which Parliament would not tax so long as the colonies made fixed contributions for defense and to support civil government. This would also be rejected.
        </p>

        <h2 id="creating-new-state-constitutions">Creating New State Constitutions</h2>

        <p>
            Following the Battle of Bunker Hill in June 1775, the Patriots had control of Massachusetts outside the Boston city limits; the Loyalists suddenly found themselves on the defensive with no protection from the British army. In all 13 colonies, Patriots had overthrown their existing governments, closing courts and driving British officials away. They had elected conventions and "legislatures" that existed outside any legal framework; new constitutions were drawn up in each state to supersede royal charters. They declared that they were states now, not colonies.[31]
        </p>

        <p>
            On January 5, 1776, New Hampshire ratified the first state constitution. In May 1776, Congress voted to suppress all forms of crown authority, to be replaced by locally created authority. Virginia, South Carolina, and New Jersey created their constitutions before July 4\. Rhode Island and Connecticut simply took their existing royal charters and deleted all references to the crown.[32] The new states were all committed to republicanism, with no inherited offices. They decided not only what form of government to create, and also how to select those who would craft the constitutions and how the resulting document would be ratified. But there would be no universal suffrage and real power, including the right to elect the future President would still lay in the hands of a few selected elites for many years. On 26 May 1776 John Adams wrote James Sullivan from Philadelphia;
        </p>

        <p>
            "Depend upon it, sir, it is dangerous to open so fruitful a source of controversy and altercation, as would be opened by attempting to alter the qualifications of voters. There will be no end of it. New claims will arise. Women will demand a vote. Lads from twelve to twenty one will think their rights not enough attended to, and every man, who has not a farthing, will demand an equal voice with any other in all acts of state. It tends to confound and destroy all distinctions, and prostrate all ranks, to one common level".[33][34]
        </p>

        <p>
            In states where the wealthy exerted firm control over the process, such as Maryland, Virginia, Delaware, New York and Massachusetts – the last-mentioned of these state's constitutions still being in force in the 21st century, continuously since its ratification on June 15, 1780 – the results were constitutions that featured:
        </p>

        <p>
            Substantial property qualifications for voting and even more substantial requirements for elected positions (though New York and Maryland lowered property qualifications);[31]
            Bicameral legislatures, with the upper house as a check on the lower;
            Strong governors, with veto power over the legislature and substantial appointment authority;
            Few or no restraints on individuals holding multiple positions in government;
            The continuation of state-established religion.
        </p>

        <p>
            In states where the less affluent had organized sufficiently to have significant power—especially Pennsylvania, New Jersey, and New Hampshire—the resulting constitutions embodied
        </p>

        <p>
            universal white manhood suffrage, or minimum property requirements for voting or holding office (New Jersey enfranchised some property owning widows, a step that it retracted 25 years later);
            strong, unicameral legislatures;
            relatively weak governors, without veto powers, and little appointing authority;
            prohibition against individuals holding multiple government posts;
        </p>

        <p>
            The radical provisions of Pennsylvania's constitution lasted only 14 years. In 1790, conservatives gained power in the state legislature, called a new constitutional convention, and rewrote the constitution. The new constitution substantially reduced universal white-male suffrage, gave the governor veto power and patronage appointment authority, and added an upper house with substantial wealth qualifications to the unicameral legislature. Thomas Paine called it a constitution unworthy of America.[6]
        </p>

        <h2 id="military-hostilities-begin">Military hostilities begin</h2>

        <p>
            Massachusetts was declared in a state of rebellion in February 1775 and the British garrison received orders to disarm the rebels and arrest their leaders, leading to the Battles of Lexington and Concord on 19 April 1775\. The Patriots set siege to Boston, expelled royal officials from all the colonies, and took control through the establishment of Provincial Congresses. The Battle of Bunker Hill followed on June 17, 1775\. While a British victory, it was at a great cost; about 1,000 British casualties from a garrison of about 6,000, as compared to 500 American casualties from a much larger force.[35][36] First ostensibly loyal to the king and desiring to govern themselves while remaining in the empire, the repeated pleas by the First Continental Congress for royal intervention on their behalf with Parliament resulted in the declaration by the King that the states were "in rebellion", and the members of Congress were traitors.
        </p>

        <p>
            In the winter of 1775, the Americans invaded Canada. General Richard Montgomery captured Montreal but a joint attack on Quebec was a total failure; many Americans were captured or died of smallpox.
        </p>

        <p>
            In March 1776, with George Washington as the commander of the new army, the Continental Army forced the British to evacuate Boston. The revolutionaries were now in full control of all 13 colonies and were ready to declare independence. While there still were many Loyalists, they were no longer in control anywhere by July 1776, and all of the Royal officials had fled.[37]
        </p>

        <p>
            In August 1775, George III declared Americans in arms against royal authority to be traitors to the Crown. Following their surrender at the Battles of Saratoga in October 1777, there were thousands of British and Hessian soldiers in American hands. Although Lord Germain took a hard line, the British generals on the scene never held treason trials; they treated captured enemy soldiers as prisoners of war.[38] The dilemma was that tens of thousands of Loyalists were under American control and American retaliation would have been easy. The British built much of their strategy around using these Loyalists.[39] Therefore, no Americans were put on trial for treason. The British maltreated the prisoners they held, resulting in more deaths to American sailors and soldiers than from combat operations.[39] At the end of the war, both sides released their surviving prisoners.[40]
        </p>

        <h2 id="independence-and-union">Independence And Union</h2>

        <p>
            In April 1776 the North Carolina Provincial Congress issued the Halifax Resolves, explicitly authorizing its delegates to vote for independence.[41] In May Congress called on all the states to write constitutions, and eliminate the last remnants of royal rule.
        </p>

        <p>
            By June nine colonies were ready for independence; one by one the last four—Pennsylvania, Delaware, Maryland and New York—fell into line. Richard Henry Lee was instructed by the Virginia legislature to propose independence, and he did so on June 7, 1776\. On the 11th a committee was created to draft a document explaining the justifications for separation from Britain. After securing enough votes for passage, independence was voted for on July 2\. The Declaration of Independence, drafted largely by Thomas Jefferson and presented by the committee, was slightly revised and unanimously adopted by the entire Congress on July 4, marking the formation of a new sovereign nation, which called itself the United States of America.[42]
        </p>

        <p>
            The Second Continental Congress approved a new constitution, the "Articles of Confederation," for ratification by the states on November 15, 1777, and immediately began operating under their terms. The Articles were formally ratified on March 1, 1781\. At that point, the Continental Congress was dissolved and on the following day a new government of the United States in Congress Assembled took its place, with Samuel Huntington as presiding officer.[43][44]
        </p>

        <h2 id="more">More...</h2>

        <a href="https://en.wikipedia.org/wiki/American_Revolution">American Revolution on Wikipedia</a>
    </div>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>

  <script src="./javascripts/main.js" type="text/javascript"></script>
</body>
</html>

Listing 10-1Long Page with a Menu

该页面引用自定义 JavaScript 的本地javascripts/main.js文件。暂时把这个当做空的。它还引用自定义 CSS 的本地stylesheets/main.css文件。把那个也当成空的。如果您保存前一页的内容并将其加载到您的浏览器上,您将看到以下内容(图 10-1 )。

img/497763_1_En_10_Fig1_HTML.jpg

图 10-1

带有顶部导航的长页面

从前面的章节中你已经知道了导航栏 HTML 标记。您还学习了如何处理隐藏body顶部内容的问题。以下是 CSS 文件中必须包含的内容:

body {
    padding-top: 56px;
}

如果您保存前面的代码并在浏览器上重新加载页面,那么您将能够看到页面的顶部内容,而不会被导航栏隐藏(图 10-2 )。

img/497763_1_En_10_Fig2_HTML.jpg

图 10-2

顶部内容可见的长页面

这个页面的另一个问题也是我在上一本书 大师 HTML & CSS23 章“定位”中处理过的问题,就是当你点击菜单项时导航栏所覆盖的内容的问题。例如,点击菜单项State Constitutions。你会看到下面的图(图 10-3 )。

img/497763_1_En_10_Fig3_HTML.jpg

图 10-3

导航栏覆盖的内容

正如您所看到的,与您链接的链接相对应的部分的开头被导航栏所覆盖。

您可以通过将下面的padding-topmargin-top CSS 属性添加到h1h2元素来解决这个问题,这两个元素是页面的 HTML 元素,带有菜单项链接到的锚点(清单 10-2 )。

h1, h2 {
    padding-top: 56px;
    margin-top: -56px;
}

Listing 10-2Add to Your CSS File to Fix Hidden Section Content

如果您将前面的代码保存在您的stylesheets/main.css文件中,并在您的浏览器上重新加载该页面,点击State Constitutions将显示如下(图 10-4 )。

img/497763_1_En_10_Fig4_HTML.jpg

图 10-4

单击菜单项时,内容不被覆盖

然而,当点击More菜单项时,你希望页面将它的内容放在顶部。这种情况现在没有发生(图 10-5 )。

img/497763_1_En_10_Fig5_HTML.jpg

图 10-5

点击更多不会将内容显示在顶部

为了解决这个问题,你需要给页面的body增加一些下边距。

添加margin-bottom: 900px;。保存 CSS 文件并在浏览器上重新加载页面。点击More菜单项,会出现如下画面(图 10-6 )。

img/497763_1_En_10_Fig7_HTML.jpg

图 10-7

指向各节开头的菜单项

img/497763_1_En_10_Fig6_HTML.jpg

图 10-6

点击更多会在顶部显示内容

显示活动部分

当前页面的问题是,当您单击一个菜单项并且内容滚动到该点时,相应的菜单项不会变为活动状态。此外,如果您只是从上到下、从一节到另一节滚动内容,相应的菜单项不会变为活动状态。

这两个问题现在都可以通过使用 ScrollSpy 来解决,scroll spy 是一个 Twitter 引导 JavaScript 插件:

  1. 你需要告诉 ScrollSpy 哪个元素包含了你想要窥探的内容。通常,这就是body。你设置数据属性data-spy="scroll"

  2. 您需要告诉 ScrollSpy 哪个是包含菜单项列表的导航栏元素。在您的例子中,这是 id 为navbardiv。因此,您必须将data-target="#navbar"属性添加到body元素中。

  3. 您还需要将body元素的position属性设置为值relative

所以,首先,转到 HTML 页面

<body>

对此:

<body data-spy="scroll" data-target="#navbar">

position: relative添加到stylesheets/main.css文件中的body元素中。

保存所有的东西,并在你的浏览器上重新加载页面。您将看到第一个菜单项被突出显示,然后当您滚动时,根据页面的可见部分,相应的菜单项被突出显示。

激活截面点

有时,当节的开始位置早于页面顶部时,您可能希望活动节在菜单上突出显示。例如,当节的起点距离页面顶部 200 像素时,您可能想要激活节。您可以使用数据属性data-offset来实现,该属性将您想要激活的区域的像素数作为值。

变化

<body data-spy="scroll" data-target="#navbar">

对此:

<body data-spy="scroll" data-target="#navbar" data-offset="200">

在浏览器上保存并重新加载页面。然后开始滚动。您将看到,在部分开始到达页面顶部之前,部分已被激活。

它是如何工作的?

除了如前所述需要设置的正确数据属性(data-spydata-target和可选的data-offset,您还需要确保

  1. 您的菜单项指向与这些部分的开头相对应的 id。再次查看导航栏中带有菜单项的 HTML 片段(图 10-7 ):

  2. 各部分的开头需要有相应的/正确的 id,例如:

<h2 id="military-hostilities-begin">Military hostilities begin</h2>

使用 JavaScript 激活

您可能需要使用 JavaScript 动态激活 ScrollSpy。因此,不是在body元素上附加特定的数据属性,而是不添加任何东西,而是调用下面的 JavaScript 代码:

$('body').scrollspy({ target: '#navbar' });

让我们看看实际情况。将 HTML body元素改为

<body>

然后更新javascripts/main.js文件,使内容如清单 10-3 所示。

$(document).ready(function() {
    $('body').scrollspy({
        target: '#navbar'
    })
});

Listing 10-3Active ScrollSpy with JavaScript

当您保存所有文件并在浏览器上重新加载页面时,您仍然会看到 ScrollSpy 像以前一样工作。

请注意,您还可以在您直接构造的对象中赋予offset属性,并将其传递给scrollspy()方法。

任务和测验

Task Details

创建一个长页面来演示 ScrollSpy 功能。您的页面需要有一个顶部导航菜单,将页面内容移动到相应部分的开始。创建两个版本——一个使用 JavaScript,另一个使用数据属性。

关键要点

  • 如何显示带有导航栏的长内容页面

  • 如何让内容可见而不被导航栏隐藏

  • 如何让最后一节内容出现在页面顶部

  • 如何在用户从页面顶部滚动到底部时自动更改活动菜单项

  • 如何使用数据属性或 JavaScript 来激活 ScrollSpy

在本书的最后一章,你将学习工具提示和弹出窗口,这是一个非常吸引人的页面特性,因为它为用户提供了与他们交互的元素的额外信息。