我正在尝试在 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>
}
}
}