1

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

<div onPaste="onPaste()">
  <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()">
  <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>

谢谢

4

1 回答 1

1

Pasteevent 被所有 HTML 元素拦截,但它只对可编辑上下文的元素产生影响,例如<input>s 和<textarea>s。
诸如<div>s 或s 之类的元素只有在它们能够具有内容的情况<p>下才能被接受。(paste)这可以通过打开contenteditable

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

以下是API 文档中关于此的摘录:

如果光标位于可编辑上下文中,则粘贴操作将以给定上下文支持的最合适格式(如果有)插入剪贴板数据。

粘贴操作在不可编辑的上下文中无效,但无论如何都会触发粘贴事件。

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

为了帮助防止滥用,除非脚本在具有焦点的文档的上下文中执行,否则此 API 不得可用。

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

--- 编辑 ---

使您的按钮内容可编辑会产生一些问题。

  • 用户可以聚焦该区域,它将有一个光标。这可以通过样式来修复

    [contenteditable] { car​​et-color: 透明;}

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

    <button class="__cancel" aria-label="Close" mat-icon-button onClick="onClickCancel()" onPaste="onPaste($event)" contenteditable="true" onKeydown="preventKey($event)">

如:

  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 - 除非我们设置样式

    用户选择:自动;

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

于 2021-10-26T18:14:07.107 回答