问题描述
所以我正在尝试用 angular 制作一个编辑器,但是当我输入 contenteditable 模糊时。这是预期的吗?我尝试了一些解决方法,但没有任何真正奏效。
我正在做的是捕获文档中的所有 keydown 事件以进行处理,并手动更新 contenteditable。但是,正如您可以想象的那样,这有其自身的一系列问题。我真的不想像这样手动更新它,因为如果我这样做,那么首先使用 contenteditable 就没有任何意义。
这是我的代码:
// editor.component.html
<div class="editor">
<p
(click)="setFocusOnLine($event)"
id="paragraph_{{ index }}"
*ngFor="let line of writtenText; let index = index"
>{{ line }}</p
>
</div>
// editor.component.ts
export class EditorComponent implements OnInit {
public readonly keyCodes: { [key: string]: number } = constants.KEY_CODES;
public showContextMenu = false;
public writtenText: string[] = ["Start typing here"];
public index = 0;
private clickCounter = 0;
private elementToFocus: HTMLElement;
constructor() {}
ngOnInit(): void {
this.forceFocus();
}
private writeOnLine(key: string): void {
let capturedString: string = this.writtenText[this.index]
? this.writtenText[this.index]
: "\n";
capturedString = `${capturedString}${key}`;
this.writtenText[this.index] = capturedString;
}
private createNewLine(): void {
this.index = this.index + 1;
this.writtenText.splice(this.index,0);
}
public setFocusOnLine(event,isOnClick: boolean = true): void {
const elementId: string = event.target.id;
const substring: number = Number(
elementId.substring(elementId.indexOf("_") + 1)
);
this.index = substring ? substring : this.writtenText.length - 1;
this.removeContentEditable();
if (isOnClick) {
this.elementToFocus = event.target;
} else {
setTimeout(() => {
this.elementToFocus = document.getElementById(elementId);
console.log("this.elementToFocus:",this.elementToFocus);
});
}
setTimeout(() => {
this.elementToFocus.setAttribute("contenteditable","true");
this.elementToFocus.focus();
});
this.getSelection();
}
public getSelection(): void {
this.clickCounter = this.clickCounter + 1;
if (this.clickCounter % 2 !== 0) {
return;
}
this.clickCounter = 0;
const selection: any = window.getSelection();
const selectionText: string = selection.toString();
if (selectionText !== constants.IS_EMPTY_STRING) {
this.showContextMenu = true;
}
}
public removeContentEditable(): void {
const elementToClearAttribute: NodeListOf<Element> = document.querySelectorAll(
"[contenteditable=true]"
);
const elementIndex: number =
elementToClearAttribute.length > 0
? elementToClearAttribute.length - 1
: 0;
if (elementIndex > 0) {
setTimeout(() => {
document
.getElementById(elementToClearAttribute[elementIndex].id)
.removeAttribute("contenteditable");
});
}
}
@HostListener("window:keydown",["$event"])
public captureInput(event): void {
console.log("event.which:",event.which);
const isControlCharacter: boolean =
event.which <= this.keyCodes.ControlCharacterMax;
const isDelete: boolean = event.which === this.keyCodes.Delete;
const isFunctionKey: boolean =
event.which >= this.keyCodes.FunctionKeyStart &&
event.which <= this.keyCodes.FunctionKeyEnd;
const isArrowKey: boolean =
event.which >= this.keyCodes.ArrowKeyLeft &&
event.which <= this.keyCodes.ArrowKeyDown;
const isNumLock: boolean = event.which === this.keyCodes.NumLock;
const isContextMenu: boolean =
event.which === this.keyCodes.ContextMenu;
const isPageUp: boolean = event.which === this.keyCodes.PageUp;
const isPageDown: boolean = event.which === this.keyCodes.PageDown;
const isHome: boolean = event.which === this.keyCodes.Home;
const isEnd: boolean = event.which === this.keyCodes.End;
const isInsert: boolean = event.which === this.keyCodes.Insert;
const isEnter: boolean = event.which === this.keyCodes.Enter;
const shouldIgnore: boolean =
(isControlCharacter && isEnter) ||
isDelete ||
isFunctionKey ||
isNumLock ||
isContextMenu ||
isPageUp ||
isPageDown ||
isHome ||
isEnd ||
isInsert;
const shouldPreventDefault: boolean = isArrowKey || isEnter;
if (!shouldPreventDefault && !shouldIgnore) {
this.writeOnLine(event.key);
return;
}
if (event.which === this.keyCodes.Enter) {
this.setEnterFunction();
}
return;
}
private setEnterFunction(): void {
this.createNewLine();
this.forceFocus();
this.writeOnLine("");
}
private forceFocus(): void {
const simulatedEventObject = {
target: { id: `paragraph_${this.index}` },};
this.setFocusOnLine(simulatedEventObject,false);
}
// editor.component.scss
@import "../../assets/variables/colors";
.editor {
p {
padding: 0.75em 0.2em;
margin: 0;
cursor: text;
&.has-focus {
background-color: rebeccapurple;
}
}
[contenteditable] {
&:after {
content: "|";
color: powderblue;
animation-name: blink;
animation-duration: 0.9s;
animation-iteration-count: infinite;
animation-timing-function: ease;
}
&:focus,&:active,&:focus-within,&:focus-visible {
outline: none;
background-color: $focus-background-color;
}
}
}
@keyframes blink {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
我发现问题在于将写入的内容插入到 writeText 变量中,但我不确定如何更改捕获它的方式
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)