javascript - 插入到 contentEditable DIV 的按钮上的单击事件不起作用
问题描述
我有一个 contentEditable DIV。我使用以下指令来管理它:
<div
class="msg-input-area"
[class.focused]="isMsgAreaFocused"
contenteditable
[contenteditableModel]="msgText"
(contenteditableModelChange)="onMsgTextChange($event)"
(contenteditableModelSubmit)="onMsgSend()"
(removeHashSign)="removeHashSign()"
placeholder="Compose your comment here"
tabindex="0"
(focus)="isMsgAreaFocused = true"
(blur)="isMsgAreaFocused = false"
#msgInputArea
></div>
@Directive({
selector: '[contenteditableModel]',
host: {
'(blur)': 'onEdit()',
'(keydown)': 'onKeyDown($event)',
'(keyup)': 'onEdit()'
}
})
export class ContentEditableDirective implements OnChanges {
@Input('contenteditableModel') model: string;
@Output('contenteditableModelChange') valueChanges = new EventEmitter<string>();
@Output('contenteditableModelSubmit') submit = new EventEmitter<void>();
@Output('removeHashSign') removeHashSign = new EventEmitter<void>();
constructor(private elementRef: ElementRef<HTMLElement>) {}
ngOnChanges(changes: SimpleChanges) {
if (changes.model) {
this.refreshView();
}
}
onEdit(): void {
const value = this.elementRef.nativeElement.innerText;
this.valueChanges.emit(value);
}
onKeyDown(event: KeyboardEvent): void {
if (!(event.ctrlKey || event.metaKey) && event.code === 'Enter') {
// submit
this.valueChanges.emit(this.elementRef.nativeElement.innerHTML);
this.submit.emit();
event.preventDefault();
return;
} else if (event.code === 'Backspace' && this.model[this.model.length - 1] === '#') {
// remove #
this.removeHashSign.emit();
return;
}
this.onEdit();
}
private refreshView(): void {
if (!this.model) {
this.elementRef.nativeElement.textContent = this.model;
} else if (this.model?.includes('<button')) {
this.elementRef.nativeElement.innerHTML = this.model;
}
}
}
如果输入#符号,则在 DIV 内添加一个按钮元素
... => {
let msgWithTag = this.msgText.slice(0, -1);
msgWithTag += this.generateLinkTag(tag);
this.msgText = msgWithTag;
}
...
private generateLinkTag(tag: IConversationTag): string {
return `<button style="color: #0d95db; font-weight: 600; cursor: pointer;">#${tag.name}</button> `;
}
到目前为止,一切都很好。该按钮显示在 DOM 内部。
如何向按钮添加(单击)事件?
我尝试了几种方法:
return `<button (click)="() => myFunc()" style="color: #0d95db; font-weight: 600; cursor: pointer;">#${tag.name}</button> `;
and
ngAfterViewInit() {
const parser = new DOMParser();
const doc = parser.parseFromString(myString, 'text/html');
doc.body.childNodes.forEach((node: ChildNode) => {
if (node.nodeName.toLowerCase() === 'button') {
console.log(node)
node.addEventListener('click', () => {
console.log('click')
});
}
});
if (this.msgContent) {
this.msgContent.nativeElement.innerHTML = doc.body.innerHTML;
}
}
在这两种情况下(点击)回调函数都不会被调用。
解决方案
对于按钮上的单击处理程序,语法应该是组件(click)="myFunc()"
中myFunc
定义的函数。
推荐阅读
- mysql - 列计数与第 1 行的值计数不匹配 - MySQL
- javascript - 使用useState Hook时如何重构具有先前状态的if else if?
- python - 我需要在某个日期创建的所有子文件夹中找到所有文本文件,打开它们,然后将内容复制到一个文本文件中
- ag-grid - 我想将事件侦听器添加到 ag-grid 中的自定义列定义
- javascript - TypeError:无法读取未定义的属性“hasOwnProperty”
- javascript - StencilJs 组件不在另一个 stenciljs 项目中呈现
- c++ - 是什么导致了我的 C++ 程序中的 Stack Smashing 错误?
- ruby-on-rails - 在部署到子目录的 Rails 应用程序中隐藏路由中的控制器
- c# - 我将如何随机化游戏中气氛的构成?
- c - 在 main 之外分配内存的问题