如何在模式中重用现有的 HTML 元素?

Posted

技术标签:

【中文标题】如何在模式中重用现有的 HTML 元素?【英文标题】:How to reuse existing HTML element in a modal? 【发布时间】:2021-08-24 18:33:18 【问题描述】:

考虑一个具有自定义组件 <foo> 的 UI - 现在假设它只是文本。

<foo id="foo-id">SOMETEXT</foo>

我想在 UI 上的两个位置显示此内容 - 其中一个是模态的。如何将模态内容委托给这个现有元素?我正在使用对 Jquery/angularjs 或原生 html 解决方案开放。

<foo id="foo-id">SOMETEXT</foo>

<div class="modal fade" id="exampleModal" ...>
      ...
      <div class="modal-body">
        ### REFERENCE TO ID #foo-id here ###
      </div>
  </div

我试图避免使用元素的第二个实例,例如:

<foo id="foo-id">SOMETEXT</foo>

<div class="modal fade" id="exampleModal" ...>
      ...
      <div class="modal-body">
            <foo id="foo-id-2">SOMETEXT</foo>
      </div>
  </div  

更多上下文

我真正想要这样做的原因是因为我们有一个带有下拉扩展器的网页,它已经呈现了丰富的组件。我们正在尝试添加一个“弹出”按钮,该按钮将在模式窗口中显示渲染的元素。因为在按下弹出窗口时元素已经处于正确的加载状态,所以将组件委托给预定义的组件而不是重新创建是有意义的。

Stack 是 angularJS、bootstrap 3、jquery,我无法更改:(

【问题讨论】:

【参考方案1】:

我会在 vanilla javascript 中执行此操作的方式是创建一个函数,该函数创建一个模态元素,然后将其附加到您想要的 DOM 元素中,例如身体。

一个例子:

function createModal(modalId, fooElement)
  const modalDiv = document.createElement('div');
  modalDiv.classList.add('modal');
  modalDiv.classList.add('fade');
  modalDiv.id = modalId;

  const modalBodyDiv = document.createElement('div');
  modalBodyDiv.classList.add('modal-body');

  modalBodyDiv.append(fooElement);

  return modalDiv;

然后使用它来创建 N 个模态元素并将它们附加到任何你想要的地方,例如身体,像这样:

const modal1 = createModal('myModal1', fooElement);

document.body.append(modal1)

这样你的 html 会更干净。 注意:这个fooElement必须是DOM元素,否则会抛出错误。 希望它有效!

【讨论】:

【参考方案2】:

如果你不需要有两个副本,你可以尝试分离元素并将其插入到他的新位置

let $fooContent = $("#foo-id");
let $myModal = $("#exampleModal > .modal-body");
...

// set it
$myModal.html( $fooContent.detach() );

// back it
$initialFooContentLocation.append( $fooContent.detach() );

【讨论】:

所以我认为这是解决方案,但是当我这样做时,模式中显示的所有 HTML 元素都不起作用。例如,如果元素具有按钮和其他动态内容,则它们在模式中呈现时将不再起作用。这是预期的吗? 您的事件是否使用 .on/.live 设置到原始包装上?如果直接使用元素设置它必须可以正常工作,但我不知道在这种情况下角度如何工作 我没有这样的显式绑定 将它备份到原始位置后是否再次起作用?要在 dom 部分之后测试事件,您也可以尝试放置一个直接事件 $fooContent.on('click', 'button', alert.bind(null,"work"));如果它有效,它可能是一个角度特定的问题,或者你如何声明你的 jquery 事件 没关系 - 我的实现中有一些错字或其他东西。我最终不得不通过 ID 直接选择模态体,而不是你在这里做的方式,它似乎工作。因此,我的应用程序中的选择器可能针对多个模式。再次感谢 - 让我将此标记为已接受【参考方案3】:

接受的答案对我有用;但是,为了完整起见,这里有另一种方法。

使用$scope/$rootScope 事件发射器在组件之间广播事件。如果组件有明确的父子关系,$scope 通常就足够了,如果它们是兄弟,那么它们可以通过$rootScope 共享事件。

由于这是一个angularJS项目,我关注this simple guide.

【讨论】:

以上是关于如何在模式中重用现有的 HTML 元素?的主要内容,如果未能解决你的问题,请参考以下文章

如何将简码插入现有的 html 元素(wordpress)?

如何让 Widget PendingIntend 重用现有的 MainActivity 实例?

使用反应渲染时如何访问现有的 dom 元素?

如何为新的面板类重用现有的布局代码?

如何使用附加模式将音频录制到现有的音频文件中?

IPython Notebook:代码重用