Flutter for Web 生成的标签 <flt-*> 是啥?

Posted

技术标签:

【中文标题】Flutter for Web 生成的标签 <flt-*> 是啥?【英文标题】:What are the tags, <flt-*> generated by Flutter for Web?Flutter for Web 生成的标签 <flt-*> 是什么? 【发布时间】:2021-01-27 07:13:28 【问题描述】:

我通过运行 flutter run -d chrome 运行 Flutter for Web,然后我看到一堆 &lt;flt-*&gt; 标签,例如 &lt;flt-glass-pane&gt;&lt;flt-scene&gt;。我认为 Flutter Web 通过 Canvas 呈现网页,但不确定它为什么会生成这些 html 标签。它们是出于 SEO 目的吗?试图查找文档,但找不到任何相关信息。

我从默认启动页面上的 generate html 标签中删除了style 属性,如下所示。

<flt-glass-pane>
  <flt-semantics-placeholder role="button" aria-live="true" tabindex="0" aria-label="Enable accessibility"></flt-semantics-placeholder>
  <flt-scene-host aria-hidden="true">
    <flt-scene flt-layer-state="updated">
      <flt-transform flt-layer-state="updated">
        <flt-offset flt-layer-state="updated">
          <flt-picture flt-layer-state="updated"></flt-picture>
          <flt-offset flt-layer-state="updated">
            <flt-clip flt-layer-state="updated" clip-type="physical-shape">
              <flt-clip-interior>
                <flt-picture flt-layer-state="updated">
                  <flt-dom-canvas>
                    <p>You have pushed the button this many times:</p>
                    <p>0</p>
                  </flt-dom-canvas>
                </flt-picture>
                <flt-clip flt-layer-state="updated" clip-type="physical-shape" >
                  <flt-clip-interior >
                    <flt-picture flt-layer-state="updated" >
                      <flt-canvas >
                        <div >
                          <div >
                            <p >Flutter Demo Home Page</p>
                          </div>
                        </div>
                      </flt-canvas>
                    </flt-picture>
                  </flt-clip-interior>
                </flt-clip>
                <flt-transform flt-layer-state="updated" >
                  <flt-clip flt-layer-state="updated" clip-type="physical-shape" >
                    <flt-clip-interior >
                      <flt-picture flt-layer-state="updated" >
                        <flt-dom-canvas >
                          <p ></p>
                        </flt-dom-canvas>
                      </flt-picture>
                    </flt-clip-interior>
                  </flt-clip>
                </flt-transform>
              </flt-clip-interior>
            </flt-clip>
          </flt-offset>
        </flt-offset>
        <flt-picture flt-layer-state="updated" >
          <flt-dom-canvas >
            <draw-rect flt-rect="Rect.fromLTRB(-40.0, 28.0, 40.0, 40.0)" flt-paint="SurfacePaintData(color = rgba(0,0,0,0.4980392156862745); maskFilter = MaskFilter.blur(BlurStyle.normal, 4.0); isAntiAlias = true)" ></draw-rect>
            <draw-rect flt-rect="Rect.fromLTRB(-40.0, 28.0, 40.0, 40.0)" flt-paint="SurfacePaintData(color = rgba(183,28,28,0.6274509803921569); isAntiAlias = true)" ></draw-rect>
            <p >DEBUG</p>
          </flt-dom-canvas>
        </flt-picture>
      </flt-transform>
    </flt-scene>
  </flt-scene-host>
</flt-glass-pane>
<flt-ruler-host >
  <div data-ruler="single-line" >
    <p >_</p>
    <div></div>
  </div>
  <div data-ruler="min-intrinsic" >
    <p >_</p>
  </div>
  <div data-ruler="constrained" >
    <p >_</p>
  </div>
  <div data-ruler="single-line" >
    <p >Flutter Demo Home Page</p>
    <div></div>
  </div>
  <div data-ruler="min-intrinsic" >
    <p >Flutter Demo Home Page</p>
  </div>
  <div data-ruler="constrained" >
    <p >Flutter Demo Home Page</p>
  </div>
  <div data-ruler="single-line" >
    <p >You have pushed the button this many times:</p>
    <div></div>
  </div>
  <div data-ruler="min-intrinsic" >
    <p >You have pushed the button this many times:</p>
  </div>
  <div data-ruler="constrained" >
    <p >You have pushed the button this many times:</p>
  </div>
  <div data-ruler="single-line" >
    <p >0</p>
    <div></div>
  </div>
  <div data-ruler="min-intrinsic" >
    <p >0</p>
  </div>
  <div data-ruler="constrained" >
    <p >0</p>
  </div>
  <div data-ruler="single-line" >
    <p ></p>
    <div></div>
  </div>
  <div data-ruler="min-intrinsic" >
    <p ></p>
  </div>
  <div data-ruler="constrained" >
    <p ></p>
  </div>
  <div data-ruler="single-line" >
    <p >DEBUG</p>
    <div></div>
  </div>
  <div data-ruler="min-intrinsic" >
    <p >DEBUG</p>
  </div>
  <div data-ruler="constrained" >
    <p >DEBUG</p>
  </div>
</flt-ruler-host>

【问题讨论】:

【参考方案1】:

Flutter 有两种类型的web renderers。 您附加的代码 sn-p 看起来像是使用 html 渲染器而不是 canvaskit。所以,你得到的是 DOM 元素而不是画布。当您运行 flutter run -d chrome 时,它会以自动模式构建,在此处自动选择渲染器,它会选择 html 渲染器。

要使用的渲染器可以通过flutter runflutter build 命令中的--web-renderer 选项(htmlcanvaskit)强制执行。

现在,如果我们查看 DOM 元素,一些 DOM 元素对于两个渲染器来说都是通用的。

图案如下所示

<flt-glass-pane>
    <flt-semantics-placeholder></flt-semantics-placeholder>
    <flt-scene-host>
        <flt-scene>

           <!-- if canvaskit renderer used here will be one canvas element only 
                and all elements or widgets will be drawn inside 
                the canvas -->

           <!-- if html renderer used here will be DOM elements with 
                different tags and attribute to render the 
                widgets in the browser -->

        </flt-scene>
    </flt-scene-host>
<flt-glass-pane>
     

对于 html 渲染器,flt-scene 中具有不同标签和属性的 DOM 元素用于在浏览器中渲染小部件。

除了容器 DOM 元素(flt-glass-paneflt-scene-hostflt-scene)之外,flt-semantics-placeholder 元素很有趣。如果在 flt-semantics-placeholder 元素上触发了 javascript click(),它将启用可访问性。从技术上讲,它在映射到小部件坐标的画布上创建了 dom 元素的叠加层,以便可访问性工具、搜索引擎和其他语义分析软件可以使用 Flutter 应用程序中的小部件来确定应用程序的含义,尽管它们被渲染在画布中,在画布中,我们无法轻松了解小部件的坐标或读取文本(使用 OCR 是可能的,但这是不同的)。这也用于颤振驱动程序here。

【讨论】:

很好的解释!太感谢了!发这个问题已经半年了,但我脑子里的问题已经被吹走了:) 有没有办法用canvaskit渲染器从网络上抓取数据?可能吗?似乎一切都画在画布上。

以上是关于Flutter for Web 生成的标签 <flt-*> 是啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何将“Flutter for Web”转换为“Flutter for Mobile”?

Map in Flutter for Web - 将数据从 JS 发送到 Flutter for Web

Flutter web 垂直标签导航

js,flutter web,H5实现浏览器跳转到微信

在Flutter中动态生成小部件

Flutter For Web实践