0

我正在尝试在 slate.js 上构建一个编辑器

从 Slate 官方示例中复制了大部分代码。

https://github.com/ianstormtaylor/slate/blob/master/examples/hovering-menu/index.js

每当我选择一个文本时,一切都很完美。定位很流畅,就像一个魅力。但是在选择/取消选择标记操作后定位错误。


这是示例 gif。https://i.stack.imgur.com/OWvMU.gif

我改变了菜单类名和 HOC 悬停菜单。

import React, { Component } from 'react';

function withHoverMenu (Menu) {
  return class extends React.Component {
    componentDidMount = () => {
      this.updateMenu()
    }
    componentDidUpdate = () => {
      this.updateMenu()
    }
    updateMenu = () => {
      const { value } = this.props
      const menu = this.menu
      if (!menu) return

      if (value.isBlurred || value.isEmpty) {
        menu.removeAttribute('style')
        return
      }

      const selection = window.getSelection()
      const range = selection.getRangeAt(0)
      const rect = range.getBoundingClientRect()
      console.log(rect)
      menu.style.opacity = 1
      menu.style.top = `${rect.top + window.scrollY - menu.offsetHeight}px`
      menu.style.left = `${rect.left + window.scrollX - menu.offsetWidth / 2 + rect.width / 2}px`
    }
    menuRef = (menu) => {
      this.menu = menu
    }
    render () {
      return <Menu className="slate-rte-balloon" menuRef={this.menuRef} {...this.props} />
    }
  }
}

export default withHoverMenu;

编辑器部分略有不同,但没什么。

import Menu from './menu';
import withHoverMenu from './menu-balloon';

const HoveredMenu = withHoverMenu(Menu)

class SlateRTE extends Component {
  state = {
    value: Value.fromJSON(initialValue)
  }
  onChange = ({ value }) => {
    this.setState({ value })
  }
  render() {
    return (
      <div className="slate-rte">
        <HoveredMenu value={this.state.value} onChange={this.onChange} />
        <Editor placeholder="Enter some text..." renderMark={this.renderMark} value={this.state.value} onChange={this.onChange} />
      </div>
    );
  }
  renderMark = (props) => {
    const { children, mark } = props
    switch (mark.type) {
      case 'bold': return <strong>{children}</strong>
      case 'code': return <code>{children}</code>
      case 'italic': return <em>{children}</em>
      case 'underlined': return <u>{children}</u>
    }
  }
}
4

0 回答 0