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
相关产品推荐
相关产品推荐

