You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中activeElement无法检测p-editor的问题求助

问题:p-editor组件无法正确获取焦点索引

在Angular项目中,需要选中id以placeholder开头且未禁用的input、select和p-editor元素,并获取当前选中元素的索引。目前逻辑对input和select组件有效,但p-editor始终返回focusedIndex=-1。

相关代码

HTML代码

<p-editor #editor *ngSwitchCase="1" #textInput="ngModel" [(ngModel)]="placeholder.value" (onTextChange)="handleInputChange($event)"
          id="placeholder{{i}}" name="placeholder{{i}}" [placeholder]="l('AddText')" required
          [style]="{height:'180px', 'width': '100%'}" formats>
  <p-header>
    <span class="ql-formats">
      <button class="ql-bold" aria-label="Bold"></button>
      <button class="ql-italic" aria-label="Italic"></button>
      <button class="ql-underline" aria-label="Underline"></button>
      <button class="ql-strike" aria-label="Strike"></button>
    </span>
    <span class="ql-formats">
      <button class="ql-list" value="ordered"></button>
      <button class="ql-list" value="bullet"></button>
    </span>
    <span class="ql-formats">
      <select class="ql-font">
        <option value="calibri">Calibri</option>
        <option value="microsoftsansserif">Sans Serif</option>
        <option value="inconsolata">Inconsolata</option>
        <option value="mirza">Mirza</option>
        <option value="arial">Arial</option>
      </select>
    </span>
    <span class="ql-formats">
      <select class="ql-size">
        <option value="8pt">8pt</option>
        <option value="9pt">9pt</option>
        <option value="10pt">10pt</option>
        <option value="11pt">11pt</option>
        <!-- <option value="12pt">12pt</option> -->
        <option value="12.5pt">12.5pt</option> <!--12pt non viene rilevato da Word, funzionano tutti i numeri tranne questo.-->
        <option value="13pt">13pt</option>
        <option value="14pt">14pt</option>
      </select>
    </span>
    <span class="ql-formats">
      <select title="Text Color" class="ql-color" defaultValue="rgb(0, 0, 0)">
        <option value="#000000" label="#000000"></option>
        <option value="#e60000" label="#e60000"></option>
        <option value="#ff9900" label="#ff9900"></option>
        <option value="#ffff00" label="#ffff00"></option>
        <option value="#008a00" label="#008a00"></option>
        <option value="#0066cc" label="#0066cc"></option>
        <option value="#ffffff" label="#ffffff"></option>
        <option value="#facccc" label="#facccc"></option>
        <option value="#ffebcc" label="#ffebcc"></option>
        <option value="#ffffcc" label="#ffffcc"></option>
        <option value="#cce8cc" label="#cce8cc"></option>
        <option value="#cce0f5" label="#cce0f5"></option>
        <option value="#bbbbbb" label="#bbbbbb"></option>
        <option value="#f06666" label="#f06666"></option>
        <option value="#ffc266" label="#ffc266"></option>
        <option value="#ffff66" label="#ffff66"></option>
        <option value="#66b966" label="#66b966"></option>
        <option value="#66a3e0" label="#66a3e0"></option>
      </select>
      <select title="Background Color" class="ql-background"
              defaultValue="rgb(255, 255, 255)">
        <option value="#000000" label="#000000"></option>
        <option value="#e60000" label="#e60000"></option>
        <option value="#ff9900" label="#ff9900"></option>
        <option value="#ffff00" label="#ffff00"></option>
        <option value="#008a00" label="#008a00"></option>
        <option value="#0066cc" label="#0066cc"></option>
        <option value="#ffffff" label="#ffffff"></option>
        <option value="#facccc" label="#facccc"></option>
        <option value="#ffebcc" label="#ffebcc"></option>
        <option value="#ffffcc" label="#ffffcc"></option>
        <option value="#cce8cc" label="#cce8cc"></option>
        <option value="#cce0f5" label="#cce0f5"></option>
        <option value="#bbbbbb" label="#bbbbbb"></option>
        <option value="#f06666" label="#f06666"></option>
        <option value="#ffc266" label="#ffc266"></option>
        <option value="#ffff66" label="#ffff66"></option>
        <option value="#66b966" label="#66b966"></option>
        <option value="#66a3e0" label="#66a3e0"></option>
      </select>
    </span>
  </p-header>
</p-editor>

TypeScript代码

this.focusableElements = Array.from(
  document.querySelectorAll("input[id^='placeholder']:not([disabled]), select[id^='placeholder']:not([disabled]), p-editor[id^='placeholder']:not([disabled]), input.p-element:not([disabled])")
) as HTMLElement[];
let focusedIndex = this.focusableElements.findIndex((element) => element === document.activeElement);

尝试过的无效代码

focusedIndex == this.focusableElements.findIndex((element) => element.tagName.toLowerCase() === "p-editor" && element.getAttribute("id") === "placeholder");

解决方案

问题根源

p-editor是PrimeNG基于Quill封装的富文本组件,实际获得焦点的是其内部的.ql-editor容器节点,而非<p-editor>自定义元素本身。因此document.activeElement指向的是内部DOM,和你存入focusableElements的<p-editor>元素不匹配,导致findIndex返回-1。

方案1:通过activeElement向上查找父级p-editor

修改索引查找逻辑,当焦点在编辑器内部元素时,自动找到对应的<p-editor>父节点再匹配:

let activeElement = document.activeElement;
// 向上查找最近的符合条件的p-editor父元素
const activeEditor = activeElement?.closest('p-editor[id^="placeholder"]');

let focusedIndex = this.focusableElements.findIndex(element => {
  // 匹配原生input/select,或者匹配对应的p-editor
  return element === activeElement || element === activeEditor;
});

方案2:监听p-editor的焦点事件记录实例

在HTML中给p-editor添加焦点/失焦事件:

<p-editor #editor *ngSwitchCase="1" ... (focus)="onEditorFocus(editor)" (blur)="onEditorBlur()">
  <!-- 编辑器内容 -->
</p-editor>

在TypeScript中维护当前聚焦的编辑器实例:

private currentFocusedEditor: HTMLElement | null = null;

onEditorFocus(editor: any) {
  // 获取p-editor对应的原生DOM元素
  this.currentFocusedEditor = editor.nativeElement;
}

onEditorBlur() {
  this.currentFocusedEditor = null;
}

// 获取索引时直接匹配记录的实例
let focusedIndex = this.focusableElements.findIndex(element => element === this.currentFocusedEditor);

额外修正点

你之前尝试的代码中,element.getAttribute("id") === "placeholder"是错误的——你的id是placeholder{{i}}(如placeholder0、placeholder1),应该用element.id.startsWith('placeholder')来判断id前缀。

内容的提问来源于stack exchange,提问作者Peppino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 12:25:53