Salesforce开发人员的JavaScript技能-了解浏览器中的JavaScript

学习目标

完成本单元后,您将能够:

  • 描述JavaScript和浏览器之间的交互。
  • 解释Web API的角色。
  • 使用基本的文档对象模型API。
  • 描述闪电组件抽象DOM的方式。

JavaScript在浏览器中的工作方式

您刚刚了解了一些JavaScript运行时引擎和语言。您还学到了一些编写JavaScript的人都应该知道的东西。在本模块中,我们重点介绍JavaScript与浏览器之间的关系,特别关注您的网页在JavaScript中的外观。 

JavaScript运行时不是浏览器,也不是浏览器JavaScript

因此,JavaScript运行时引擎可以在许多不同的地方运行,但是最常托管在浏览器中。那么JavaScript和浏览器之间有什么区别? 

浏览器的主要工作是充当Web服务器的客户端。它使用几种协议(通常为HTTP / HTTPS)之一通过Internet请求资源。服务器将其中的一些资源传递给服务器后,浏览器需要对其进行处理。至少将HTML和CSS渲染到页面中。当资源包含一些JavaScript时,浏览器将到达JavaScript运行时引擎以解析,评估和执行该代码。 

同样,在执行脚本时,它也可以返回到浏览器以执行诸如修改网页,与本地环境交互或与其他Web资源交互的操作。

具有API的JavaScript引擎

为了使这些交互有效,浏览器会显示API。实际上,人们认为客户端JavaScript的很大一部分实际上就是这些API。 

Web API

标准品

能够与浏览器进行交互的API并不奇怪。就像任何其他编程语言或平台界面API与其在其上运行的环境进行交互一样,您的浏览器也是如此。 

虽然超过一半的浏览器互联网 流量来自Google Chrome浏览器,但大约另外30%来自其他五个浏览器。这强调了Web标准对于这些API的重要性,因此JavaScript可以编写一次并可以在任何地方运行。 

将Web API添加到图片

以前,我们创建了JavaScript运行时的图片。 

  • 请求使用单个线程在堆栈上执行。
  • 一个请求将保留线程,直到该线程执行完该请求的所有同步逻辑为止。
  • 新请求将排队,直到线程准备就绪。
  • 事件循环在下一个排队的请求可用时将其移入堆栈。

现在,我们将Web API添加到JavaScript图片中。这些扩展了核心JavaScript语言。它们显示界面,这些界面执行了许多对于现代Web用户体验至关重要的工作。例如,浏览器API可以: 

  • 与浏览器中呈现的当前页面的结构进行交互(文档对象模型或DOM API)
  • 在不离开当前页面的情况下执行对服务器的异步请求(Fetch API)
  • 与音频,视频和图形进行交互
  • 与显示在浏览器上的设备功能进行交互(地理位置,设备方向,客户端数据存储)

在大多数情况下,正是这些API向队列添加了新请求。 

注意

注意

我们正在避开JavaScript生态系统的重要组成部分:抽象或扩展浏览器功能的第三方API和JavaScript库。这些在野外使用JavaScript方面起着重要作用。 

就我们在​​Salesforce中的目的而​​言,我们涵盖了我们的JavaScript框架:Lightning Component Framework。具体来说,当谈论Lightning Platform上的JavaScript时,此模块介绍了Lightning Web组件开发模型。

举个例子。您在带有表单的网页上有一个注释列表。您填写表单上的某些字段,单击按钮以保存该数据,然后将新项添加到列表中。为了好玩,我们还说您将在本地缓存此新记录,以加快涉及该记录的将来请求。 

这个简单的用例将与以下浏览器API交互

  • 提取API(以保存记录)
  • DOM API(用于将新项目添加到HTML列表中)
  • 客户端数据存储(用于本地缓存数据)

让我们深入了解DOM API,因为它代表了用户在JavaScript中看到的内容。 

文档对象模型

DOM:您的JavaScript页面

当请求页面然后由浏览器接收时,浏览器将解析HTML并创建该页面的描述或模型。此模型用于在浏览器的视口中绘制页面。它也通过DOM浮出水面。 

将DOM视为一棵树。它始于浏览器显示功能的根:窗口。从那里开始,页面被封装在中window.document,页面的主体位于window.document.body。然后,树会扇动到页面上所表示的每一位内容。大多数网页都有一个非常复杂的树,其中许多节点最终以叶节点作为层次结构中最细化的部分结束。 

作为一个API,DOM是巨大的,它使您可以触摸树的每个部分。它还具有许多优化与DOM交互的方法。看一下jsbin.com 上的这个简单 示例。它 包括:

  • 输入字段
  • 添加项目按钮
  • 无序列表

每次单击按钮时,代码都会到达输入字段,读取其值,将其转换为文本节点,创建一个新li元素,将文本节点插入该li节点,最后将新的li-and-text节点粘贴到的ul。 

注意

为了获得更多乐趣,并且如果您想实践到目前为止讨论的一些原理,请查看是否可以修改jsbin以执行以下操作。

  • 检查文本输入中是否有数据
  • 如果不是,请不要在列表中添加新的li
  • 添加新li后,清除文本输入

如果悬念杀死了您,请查看修改后的 代码。

如您所见,仅此简单示例就需要开发人员执行一系列手动步骤。而且它甚至不会在服务器上存储任何数据,也不会以任何其他方式与服务器交互。因此,JavaScript库(reactjs,jQuery)和框架(Angular,vuejs)已成为交互式页面的标准。这样的框架会抽象化并简化DOM交互,并且通常会自动对缺少的功能应用polyfill。闪电组件框架没有什么不同。 

使用Shadow DOM封装

DOM API丰富而灵活。使用相对简单的JavaScript,很容易对UI调用的外观,行为和动作进行更改。 

但是有一个陷阱。DOM模型使得难以封装UI部分并保护它们免受意外(或有目的和恶意)更改的影响。 

因此,开发了Shadow DOM标准。Shadow DOM在UI功能的特定部分周围创建边界。该边界可防止父母更改孩子的元素或CSS。它还会强制跨边界传播的所有事件重新确定其目标范围,从而阻止父级跨越阴影DOM边界。

Lightning组件框架:Aura组件和Lightning Web组件

从Spring ’19版本(API版本45.0)开始,您可以使用两个编程模型来构建Lightning组件:Lightning Web组件模型和原始的Aura组件模型。闪电Web组件是使用HTML和现代JavaScript构建的自定义HTML元素。闪电Web组件和Aura组件可以在页面上共存和互操作。此内容仅涵盖Lightning Web Components。

闪电Web组件和DOM

注意

从现在开始,每个单元都有一个相似的部分,并带有一些示例,以说明与Lightning Web Components的关联。如果您想应用所学内容,现在是开始在Trailhead上使用Lightning Web Components Basics 模块的好时机 。

自动DOM更新

Lightning组件的基本价值在于构建由Salesforce数据驱动的自定义UI。这与DOM操作有关,因为DOM本身是由Salesforce数据驱动的。 

该组件以最简单的形式演示了该原理。

具有数据驱动UI的简单组件,显示的文本为“此文本来自JS道具。

这是此组件的代码。

// JavaScript Module: demo.js
import { LightningElement } from 'lwc';
export default class Demo extends LightningElement {
    text = 'This text came from a JS prop';
}
<!-- HTML Template: demo.html -->
<template>
    <lightning-card title="Basic DOM Example" icon-name="utility:hierarchy">
        <div class="slds-card__body slds-card__body-inner">
            <p>
                <lightning-formatted-text value={text}></lightning-formatted-text>
            </p>
        </div>
    </lightning-card>
</template>

首先介绍一下上下文:每个Lightning Web组件都需要一个JavaScript模块。如果组件包含要呈现给用户的任何元素,则也需要HTML模板。大多数组件在捆绑中都包含一个JavaScript和一个HTML文件。 

Lightning Web Components使将数据呈现到UI变得毫不费力。例如,上面的代码使用JavaScript属性text存储硬编码的字符串。在<lightning-formatted-text>标记中,value 属性的text属性绑定到JavaScript text属性,从而在UI中呈现数据。 

但是,如果您希望用户交互时更改UI,该怎么办?我们可以扩展这个例子来做到这一点。

这是代码。

// JavaScript Module demo2.js
import { LightningElement, track } from 'lwc';
export default class Demo2 extends LightningElement {
    @track text = '';
    handleChange(event){
        this.text = event.target.value;
     }
}
<!-- HTML Template demo2.html -->
<template>
    <lightning-card title="Basic DOM Example" icon-name="utility:hierarchy">
        <div class="slds-card__body slds-card__body-inner">
            <p>
                <lightning-formatted-text value={text}></lightning-formatted-text>
            </p>
            <p>
                <lightning-input onchange={handleChange} label="Input Text" value={text}></lightning-input>
            </p>
        </div>
    </lightning-card>
</template>

如果text再次查看该属性,则会看到我们添加了一些新行为。通过使用@track,我们利用了称为装饰器的相对较新的JavaScript功能。此装饰器将功能附加到属性,以确保在其值更改时重新呈现组件的DOM。  

在模板中,我们添加了一个<lightning-input>。尽管绑定text属性是显示数据的关键,但请注意该onchange属性。handleChange现在已由change事件触发已添加到JavaScript模块的功能。用户对值的每次修改都会更新的值text。文本更新时,DOM也更新。  

尽管这是一个人为的示例,但它说明了Lightning Web Components如何显示使隐式DOM更改易于实现为开发人员的功能。

显式DOM操作

在构建Lightning Web组件时,手动DOM操作不应该是您的首要策略,但是更复杂的组件可能需要您这样做。这是一个更高级的主题,但是在签署DOM之前值得先了解一下它的工作原理。 

有条件的渲染

编写Lightning Web组件时,可以显式定义UI的部分,这些部分仅在满足某些条件时才呈现。您可以通过在嵌套 标记中添加if:trueor if:false指令来实现template。 

//conditionalButton.js
import { LightningElement, track } from 'lwc';
export default class ConditionalButton extends LightningElement {
    @track show = true;
    handleClick(){
        this.show = !this.show;
    }
}
//conditionalButton.html
<template>
    <lightning-card title="Conditional Rendering with Button" icon-name="utility:hierarchy">
        <div class="slds-card__body slds-card__body-inner">
            <p>
                <template if:true={show}>
                    Peek-a-boo!
                </template>
                <template if:false={show}>
                    I'm hiding!
                </template>
            </p>
            <p>
                <lightning-button onclick={handleClick} variant="neutral" label="Switch"></lightning-button>
            </p>
        </div>
    </lightning-card>
</template>

在此代码示例中,文本Peek-a-boo!show属性值为时出现true。当show设置为时false我隐藏的文本出现。单击该按钮可切换show属性的值。

手动操作DOM的其他方法

在某些情况下,可以使用显示CSS样式来操作DOM元素的显示。尽管此方法在Lightning Web Components中照常工作,但超出了此特定模块的范围。