【问题标题】:Hypertexting by pasting a link using a toolbar通过使用工具栏粘贴链接进行超文本处理
【发布时间】:2019-02-22 11:07:56
【问题描述】:

我不得不说我这周开始使用 Javascript 和 React,所以我还不是很熟悉它或前端的任何东西。

我在工具栏旁边有一个链接按钮。我希望能够单击它,打开一个文本框,我可以在其中编写链接,然后将文本与它一起超文本。只想说任何提示都值得赞赏。

类似于以下图片。

我已经对工具栏进行了编码,并且正在使用编辑器的 slate-react 模块(使用的文本编辑器)。我正在尝试遵循 GitHub 示例中所做的操作,这并不完全相同。

因此,本质上,它是工具栏内的链接组件,它位于“工具提示”组件(包含水平工具栏和另一个垂直栏)内,位于编辑器内。

我的问题是:如何使用 react 和 slate 编辑器将工具栏中的链接绑定在一起? Link 组件是否需要 state 和 onChange 函数?如何在工具栏(按钮组)中包含链接组件,以及“const Marks”中的其他按钮?

我知道这些问题可能很基础,但我是初学者,希望得到解释。

我创建的 Link 组件可以包装和解开链接。点击后,

onClickLink = event => {
  event.preventDefault()
  const { value } = this.state
  const hasLinks = this.hasLinks()
  const change = value.change()

  if (hasLinks) {
    change.call(this.unwrapLink)
  } 

  else 
  {
    const href = window.prompt('Enter the URL of the link:')
    change.call(this.wrapLink, href)
  } 

  this.onChange(change)
}

wrap、unwrap 和 hasLinks 布尔值

class Links extends React.Component {
onChange = ({ value }) => {
      this.setState({ value })
}
wrapLink(change, href) {
change.wrapInline({
  type: 'link',
  data: { href },
})

change.moveToEnd() }

unwrapLink(change) {
change.unwrapInline('link') }

hasLinks = () => {
  const { value } = this.state
  return value.inlines.some(inline => inline.type == 'link')
}

在编辑器中渲染它。

const renderNode = ({ children, node, attributes }) => {
  switch (node.type) {
     case 'link': {
        const { data } = node
        const href = data.get('href')
        return (
          <a {...attributes} href={href}>
            {children}
          </a>
        )
      }

“工具提示”组件,包含 MarkSelect(如图中的水平工具栏)和另一个称为 NodeSelector 的垂直栏。

    function Tooltip({ onChange, value }: Props) {
  return (
    <Fragment>
      <SelectionPlacement
        value={value}
        render={({ placement: { left, top, isActive } }) => (
          <div
            id=...
              {
                isActive,
              },
            )}
            style={{ left, top }}
          >
            <NodeSelector onChange={onChange} value={value} />
            <MarkSelector onChange={onChange} value={value} />
          </div>
        )}
      />

按钮组中的 MarkSelector 和其他标记(按钮)。

const MarkSelector = function MarkSelector({ onChange, value }: Props) {
  return (
    <ButtonGroup className=...>
      {Marks.map(({ tooltip, text, type }) => {
        const isActive = value.activeMarks.some(mark => mark.type === type);
        return (
          <Tooltip key={type} title={tooltip}>
            <Button
              className={classNames({ 'secondary-color': isActive })}
              onMouseDown={event => {
                event.preventDefault();

                const change = value.change().toggleMark(type);
                onChange(change);
              }}
              size=...
              style=...
              }}
            >
              {text}
            </Button>
          </Tooltip>
        );
      })}
    </ButtonGroup>
  );
};

const Marks = [
  {
    type: BOLD,
    text: <strong>B</strong>,
    tooltip: (
      <strong>
        Bold
        <div className=...</div>
      </strong>
    ),
  },
  {
    type: ITALIC,
    text:...

带有工具提示的编辑器。

render() {
const { onChangeHandler, onKeyDown, value, readOnly } = this.props;
return (
  <div
    className=...
    id=...
    style=..
  >
    {!readOnly && (
      <EditorTooltip value={value} onChange={onChangeHandler} />
    )}

    <SlateEditor
      ref=...
      className=...
      placeholder=...
      value={value}
      plugins={plugins}
      onChange={onChangeHandler}
      onKeyDown={onKeyDown}
      renderNode={renderNode}
      renderMark={renderMark}
      readOnly={readOnly}
    />
    {!readOnly && <ClickablePadding onClick={this.focusAtEnd} grow />}
  </div>
);

}

【问题讨论】:

    标签: javascript node.js reactjs


    【解决方案1】:

    虽然不推荐在数据驱动的前端框架中直接操作 DOM,但您始终可以获取链接的 HTML 元素,并根据内部状态设置其 innerHTML(即超文本)。这很 hacky,但它可能会起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-20
      • 2021-07-18
      • 1970-01-01
      • 2019-03-17
      • 1970-01-01
      • 2022-06-13
      相关资源
      最近更新 更多