#javascript #html #angular #dom #dom-events
#javascript #HTML #angular #dom #dom-события
Вопрос:
У меня есть раздел с возможностью редактирования содержимого. Для управления им я использую следующую директиву:
<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) amp;amp; event.code === 'Enter') {
// submit
this.valueChanges.emit(this.elementRef.nativeElement.innerHTML);
this.submit.emit();
event.preventDefault();
return;
} else if (event.code === 'Backspace' amp;amp; 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;
}
}
}
Если введен знак #, то элемент button добавляется внутри 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>amp;nbsp;`;
}
Пока все хорошо. Кнопка отображается внутри DOM.
Как я могу добавить событие (щелчок) к кнопке?
Я пробовал несколько способов:
return `<button (click)="() => myFunc()" style="color: #0d95db; font-weight: 600; cursor: pointer;">#${tag.name}</button>amp;nbsp;`;
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;
}
}
В обоих случаях (щелчок) функции обратного вызова не вызываются.
Ответ №1:
Для обработчика щелчка по кнопке синтаксис должен быть (click)="myFunc()"
таким: where myFunc
— это функция, определенная в вашем компоненте.