我们先来看下最终的交互效果:
思路:
1.创建一个autocomplete组件,并且接受一个名为Dom参数.(Dom是与之对应的文本框的节点)
2.创建一个指令[appFjAutocomplete],exportAs设置为:‘app-fj’
3.页面上,在文本框上使用指令appFjAutocomplete,并且添加一个变量#departmentName,并且赋值为app-fj,,
4.页面上,在<autocomplete>上将文本框上的Dom赋值为[Dom]='departmentName'
创建一个指令appFjAutocomplete
@Directive({
selector: '[appFjAutocomplete]',
exportAs:'app-fj'
})
export class FjAutocompleteDirective {
el:ElementRef
constructor(el: ElementRef) {
this.el = el;
}
@Input('appFjAutocomplete') fjAutocomplete: string; // 传进来的方式
if(this.fjAutocomplete === 'auto'){...}
}
创建autocomplete组件,并对弹出的内容层进行定位
export class AutocompleteComponent implements OnInit {
autoIsShow:boolean = false;
listStyle:{width?:string,top?:string,left?:string,'pointer-events'?:string} = {
width:'0px',
top:'0px',
left:'0px',
'pointer-events':'auto'
}
@Input() Dom;
@Output() itemSelected: EventEmitter<any> = new EventEmitter();
constructor() {}
ngOnInit() {
this.Dom.el.nativeElement.onfocus = ()=>{
this.autoIsShow = true;
const getPos = this.getPos()
this.listStyle = {
'width':`${getPos.width}px`,
'left':`${getPos.left}px`,
'top':`${getPos.top+getPos.height}px`,
'pointer-events': 'auto'
}
console.log(this.autoIsShow)
}
document.addEventListener('click',()=>{
this.autoIsShow = false;
})
this.Dom.el.nativeElement.onclick = (event) => {
this.stopPropagation(event);
}
// this.Dom.el.nativeElement.style.backgroundColor = 'red'
}
/**点击内部的item,关闭auto */
selected(event){
this.autoIsShow = false;
this.itemSelected.emit(event);
}
/* 阻止冒泡 */
stopPropagation(event) {
event = event || window.event;
event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true;
}
getPos() {
const scrollx = document.documentElement.scrollLeft || document.body.scrollLeft,
scrollt = document.documentElement.scrollTop || document.body.scrollTop;
const pos = this.Dom.el.nativeElement.getBoundingClientRect();
return {
top: pos.top + scrollt,
right: pos.right + scrollx,
bottom: pos.bottom + scrollt,
left: pos.left + scrollx,
width:pos.width,
height:pos.height
}
}
}
页面上使用:
<input type="text" [appFjAutocomplete]="'auto'" #departmentName="app-fj"/>
<app-autocomplete [Dom]="departmentName" (itemSelected)="onAutoComplete($event)">
<div [attr.key]='filter.key' class="sll-auto-component-item" *ngFor="let filter of filteredStates">
{{filter.value}}
</div>
</app-autocomplete>
注意:文本框上的变量名称一定要和app-autocomplete上面的DOM后面的值保持同一个,否则对应不上