前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一次性清除“知乎”所有DIV

一次性清除“知乎”所有DIV

作者头像
公众号@魔术师卡颂
发布2020-08-26 09:55:09
1K0
发布2020-08-26 09:55:09
举报
文章被收录于专栏:魔术师卡颂魔术师卡颂

学习本文的前置知识:

  • React每次更新都会从rootFiber(根Fiber节点)向下深度优先遍历
  • JSX在编译时会变为React.createElement,在组件render时会调用该方法。

30秒速答:

知乎首页是React写的,我们可以覆写React.createElement方法,在运行时将所有div节点渲染为React.Fragment

这样就能清除所有div

让我们来愉快的改造知乎吧。

拿到React对象

这时候遇到了第一个问题:知乎没把React暴露到全局(废话,当然不会),怎么获取React对象呢?

好在当我们使用React Dev Tools时,Dev Tools会向页面注入全局变量__REACT_DEVTOOLS_GLOBAL_HOOK__

这个变量是连接ReactDev Tools的桥梁。

其中renderers属性指页面使用的渲染器

React源码架构划分为调度器 - 协调器 - 渲染器

对于不同的宿主环境,使用不同的渲染器

  • 对于web,使用ReactDOM渲染器
  • 对于客户端,使用React-Native渲染器

renderers属性中,我们发现一个方法findFiberByHostInstance

方法名居然出现了Fiber字样。

Fiber节点React的最小可调度单元,可以理解为虚拟DOM节点

findFiberByHostInstance方法所在文件一定有React相关定义。我们右键跳转到定义函数的文件,

在文件内搜.createElement

果然让我们找到了。打上断点,刷新页面试试

果然进来了,事情越发有趣了。

看看o.a包含的属性,ChildrencreateElement......

看来这就是React对象了。

我们将来之不易的React对象保存在window,顺便把React.createElement也保存一份。

现在放开断点,window.React已经指向知乎首页内部使用的React啦。

修改React.createElement

React.createElement方法第一个参数为type

在源码中,我们找到React.Fragment对应的type

代码语言:javascript
复制
if (typeof Symbol === 'function' && Symbol.for) {
  const symbolFor = Symbol.for;
  REACT_ELEMENT_TYPE = symbolFor('react.element');
  REACT_PORTAL_TYPE = symbolFor('react.portal');
  REACT_FRAGMENT_TYPE = symbolFor('react.fragment');
  REACT_STRICT_MODE_TYPE = symbolFor('react.strict_mode');
  REACT_PROFILER_TYPE = symbolFor('react.profiler');
  REACT_PROVIDER_TYPE = symbolFor('react.provider');
  // ...
}

接下来,修改全局变量,将所有div变为Fragment

代码语言:javascript
复制
React.createElement = (type, ...args) => {
    if (type === 'div') {
        type = Symbol.for('react.fragment');
    }
    // originCreateElement是原始React.createElement
    return originCreateElement(type, ...args);
}

让我们滚动页面,触发随便啥组件的setState

接下来,就是见证奇迹的时刻。。。

div都消失啦,终于恢复了往日的清爽界面(大误)

理论上我们可以用这个方法将任何React应用改造成任何样子。

真是,太无聊了......

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-08-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 魔术师卡颂 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 拿到React对象
  • 修改React.createElement
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档