如何阻止按钮阻止 onPaste 事件

How do I stop buttons from blocking an onPaste event

我有一个图像模式,用户可以在其中上传或粘贴图像。 两者都很好用,除了目前我在模式上有按钮捕获焦点,所以粘贴只能通过手动单击按钮外部来进行。如果此组件具有焦点,或者组件内的任何内容都具有焦点,我希望任何粘贴都能正常工作。

<div onPaste="onPaste()">
  <button class="__cancel" aria-label="Close" onClick="onClickCancel()">
  <button ... upload .../>
</div>

有没有办法让粘贴操作通过按钮传递?

这实际上是一个 angular 应用程序,因此下面更接近我的实际代码:

<div (paste)="onPaste($event)" cdkTrapFocusAutoCapture cdkTrapFocus>
  <button class="__cancel" aria-label="Close" (onClick)="onClickCancel()">
  <button ... upload .../>
</div>

我试过将粘贴方法添加到按钮,但它们没有触发。

<div (paste)="onPaste($event)" cdkTrapFocusAutoCapture cdkTrapFocus>
  <button class="__cancel" aria-label="Close" (onClick)="onClickCancel()" (paste)="onPaste($event)">
  <button ... upload   (paste)="onPaste($event)".../>
</div>

谢谢

Paste事件被所有HTML元素拦截,但它只对可编辑上下文的元素有效,例如<input>s和<textarea>s .
<div>s 或 <p>s 等元素只有在能够包含内容的情况下才能接受 (paste)。这可以通过打开 contenteditable:

<div onPaste="onPaste()" contenteditable="true">
  <button class="__cancel" aria-label="Close" (click)="onClickCancel()">
                                              //^-here also
  <button ... upload .../>
</div>

这是 API doc 关于 这个:

If the cursor is in an editable context, the paste action will insert clipboard data in the most suitable format (if any) supported for the given context.

The paste action has no effect in a non-editable context, but the paste event fires regardless.

此外,由于隐私限制,该元素应成为焦点:

To help prevent abuse, this API must not be available unless the script is executing in the context of a document that has focus.

不同的浏览器可能有不同的行为,但牢记这些限制可能有助于使代码在任何地方都能正常工作。

--- 编辑 ---

让您的按钮可编辑会产生一些问题。

  • 用户可以聚焦那个区域,它会有一个光标。这可以通过

    样式来解决

    [contenteditable] { 插入符号颜色:透明; }

  • 它还使用户能够更改其内容,这可能是不受欢迎的。这可以通过添加 keydown 处理程序来解决:

如:

  preventKey(event: KeyboardEvent) {
    // Buttons need contenteditable to receive (paste),
    // but we don't want our buttons to be editable, so this is blocked by this function.
    if (
      !(
        event.key === 'Tab' ||
        event.keyCode == 9 ||
        ((event.ctrlKey || event.metaKey) &&
          (event.key === 'v' || event.keyCode == 86))
      )
    ) {
      event.preventDefault();
    }
  }
  • 粘贴到 contenteditable 元素在 safari 上不起作用 - 除非我们设置样式

    用户-select:自动;

如果您有一个 angular 项目(如在原始问题中),这会破坏 cdkTrapFocus。据作者所知,这是 angular 中的一个错误。参见 https://github.com/angular/components/issues/23846