【问题标题】:Angular 4 focus on item on arrow down and scrollAngular 4专注于向下箭头和滚动上的项目
【发布时间】:2017-12-22 10:06:37
【问题描述】:

我在 div *ngFor 循环中有项目,它在选定的消息上应用 css 类 'message-list-active'。

app.html

 <div  id="listText" *ngFor="let message of messages; let i=index" activeIndex = i" 
   [ngClass]="{'message-list-active': activeIndex === i  }">
      {{message.name}}
 </div>

component.ts //监听键盘事件,使用上下箭头选择消息

  messages;  // we have date stored here
  activeIndex = 0;


  @HostListener("document:keydown", ['$event']) 
   doSomething(event: KeyboardEvent): void {


  if (event.code == "ArrowUp" && this.activeIndex > 0) {
    this.activeIndex--

   }
  if (event.code == "ArrowDown" && this.activeIndex < this.messages.length-1) {
    this.activeIndex++

  }
 }

app.css

    #listText {
        width: auto;
        height:100%;
        overflow: auto
      }

     .message-list-active {
        margin: 0;
        padding: 15px 15px 5px 13px;
        border-radius: 0;
        background-color: #CDE6F7;
        border-style: dotted;
        border-width: 1px;
        border-bottom: 1px dotted;
         }

问题是当所选消息到达列表末尾时,它不会滚动。所以我想要实现的是让所选项目始终保持焦点并能够向下和向上滚动:

这里也有类似的例子:

这是我试图实现的目标,这是使用 jquery jsfiddle http://jsfiddle.net/38zR3/42/similar question/answer 回答的,但我如何使用 typescript 在 Angular 4 中实现这一目标

【问题讨论】:

    标签: javascript css angular typescript keyboard-events


    【解决方案1】:

    它看起来像这样:

    private scrollTo(_index: any) {
      let elmnt = document.getElementById(_index);
      elmnt.scrollIntoView();
       window.scrollTo(0, 0); // only if it's innerhtml
    }
    

    这将确保焦点所在的所有项目都在视野中。

    在html中需要做类似的事情:

    id={{item.uniqueID}} (focus)="scrollTo(item.uniqueID)" 确保它对所有使用此功能的东西都是唯一的。

    编辑

    在 html 中尝试:id="list{{i}}"

    if (event.code == "ArrowUp" && this.activeIndex > 0) {
        this.activeIndex--
        let str = `list${this.activeIndex}`;
        let elmnt = document.getElementById(str);
        elmnt.scrollIntoView();
        window.scrollTo(0, 0);
    }
    

    【讨论】:

    • 感谢您的建议,但我似乎无法专注于 div 元素
    • 向下或向上箭头应该会触发焦点嗯。
    • 是的,我尝试了唯一 id,它只是当我选择 div/message 时没有触发(焦点)事件 div ..
    • 进行了编辑。不是 100% 确定 html id 是否可以工作,但应该可以采用不同的格式。
    【解决方案2】:

    好的,所以通过制作自定义指令 [focused] 来修复它

    app.html

         <div id="listText">
            <div *ngFor="let message of messages; [focused]="i === activeIndex" let i=index" activeIndex = i" 
              [ngClass]="{'message-list-active': activeIndex === i  }">
           {{message.name}}
      </div>
    

    Focused.directive:

      import {Directive, Input, Renderer, ElementRef} from '@angular/core'
    
      @Directive({
       selector: '[focused]'
         })
    
     export class FocusedDirective {
    
          @Input()
          set focused(value: boolean){
             if(value){
               this.renderer.invokeElementMethod(this.elementRef.nativeElement, 'scrollIntoViewIfNeeded');
             }
        }
    
      constructor(private elementRef: ElementRef, private renderer: Renderer){}
       }
    

    【讨论】:

    • 渲染器在 Angular 4 中已被弃用,我相信。
    • @Jun711 我对水平做了同样的事情,现在当活动指针通过屏幕宽度时,它没有滚动页面。任何帮助将不胜感激。
    • AlexFF1 我无法保持焦点,请您分享更多代码
    • @AnshulRiyal 你的意思是你想在你点击 ENTER 时运行一个方法 onItemClick()?
    • @AnshulRiyal try (keyup.enter)="onItemClick(user_id, resource)" 或 (keydown.enter),是的,它可能没有指令,但我认为有一个指令很好,你可以重复使用它,你的代码会更干净
    猜你喜欢
    • 1970-01-01
    • 2012-04-13
    • 2012-01-16
    • 1970-01-01
    • 2022-08-16
    • 2013-07-17
    • 2022-08-12
    • 2021-03-01
    • 2019-10-08
    相关资源
    最近更新 更多