前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【译】利用HTML Slot, HTML Template和Shadow DOM提取出网页摘要

【译】利用HTML Slot, HTML Template和Shadow DOM提取出网页摘要

作者头像
腾讯IVWEB团队
发布2020-06-28 11:05:57
8790
发布2020-06-28 11:05:57
举报

原文地址:Extracting Text from Content Using HTML Slot, HTML Template and Shadow DOMundefined日期:2019-03-06undefined作者:Preethi

书本上的章节名称、演讲的引用、文章里的关键字、报告上的统计信息,这些都是有助于提炼和转化成高度总结的摘要的内容。

比如, 你是否看到过 "Business Insider" 在展示文章内容之前提供的文章的关键点?

这些就是我们要做的事情,尝试使用HTML Slot, HTML Template和Shadow DOM直接从文章中提取出关键点。

这三个名词是Web Components规范的一部分,用于在网页中使用自定义的组件模块。

现在我们的目标是文本提取,并不需要自定义组件,但是它可以利用这三种技术。有一个很基础的办法来达到目的,例如我们可以用一些基本的js脚本就可以提取文本,而不需要使用slot和template。既然我们已经有一些熟悉的方法,那么为什么还要用他们呢?

使用这些技术的原因是他们允许我们为从HTML中提取的文本预设标记(也可以选择style或script)。本文后面的内容会介绍到这些。

现在, 对我们要用到的技术做一个简单的定义:

  • template是一组可被复用的标签
  • slot是页面中指定元素的占位符
  • shadow dom是dom树,在我们用script引入它之前没有存在于页面中

当我们开始编码后,就能更深入的了解他们。现在我们要做的是创造一个article标签,它的文本内容包含了若干个关键。你可能猜到了, 这些关键点是从文章中提取出来的, 并编译到了keyPoints节点。

<iframe name="cp_embed_1" src="https://codepen.io/rpsthecoder/embed/gZqVBO?height=430&amp;theme-id=1&amp;default-tab=result&amp;user=rpsthecoder&amp;slug-hash=gZqVBO&amp;pen-title=Text%20Extraction%20with%20HTML%20Slot%20and%20HTML%20Template&amp;name=cp_embed_1" scrolling="no" frameborder="0" height="430" allowtransparency="true" allowfullscreen="true" allowpaymentrequest="true" title="Text Extraction with HTML Slot and HTML Template" class="cp_embed_iframe " style="width: 100%; overflow: hidden; display: block; height: 100%;" id="cp_embed_gZqVBO"></iframe>

这些关键点需要被展示成一个列表。所以我们首先为这个列表创建一个模板, 并指定一个展示的位置。

代码语言:javascript
复制
<article><!-- Article content --></article>

<!-- Section where the extracted keypoints will be displayed -->
<section id='keyPointsSection'>
  <h2>Key Points:</h2>
  <ul><!-- Extracted key points will go in here --></ul>
</section>

<!-- Template for the key points list -->
<template id='keyPointsTemplate'>
  <li><slot name='keyPoints'></slot></li>
  <li style="text-align: center;">&#x2919;&mdash;&#x291a;</li>
</template>

我们使用包含了ul标签的section标签去展示关键点列表。然后, 我们使用template做为li标签的父元素,这两个li标签一个拥有文章中关键点的 <slot> 占位符, 另一个被设计成居中的分界线。

关于布局你可以随便一点,重点是放置一个slot去提取关键点。在我们使用js脚本把template添加到页面之前, 页面上什么都不会渲染出来。

值得一提的是,template中的标记也可以是行内的style或者使用style标签的css:

代码语言:javascript
复制
<template id='keyPointsTemplate'>
    <li><slot name='keyPoints'></slot></li>
    <li style="text-align: center;">&#x2919;&mdash;&#x291a;</li>
    <style>
        li{/* Some style */}
    </style>
</template>

接下来是有趣的部分了,从文章中提取出关键点。需要注意template中的slot标签上的name属性的值(keyPoints), 因为我们需要它。

代码语言:javascript
复制
<article>
  <h1>Bears</h1>
  <p>Bears are carnivoran mammals of the family Ursidae. <span><span slot='keyPoints'>They are classified as caniforms, or doglike carnivorans</span></span>. Although only eight species of bears <!-- more content --> and partially in the Southern Hemisphere. <span><span slot='keyPoints'>Bears are found on the continents of North America, South America, Europe, and Asia</span></span>.<!-- more content --></p>
  <p>While the polar bear is mostly carnivorous, <!-- more content -->. Bears use shelters, such as caves and logs, as their dens; <span><span slot='keyPoints'>Most species occupy their dens during the winter for a long period of hibernation</span></span>, up to 100 days.</p>
  <!-- More paragraphs -->
</article>

关键点包含在span标签中,带有一个属性值为keyPoints的slot,它和template中的有相同name属性的slot标签相匹配。

再次注意,我们使用了span标签作为关键点的父元素。原因是slot的name通常是唯一且不重复的, 因为一个slot只使用一个name属性去匹配一个元素。如果有多个元素具有相同的slot name,那么slot占位符将被所有这些元素接连替换, 最后一个会覆盖之前所有的slot。因此, 如果我们对段落或文章中具有相同slot属性值 (关键点) 的所有span元素进行匹配, 我们最终只会匹配到段落或文章中最后一个关键点slot。

这不是我们想得到的结果,我们需要匹配到所有的关键点,于是我们可以用一个span元素作为父元素来包含这些关键点来匹配每一个单独的slot标签属性,看看代码怎么做:

代码语言:javascript
复制
const keyPointsTemplate = document.querySelector('#keyPointsTemplate').content;
const keyPointsSection = document.querySelector('#keyPointsSection > ul');
/* Loop through elements with 'slot' attribute */
document.querySelectorAll('[slot]').forEach((slot)=>{
  let span = slot.parentNode.cloneNode(true);
  span.attachShadow({  mode: 'closed' }).appendChild(keyPointsTemplate.cloneNode(true));
  keyPointsSection.appendChild(span);
});

首先我们遍历每一个拥有slot属性的span元素并且复制它们的父元素(外层span),当然我们也可以直接遍历外层span,但是这样就要给外层span提供一些共有的class属性便于query到。接下来给外层span附上了一个由模板内容组成的shadow tree(span.attachShadow), 这个绑定在外层上的 "附件" 会导致shadow tree中模板list也会接受并匹配有相同slot name值(也就是我们的关键点)的span元素。再把这些关键点就添加到页面底部(keyPointsSection.appendChild)。我们在遍历中处理所有的关键点。

大功告成,我们已经提取出了文章中的所有关键点, 并复制了它们的内容, 然后把内容填充到模板list中, 便于把所有关键点组合在一起来提供一个像笔记一样的文章摘要。

这是最终的demo:

<iframe name="cp_embed_2" src="https://codepen.io/rpsthecoder/embed/gZqVBO?height=430&amp;theme-id=1&amp;default-tab=result&amp;user=rpsthecoder&amp;slug-hash=gZqVBO&amp;pen-title=Text%20Extraction%20with%20HTML%20Slot%20and%20HTML%20Template&amp;name=cp_embed_2" scrolling="no" frameborder="0" height="430" allowtransparency="true" allowfullscreen="true" allowpaymentrequest="true" title="Text Extraction with HTML Slot and HTML Template" class="cp_embed_iframe " style="width: 100%; overflow: hidden; display: block; height: 100%;" id="cp_embed_gZqVBO"></iframe>

你是怎么看待这个技术呢?它在处理一些有大量内容的场景, 如博客, 新闻, 或者维基百科词条时是有用的?或者你还想到了什么其他使用场景?

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档