NgbTypeahead component doesn't scroll inside a scrollable component

后端 未结 4 1304
温柔的废话
温柔的废话 2021-01-25 03:11

I am using NgbTypeahead component of ng-bootstrap. My problem is, when I put the typeahead component inside a scrollable component and make a scroll down, the position of dropdo

4条回答
  •  春和景丽
    2021-01-25 04:07

    typeahead-scrollable.html file

    typeahead-scrollable.ts file

        @ViewChild('typeaheadInstance')
        private typeaheadInstance: NgbTypeahead;
    
        typeaheadKeydown($event: KeyboardEvent) {
          if (this.typeaheadInstance.isPopupOpen()) {
            setTimeout(() => {
              const popup = document.getElementById(this.typeaheadInstance.popupId);
              const activeElements = popup.getElementsByClassName('active');
              if (activeElements.length === 1) {
                // activeElements[0].scrollIntoView();
                const elem = (activeElements[0] as any);
                if (typeof elem.scrollIntoViewIfNeeded === 'function') {
                  // non standard function, but works (in chrome)...
                  elem.scrollIntoViewIfNeeded();
                } else {
                  //do custom scroll calculation or use jQuery Plugin or ...
                  this.scrollIntoViewIfNeededPolyfill(elem as HTMLElement);
                }
              }
            });
          }
        }
    
        private scrollIntoViewIfNeededPolyfill(elem: HTMLElement, centerIfNeeded = true) {
          var parent = elem.parentElement,
            parentComputedStyle = window.getComputedStyle(parent, null),
            parentBorderTopWidth = parseInt(parentComputedStyle.getPropertyValue('border-top-width')),
            parentBorderLeftWidth = parseInt(parentComputedStyle.getPropertyValue('border-left-width')),
            overTop = elem.offsetTop - parent.offsetTop < parent.scrollTop,
            overBottom = (elem.offsetTop - parent.offsetTop + elem.clientHeight - parentBorderTopWidth) > (parent.scrollTop + parent.clientHeight),
            overLeft = elem.offsetLeft - parent.offsetLeft < parent.scrollLeft,
            overRight = (elem.offsetLeft - parent.offsetLeft + elem.clientWidth - parentBorderLeftWidth) > (parent.scrollLeft + parent.clientWidth),
            alignWithTop = overTop && !overBottom;
    
          if ((overTop || overBottom) && centerIfNeeded) {
            parent.scrollTop = elem.offsetTop - parent.offsetTop - parent.clientHeight / 2 - parentBorderTopWidth + elem.clientHeight / 2;
          }
    
          if ((overLeft || overRight) && centerIfNeeded) {
            parent.scrollLeft = elem.offsetLeft - parent.offsetLeft - parent.clientWidth / 2 - parentBorderLeftWidth + elem.clientWidth / 2;
          }
    
          if ((overTop || overBottom || overLeft || overRight) && !centerIfNeeded) {
            elem.scrollIntoView(alignWithTop);
          }
        }
    

    Working example:

    https://stackblitz.com/edit/angular-utd9ii?file=app%2Ftypeahead-scrollable.ts

自定义标题
段落格式
字体
字号
代码语言
提交回复
热议问题