第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定

Web組件的問題在哪?

標(biāo)簽:
Html5 JavaScript CSS3

Web Components 的真实问题很简单:没有一个明确的成功路径来使用它们。没有一个统一的使用指南。直到最近,标准一直在变化。在某种程度上,仍然如此。但核心API已经稳定下来,许多开发者已经开始涉足这一领域。

然而,对于那些没有跟随过(https://github.com/WICG/webcomponents)这一标准发展过程的人来说,知道从哪里开始可能会感到困惑。要掌握使用这套强大工具所需的概念也是一项挑战。虽然有很多关于这个主题的文章,但真正有用的信息却被淹没在了那些过时的教程里,这些教程中展示的实验性功能已经随时间发生了变化

那么,如果你一直在思考如何从头开始制作自己的组件,这篇文章正是为你准备的。

Web 组件剖析

咱们从基础开始讲起。Web Components 的关键在于能够创建自定义 HTML 元素。你可能还听说过 HTML 模板和阴影 DOM。这些额外的 API 让我们能更好地控制浏览器的原生封装方法,不过现在你不用完全理解这些也没关系。在开始研究这些高级主题之前,我们先来看看浏览器是怎么处理自定义元素的。

了解自定义元素是什么

当HTML文档被解析时,会根据找到的标签创建元素实例。浏览器非常熟悉的包括标准元素如 <div><p><button>。但当你尝试创建自己的标签时,会发生什么呢?

    <组件></组件>

全屏模式 开启/关闭

浏览器不能一遇到不认识的标签就崩溃。也不能直接丢弃应该传递给用户的数据。所以它们将这些未描述的标签初始化为 HTMLUnknownElement 实例,并将其内容以纯文本形式展示,甚至继续解析嵌套的 HTML 子元素。这种行为正是我们定义自定义元素的基础。

创建一个自定义元素

HTML 有一套固定且定义良好的标签。这套标签基本不会发生变化。当 HTML5 发布时,我们增加了一些新的语义元素,但之后新增的并不多。在过去,我们只能寄希望于新的元素出现。然后我们用 <div> 和其他元素构建了一些复杂的抽象。现在,我们可以将这些抽象简化为可重用的组件,为我们的文档添加更多意义。不过,HTML 的根命名空间需要保留给未来的内置标签。因此,如果你想创建自己的标签,这个标签必须包含至少一个连字符 -

    <my-element>你好,世界</my-element>
    <my-next-element>
      <span>这是</span>
      <span>是</span>
      <span>一个</span>
      <span>测试</span>
    </my-next-element>

全屏模式, 退出全屏

通过这样做,我们告诉浏览器这不再是一个未知元素了。我们现在对其负责。这个元素会被解析为一个普通的内联元素,类似于<span>标签。

你可以像定位其他任何元素一样,用 CSS 定位它们。

    my-element {
      显示: 块;
      垫片: 1em;
      颜色: 黑色;
      背景: 绿色;
    }

    my-next-element {
      显示: 弹性;
      弹性流程: 行 包裹;
      水平对齐内容: 空间环绕;
    }

全屏模式;退出全屏

你可以用JS像操作任何其他元素一样操作它们。

const myElement = document.querySelector('my-element');
console.log(myElement instanceof HTMLElement); // 结果为 true

const myNextElement = document.querySelector('my-next-element');
console.log(myNextElement.children); // HTMLCollection 元素有 4 个

全屏 播出/显示 点击退出全屏

所有的基础特性,如 HTMLElement 的特性,都可用,例如事件。

    myElement.addEventListener('click', event => {
        console.log(event.target);
    })

当点击myElement时,打印出触发事件的目标元素。

进入全屏,退出全屏

我们才刚刚开始了解Web组件技术的皮毛。

注册自定义组件

为了使通用组件变得有意义,我们需要将其注册到浏览器。

    类 MyElement 继承 HTMLElement {
      构造函数() {
        super();
      }
    }

    customElements 定义('my-element', MyElement);

全屏 取消全屏

这个例子本身并没有带来额外的好处,但它是构建我们新模块化、可重用组件的基础。在 Custom Elements 出现之前,我们必须:先等待 DOM 完全解析,然后查询并选择特定元素的所有实例,使用外部脚本将我们的功能封装到这些元素中。

通过自定义元素,我们现在可以将该逻辑直接定义在元素中。我们不再需要在DOM中查找这些元素。每当遇到这个元素时,它会自动使用我们定义的类。

利用力量

注册我们的元素使我们能够施展各种魔法。我们可以解析元素以找到子元素,可以检测到新子元素的出现,也可以添加我们自己的子元素。我们可以随心所欲地操作元素。这完全取决于你的具体需求。每个组件都有自己的特性,可能性无穷无尽。

但我们得从某个地方开始。所以让我们建立一个简单的示例。我们将创建一个 <copy-text> 元素,当点击这个元素时,它的文本内容将被复制到剪贴板。

我们可以用一些JavaScript来针对 <span> 元素来实现这一点,但使用一个专用的元素可以让我们在我们的标记中更清楚地表达意图。这还允许我们在样式表中创建独特的规则,而不需要在类或ID上进行过多的范围定义。而且,我们不需要更改任何代码就可以添加更多实例。

注意我在类定义中使用了#private方法来。这保护了组件内部功能,防止外部操作。这在后面谈到封装时会显得尤为重要。目前,我们创建了一个完全位于根文档中的组件。页面的样式表完全涵盖了该元素。其整个结构都可以在文档上下文中访问到。

再利用自定义元素

自定义标签只需在每个浏览器上下文中初始化一次。无论是作为内联脚本还是通过获取脚本引入我们的组件定义,这样我们就可以在任何地方多次使用它。

    <!DOCTYPE html>
    <title> 复制文本元素示例 </title>
    <link rel="stylesheet" href="theme.css">
    <script type="module" class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="copy-text.js"></script>
    <div>
      <label> 示例: </label>
      <copy-text title="复制您的API密钥">
        A_REALLY_LONG_API_KEY_OR_WHATEVER
      </copy-text>
    </div>
    <div>
      <label> 示例 2: </label>
      <copy-text>
        更多要复制的文本
      </copy-text>
    </div>

切换到全屏,退出全屏

如果我们从我们的模块中导出了这个类,我们也可以在其他脚本中导入它并创建自定义对象。

    // 在复制文本的 JS 文件末尾
    export { CopyTextElement }

全屏,退出全屏

    // 在另一个组件里
    import { CopyTextElement } from './copy-text.js';
    const copyText = new CopyTextElement();

进入全屏 退出全屏

然而,如果你对自己的模块已经100%加载确定,这种情况就无需再这样做。我们只需要像其他元素一样创建一个实例。如果需要,我们也可以从元素注册表中获取该类。

    const 复制文本 = document.createElement('复制文本');
    const CopyTextElement = customElements.get('复制文本');
    const 另一个复制 = new CopyTextElement();

切换到全屏 退出全屏

如果你不能控制组件的加载次序,也可以等你的元素注册好。

    customElements.whenDefined('copy-text')
    .then(CopyTextElement => {
      const copyText = new CopyTextElement();
    });

切换到全屏,退出全屏

我们要深入一点.

到目前为止,我们主要讨论的是自定义元素的单独行为。现在我们需要处理包含子树的元素。在传统的Web应用程序中,我们会通过选择宿主元素来获取元素集合。而对于自定义元素,我们可以让元素本身对其子元素负责,这样更灵活。处理这种情况的最佳方式是使用 Mutation Observer

我们设置了初始事件处理器,然后根据任何进入或离开子树的元素动态添加或删除它们。需要注意的是,我们在构造函数中初始化了所有内容。虽然许多教程认为 connectedCallback 是生命周期中最重要的部分,但这不一定总是这样。构造函数是设置我们组件核心功能的理想场所。

主要原因是我们这个元素能够立即处理子元素。我们不会等到它连接到DOM才开始处理。这使我们能够通过代码创建这个元素的实例,并在添加到文档之前就已经配置好了。在这个例子中,我们仅仅添加了点击处理器。但是,如果需要的话,我们可以用这种方法来实现更复杂的逻辑。我们的元素在插入时不会延迟渲染,而是立即准备好使用。

    const clickHandler = document.createElement('click-handler');

    [ 'test', 'another', 'more' ].forEach(label => {
      const span = document.createElement('span');
      span.textContent = label;
      clickHandler.append(span);
    });

    requestAnimationFrame(() => {
        document.body.append(clickHandler);
    });

全屏进入,退出全屏

既优雅又灵活

我们已经见识了如何利用自定义元素以简单、模块化的方式实现可重用的功能。这不需要构建工具或框架依赖。只需有意义的标记、经典的 CSS 和原生的 JS。这个工具包提供的是可在任何地方运行的 Web 组件。但到目前为止,我们所做的只是简化了已有的方法。其实,这个工具包还有很多其他的功能。

接下来的文章中,我们将探讨如何使用HTML模板将这些简单的声明性定义轻松转换成复杂的标记结构。我们还将讨论如何充分利用Shadow DOM来完全或部分封装我们的组件。

在此之前,试着创建你自己的自定义元素。从简单的开始做起。专注于解决实际中的问题。这里有几个想法来帮你激发创意:

  • <format-number> : 用于显示具有特定格式的数字(如货币、小数等)
  • <tool-tip> : 悬停或点击时显示弹出的描述性文本
  • <marquee-text> : 一种早期的非标准元素
  • <nav-bar> : 一个自动高亮当前路径的网站菜单
點(diǎn)擊查看更多內(nèi)容
TA 點(diǎn)贊

若覺得本文不錯(cuò),就分享一下吧!

評(píng)論

作者其他優(yōu)質(zhì)文章

正在加載中
  • 推薦
  • 評(píng)論
  • 收藏
  • 共同學(xué)習(xí),寫下你的評(píng)論
感謝您的支持,我會(huì)繼續(xù)努力的~
掃碼打賞,你說多少就多少
贊賞金額會(huì)直接到老師賬戶
支付方式
打開微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊(cè)有機(jī)會(huì)得

100積分直接送

付費(fèi)專欄免費(fèi)學(xué)

大額優(yōu)惠券免費(fèi)領(lǐng)

立即參與 放棄機(jī)會(huì)
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)

舉報(bào)

0/150
提交
取消