我有以下Angular 2代码:
write.component.ts:
import { CommentHeaderComponent } from './comment.header.component';
import { StyleService } from './../../services/services/style.service';
import { Parameters } from './../../services/services/parameters';
import { Component, Input, ViewChild,ElementRef,HostBinding} from "@angular/core";
import { ContenteditableModel } from './../directives/contenteditable.directive';
@Component({
selector:'write',
templateUrl:'app/templates/write.component.html',
styleUrls:['app/templates/css/write.component.css']
})
export class WriteComponent
{
@HostBinding('class.hbox')
parameters:Parameters;
private writeText:string="";
private rows:number=1;
private maxRows:number=4;
private comment:boolean=false;
private lineHeight:string="1.7em";
@ViewChild('writeBox') writeBox:ElementRef;
constructor(private stService:StyleService){}
ngOnInit()
{
this.writeBox.nativeElement.innerText="";
this.stService.setProperty(this.writeBox,[{rows:this.rows}]);
this.stService.setStyle(this.writeBox,[{lineHeight:this.lineHeight}]);
if (this.parameters.Iskey("comment"))
{
this.comment=true;
}
}
write(data:any)
{
this.parameters.cfunc({event:"comment",message : this.writeText});
this.writeText="";
}
getWriteText():String
{
return this.writeText;
}
}
write.component.html:
<div contenteditable="true" #writeBox [ceModel]="writeText" (ceChange)="writeText=$event" [innerHTML]="writeText">
</div>
<ng-template [ngIf]="this.comment">
<button type="button" (click)="files($event)" class="btn fa fa-paperclip"> </button>
</ng-template>
<button type="button" (click)="write($event)" class="btn fa fa-chevron-right"> </button>
contenteditable.directive.ts:
从'./../../services/service/validator.service'导入{ValidatorService}; 从'@ angular / core'导入{Directive,HostListener,Input,ElementRef,OnInit,SimpleChanges,EventEmitter,Output};
@Directive({selector: '[ceModel]'})
export class ContenteditableModel
{
@Input('ceModel') ceModel: any="";
@Output('ceChange') ceChange = new EventEmitter();
constructor(private elRef: ElementRef,private v:ValidatorService) {}
@HostListener('keyup', ['$event'])
onChange($event: any)
{
if ($event.keyCode==32)
{
console.log(this.ceModel);
this.ceModel="<a>"+this.ceModel+"<\a>";
this.ceChange.emit(this.ceModel);
return;
}
this.ceModel=this.elRef.nativeElement.innerText;
this.ceChange.emit(this.ceModel);
}
@HostListener('paste', ['$event'])
onPaste($event: any)
{
console.log($event);
}
}
我想动态更新一个有意义的div,请参阅write.component.html,它链接到由指令contenteditable.directive.ts管理的模型。类变量writeText被发送到指令以检查用户是否已写入url,如果是这种情况,则url内容应转换为:url。这在div中呈现为html:
问题是,每当我键入一些文本时,插入符/光标总是会跳转 到开始位置:
是否可以手动将光标移动到div内容的末尾? 内容可以是文本和HTML。 我试过这里提出的解决方案没有运气:
Set the caret position always to end in contenteditable div
感谢您的帮助。
答案 0 :(得分:2)
在我的问题中,我在输入时触发焦点(它自动转到新行)并重新聚焦(到最后一个todo的最后一个字符)如果我删除
....
// somewhere you trigger that focus event:
(div:HTMLElement) => {
// div.focus();
if (div.lastChild) this.setSelectionRange(div)
else div.focus();
this.changeDetector.detectChanges();
}
....
setSelectionRange(el:HTMLElement) {
let range = document.createRange();
let pos = el.lastChild.textContent.length;
let sel = window.getSelection();
console.log('el last child',el.lastChild.textContent.length,typeof(el.lastChild.textContent.length));
range.setStart(el.lastChild, pos);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
注意“el.lastChild”,你的contenteditable使用(textContent或innerHTML?)
答案 1 :(得分:1)
我希望你仍然有兴趣得到答案。我能想象的最简单的方法是保存对<a>
节点的引用并使用它来放置插入符号。
在ContenteditableModel
内,您只需创建以下内容:
private moveCaret(): void {
let range = document.createRange(),
pos = this.elRef.lastChild.innerText.length - 1,
sel = window.getSelection();
range.setStart(this.elRef, pos);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
这允许您使用elRef将插入符号放在其最后一个子节点<a>
元素的最后一个字符处。