上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖

[油猴脚本开发指南]实战抖音React富文本输入框

[复制链接]
  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    637

    主题

    5212

    回帖

    6088

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6088

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2024-3-15 17:54:24 | 显示全部楼层 | 阅读模式

    我们的目标是触发输入框的消息
    图片.png
    查看DOM结构发现没有任何输入框
    应该是通过监听输入事件后读取数据自己合成出来文字
    图片.png
    我们网上逐层找看看会不会有什么思路
    可以看到有一个叫做DraftEditor-root的Dom节点,这个大概率是一个React组件的根
    图片.png
    我们在他和im-richtext-container两个之间找找有没有什么有用的信息
    发现在im-richtext-container的__reactFiber$n5t796psn7s.memoizedProps.children.props.children.props中有一个onChange的回调函数
    图片.png
    感觉有戏?我们在控制台打印出来然后追过去下一个断点
    图片.png
    再次尝试触发输入,但是没有显示任何的数据,而是一个{_immutable:n}的对象
    图片.png
    那我们目前就走投无路了,难道真的就就此停止了?
    不!!
    我直接给我女神打一个电话表白,表白失败获得度日如年BUFF
    然后打开网易云音乐叠一个战歌BUFF
    再高喊因为我背负的太多,所以我根本不会输
    然后临时叠上LGBT,素食主义者,螺旋武装直升机等BUFF
    只要BUFF叠的够满,一级也能打爆BOSS

    BUFF叠的差不多了,我们就开干
    我们从DraftEditor-root找找思路,发现根据搜索有一个Draft.js的库
    同样也有react版本,我就找了一份在线例子看看
    https://codesandbox.io/p/sandbox/draftjs-ytf7q
    发现对比抖音的结构几乎一致
    1

    那我们就去看看react版本的draftjs
    可以发现其中我们刚才找到的应该是editorState对象,onChange则是通过一些其他逻辑然后设置editorState

    import React from 'react';
    import ReactDOM from 'react-dom';
    import {Editor, EditorState} from 'draft-js';
    import 'draft-js/dist/Draft.css';
    
    class MyEditor extends React.Component {
      constructor(props) {
        super(props);
        this.state = {editorState: EditorState.createEmpty()};
        this.onChange = editorState => this.setState({editorState});
      }
    
      render() {
        return (
          <Editor editorState={this.state.editorState} onChange={this.onChange} />
        );
      }
    }
    
    ReactDOM.render(<MyEditor />, document.getElementById('container'));

    那我们的目标就是如何生成editorState并且丢给onChange呢?
    我们查阅各种提问找到了一个设置初始值为自定义类型的demo
    https://stackoverflow.com/questions/71496940/how-can-i-set-defaultvalue-on-react-draft-wysiwyg

    import { Editor } from "react-draft-wysiwyg";
    import { EditorState, ContentState } from "draft-js";
    
    export const TestComponent = () => {
      const [editorState, setEditorState] = useState(() => {
        const content = ContentState.createFromText(
          "This is your default content."
        );
        return EditorState.createWithContent(content);
      });
    
         return (<Editor
                  editorState={editorState}
                  wrapperClassName="wrapper-class"
                  editorClassName="editor-class"
                  toolbarClassName="toolbar-class"
                  onEditorStateChange={onEditorChange}
                />);
    }
    export default TestComponent;

    到这里我们就知道了需要调用ContentState.createFromText以及EditorState.createWithContent生成,我们可以选择Webpack核心注入方式拿到draft.js的函数,但是由于Tree-Shark的原因难以保证没有被调用的函数依然能正确运行,同时由于这种初始化数据的函数极有可能是有一个无状态函数,所以我们尝试直接引入一个draft.js生成editorState内容试试。
    直接引入// @require https://cdn.bootcdn.net/ajax/libs/draft-js/0.11.7/Draft.js会报错,根据查阅发现还需要react以及react-dom,过于复杂了,所以感觉建立一个项目通过webpack打包到一起暴露出去吧。

    安装webpack依赖npm i webpack webpack-cli -D,安装draft依赖npm i draft-js,然后编写代码

    import { EditorState, ContentState, convertFromHTML } from "draft-js";
    
    export function init() {
      return {
        EditorState,
        ContentState,
        convertFromHTML,
      };
    }

    然后编写一个简易的webpack模板

    //webpack.config.js
    
    const path = require("path");
    module.exports = {
      entry: "./index.js",
      output: {
        filename: "bundle.js",
        path: path.resolve(__dirname, "dist"),
        library: "draftUtils",
      },
      mode: "production",
      optimization: {
        usedExports: true,
      },
    };

    通过npx webpack即可打包
    然后引入我们的js并且写一个生成函数

    // ==UserScript==
    // @name         New Userscript
    // @namespace    https://bbs.tampermonkey.net.cn/
    // @version      0.1.0
    // @description  try to take over the world!
    // @author       You
    // @match        https://www.douyin.com/*
    // @require      https://scriptcat.org/lib/1612/1.0.0/draftUtils.js
    // @grant        unsafeWindow
    // ==/UserScript==
    
    const { ContentState, EditorState } = draftUtils.init()
    function generateRichText(text) {
        const content = ContentState.createFromText(
            text
        );
        return EditorState.createWithContent(content)
    }
    unsafeWindow.generateRichText = generateRichText

    根据测试可以正确生成富文本的数据对象了
    图片.png
    接下来我们把刚才的im-richtext-container的__reactFiber$wwgviaigfbb.memoizedProps.children.props.children.props.onChange投递进去这个对象即可实现draft.js的数据触发

    结语

    撒花

    已有1人评分好评 油猫币 理由
    zip11 + 1 + 7 很给力!

    查看全部评分 总评分:好评 +1  油猫币 +7 

    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
  • TA的每日心情
    开心
    2024-1-27 11:40
  • 签到天数: 1 天

    [LV.1]初来乍到

    5

    主题

    14

    回帖

    37

    积分

    助理工程师

    积分
    37
    发表于 2024-3-17 12:57:10 | 显示全部楼层
    大佬,mac不支持scriptcat+vscode吗
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    637

    主题

    5212

    回帖

    6088

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6088

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2024-3-17 14:08:43 | 显示全部楼层
    uuorz 发表于 2024-3-17 12:57
    大佬,mac不支持scriptcat+vscode吗

    应该是可以的吧
    我没用过mac
    但是论坛其他人有
    哥哥可以开个新帖询问
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情

    7 小时前
  • 签到天数: 571 天

    [LV.9]以坛为家II

    26

    主题

    301

    回帖

    1001

    积分

    高级专家

    积分
    1001

    油中2周年生态建设者油中3周年挑战者 lv1

    发表于 2024-3-17 15:30:49 | 显示全部楼层
    放手一搏吧,别顾虑太多
    回复

    使用道具 举报

  • TA的每日心情
    擦汗
    2024-3-25 15:30
  • 签到天数: 135 天

    [LV.7]常住居民III

    6

    主题

    104

    回帖

    199

    积分

    荣誉开发者

    积分
    199

    荣誉开发者油中2周年

    发表于 2024-3-17 23:47:14 | 显示全部楼层
    dgnb !!!!!!!!!
    可恃唯我
    回复

    使用道具 举报

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表