【问题标题】:ReactJS - render external DOM element with eventsReactJS - 使用事件渲染外部 DOM 元素
【发布时间】:2020-08-20 07:48:41
【问题描述】:

我使用 ReactJS 16.13.1,现在我想渲染一个带有事件的外部 DOM 元素。

所以我们假设有一个

<button type="button" id="testBtnSiri" onclick="alert('Functionality exists');">Testbutton Siri</button>

这是由库生成的(还有一些其他事件)。

现在我想要: 复制它(带有事件)并在我的 ReactJS 渲染函数中渲染这个元素。

最合适的方法是什么?

我不是在寻找 ReactDOM.createPortal()。

我想在我的 React 组件中显示一个带有事件的外部 DOM 元素。

【问题讨论】:

  • @yAzou 不,这没有帮助。他们将一个 React 组件渲染到另一个 DOM 元素中。我正在寻找完全相反的情况。我想在我的 ReactJS 组件中显示一个带有事件的外部 DOM 元素。

标签: javascript reactjs dom


【解决方案1】:

为了在你的 React 代码中使用 HTML,你需要在一个元素上使用 dangerouslySetInnelHTML 属性。

function libraryReturnedHTML() {
  return '<button type="button" id="testBtnSiri" onclick="alert('Functionality exists');">Testbutton Siri</button>'
}

function MyComponent() {
  return <div dangerouslySetInnerHTML={__html: libraryReturnedHTML} />;
}

但是您必须知道,这会使您的代码容易受到 XSS 攻击。为了防止出现这种情况,最好先清理您的 HTML,以便您只有所需的脚本和链接标签。为了清理html,您可以简单地使用普通的Javascript函数和document.createTreeWalker

您还可以利用现有的库来清理您的 HTML。例如sanitize-html 然而,消毒只是一个额外的预防措施。

【讨论】:

  • 这对我没有帮助,因为我还需要按钮上的其他功能(事件)。
  • 什么样的功能。它们都将附带库为您提供的脚本
  • 一个完整的上传功能和其他 80 个我无法手动重建的事件。
  • 正如我在回答中所说的,事件和其他东西应该由库提供,并带有它返回的 HTML
  • 它对我一点帮助都没有。我的 ReactJS 应用程序是在外部库之后呈现的,如果我只使用 html 来呈现相同的按钮,那么按钮的功能(事件)将不存在。
【解决方案2】:

Node.addEventListener() 上创建一个包装器,它将在其他库呈现按钮时捕获添加到按钮的所有事件侦听器。它可能看起来像这样(这段代码必须在外部库创建按钮之前执行):

let ael = Node.prototype.addEventListener
let eventListeners = []
Node.prototype.addEventListener = function(type: string, listener: EventListenerOrEventListenerObject | null, options?: boolean | AddEventListenerOptions): void {
  if((this as HTMLElement).id === "buttonID")
    eventListeners.push({type, listener, options})
  this.addEventListener = ael
  this.addEventListener(type, listener, options)
}

使用您的按钮创建反应组件 - 您可以创建一个新组件,或使用 dangerouslySetInnerHtml 注入。将 eventListeners 数组作为道具传递。在组件挂载和卸载时,将事件侦听器添加/删除到您的按钮。

function ClonedButton({eventListeners}: any){
  useEffect(()=>{
    eventListeners.forEach((el) => document.getElementById("my-migrated-new-button")!.addEventListener(el.type, el.listener, el.options));
    return () => {
      eventListeners.forEach((el) => document.getElementById("my-migrated-new-button")!.removeEventListener(el.type, el.listener, el.options));
    }
  }, [])
  return <button id="my-migrated-new-button"></button>
}

【讨论】:

  • 听起来是个好主意。然后你将如何在 ReactJS 中渲染克隆的元素?
  • 你能举个例子吗?
  • @Gutelaunetyp 我提供了使用 Typescript 和 react 钩子的示例。希望这会有所帮助。
  • 嗨,昨天我尝试使用 jQuery(带有事件)克隆元素,但已经不起作用了。你能看看stackoverflow.com/questions/61731465/… 吗?在那里,我还以一种不同的、更笼统的方式描述了我的问题。
猜你喜欢
  • 2021-08-05
  • 2015-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-09
  • 2021-08-02
相关资源
最近更新 更多