Flutter web嵌入原有js获取不到节点问题

Flutter web 与原js结合

起因

由于Flutter最近很火,团队在做flutter-dart的全平台尝试。
对于Web这块,由于我们本身有很多react组件的积累,所以想在flutter web上直接使用原有的JS。

一开始,因为flutter web的语法可以直接和js语法对标,所以感觉不是什么困难的事情。

但是最终发现了有个1.20.4版本flutter,暂时还无法逾越的坑。

shadow dom

简单说,flutter 在创建web的platform view时,会在node前添加# showdow-root(open)
该标记会将子Node作为一个单独的绘制区域,导致导入进来的js无法直接获取到shadow root中的子节点,结果无法替换对应的dom。
shadow-root

尝试解决

1、官方的回答

https://github.com/flutter/flutter/issues/50452
总结就是,flutter官方后续可能会开放一个shadow-root创建成功的回调,也可能是直接将整个绘制成外面加一个shadow-root,让大家可以自定义style、class啥的。现在已经提上日程,但是开发者度假中,等回来再说…希望你看到这篇文章的时候该问题已经解决。

2、尝试使用<slot>

Element _iFrame = DivElement()
    ..id = 'container'
    ..style.border = '1'
    ..append(DivElement()..id = 'app' ..style.border='1')
    ..appendHtml('''<slot name="app"></slot>''')
    ..append(ScriptElement()
        ..type = "text/javascript"
        ..src = "/js/app.js"
    );

想用light dom去替换相应的节点。
结论:失败,提示slot标签是不被允许添加的。

3、最后只能修改js,先获取shadowRoot

将原来获取标签的方法,修改为用shadowRoot获取

	var shadowRoot = document.getElementsByTagName("flt-platform-view")[0].shadowRoot;
    i.i.render(i.i.createElement(u, null), shadowRoot.getElementById("app"))

指标不治本,先凑合用。

总结

虽然3解决这个问题,但是当一个页面有多个HtmlElementView时,就要修改每一个js,这个对于复用来说很不好,所以建议大家flutter web要用就纯粹用flutter,除了难实现的三方库。

2020-3-4 更新

Flutter 在3月4日添加了新的更新,<slot> 标签已经可用。
相关文档:
https://docs.google.com/document/d/1U6aCSuzQsFpOP8_OseL-fwl2-MC2bxJAsgt2R_-sC30/edit

This makes applying the above technique to Flutter Web relatively straightforward:

Attach a Shadow Root to the flt-scene-host element.
Render flt-scene and all its descendants inside said ShadowDOM.
When a platform view of “viewType” (defined by the user) is rendered:
A tag with the passed-in name (viewType) is added into the right position of the scene by the framework (this’ll end up inside the ShadowDOM of the flt-scene-host).
The actual contents of the platform view get a “slot” attribute added to them, with the value of viewType, and rendered as a child of the flt-scene-host element (“a sibling” to its ShadowDOM).
Ensure both the HTML and CanvasKit backends render platform views the same way.
Most of the lifecycle and DOM attachment logic for platform views should be reusable. The main difference would only be the creation of the elements.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值