微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在Angular 8的primeng选项卡视图中为左右导航添加箭头?

如何解决如何在Angular 8的primeng选项卡视图中为左右导航添加箭头?

我希望添加左右导航箭头以支持导航中更大的标签大小。

我尝试使用 primeng,因为我的应用程序已经在 Angular 8 中安装了这个库。

除了 Angular Material 之外,是否还有其他库支持功能

enter image description here

在这里创建了我的示例。

https://stackblitz.com/edit/primeng-tabview-ngif-hluezs

角材料示例。

https://stackblitz.com/edit/angular-selecting-mattab-bihcd1

enter image description here

解决方法

您可以创建自己的指令来实现此目的...

在您的 styles.css 文件中包含以下 css

.nav-wrapper {
  position: relative;
  overflow: hidden;
  padding: 0;
}
.nav-wrapper > ul {
  display: flex;
}

.nav-wrapper--scrollable {
  padding: 0 32px;
}

.nav-arrow {
  position: absolute;
  display: none;
  top: 0;
  bottom: 0;
  z-index: 1;
  border: 1px solid #2399e5;
  background: #2399e5;
  font: 14px/1 FontAwesome;
  color: #fff;
  cursor: pointer;
}
.nav-wrapper--scrollable .nav-arrow {
  display: block;
}
.nav-arrow:hover {
  border: 1px solid #1f89ce;
  background: #1f89ce;
}

.nav-arrow:before {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
}

.nav-arrow--left {
  left: 0;
}
.nav-arrow--left:before {
  content: "\f053";
}

.nav-arrow--right {
  right: 0;
}
.nav-arrow--right:before {
  content: "\f054";
}
.nav-arrow--disabled,.nav-arrow--disabled:hover {
  background: #ccc;
  border: #ddd;
  cursor: default;
}

创建指令

import {
  ContentChildren,Directive,ElementRef,Input,NgZone,QueryList
} from "@angular/core";
import { TabPanel } from "primeng/tabview";
import { fromEvent,interval,Subject } from "rxjs";
import { delay,mergeMap,take,takeUntil } from "rxjs/operators";

@Directive({
  selector: "[appTabScroller]"
})
export class TabScrollerDirective {
  @Input() arrowWidth = 30;
  @Input() shiftWidth = 25;

  @ContentChildren(TabPanel) tabPanels: QueryList<TabPanel>;

  private _container: HTMLElement;
  private _nav: HTMLElement;

  private _shift = 0;
  private _scrollable: boolean;

  private _leftArrow: HTMLElement;
  private _rightArrow: HTMLElement;

  private readonly _destroyed$ = new Subject<void>();

  constructor(private elRef: ElementRef,private zone: NgZone) {}

  get rightBorder() {
    return -(this._nav.scrollWidth - this._nav.offsetWidth);
  }

  ngAfterContentInit() {
    this.tabPanels.changes.pipe(takeUntil(this._destroyed$)).subscribe(() => {
      this.zone.onStable
        .asObservable()
        .pipe(take(1))
        .subscribe(() => this._refreshScroller());
    });
  }

  ngAfterViewInit() {
    this.zone.runOutsideAngular(() => this.init());
  }

  init() {
    this._nav = this.elRef.nativeElement.querySelector("[role=tablist]");
    this._container = wrap(this._nav,"nav-wrapper");

    this._initEvents();

    this._leftArrow = this._createArrow("left");
    this._rightArrow = this._createArrow("right");

    this._refreshScroller();
  }

  scroll(shift: number) {
    this._shift += shift;

    const rightBorder = this.rightBorder;
    if (this._shift < rightBorder) {
      this._shift = rightBorder;
    }
    if (this._shift >= 0) {
      this._shift = 0;
    }

    this._leftArrow.classList.toggle("nav-arrow--disabled",this._shift >= 0);
    this._rightArrow.classList.toggle(
      "nav-arrow--disabled",this._shift <= rightBorder
    );

    this._nav.style.transform = `translateX(${this._shift}px)`;
  }

  ngOnDestroy() {
    this._destroyed$.next();
    this._destroyed$.complete();
  }

  private _initEvents() {
    fromEvent(this._container,"mousewheel")
      .pipe(takeUntil(this._destroyed$))
      .subscribe((e: any) => this._onMouseWheel(e));
    // Firefox
    fromEvent(this._container,"DOMMouseScroll")
      .pipe(takeUntil(this._destroyed$))
      .subscribe((e: any) => this._onMouseWheel(e));
    fromEvent(window,"resize")
      .pipe(takeUntil(this._destroyed$))
      .subscribe(() => {
        this._refreshScroller();
      });
  }

  private _onMouseWheel(e: any) {
    const delta = Math.max(-1,Math.min(1,e.wheelDelta || -e.detail));
    this.scroll(delta * 25);
  }

  private _createArrow(direction: string) {
    const arrow = el(`nav-arrow nav-arrow--${direction}`);
    this._container.insertBefore(arrow,this._nav);
    arrow.style.width = this.arrowWidth + "px";
    fromEvent(arrow,"click")
      .pipe(takeUntil(this._destroyed$))
      .subscribe(() => {
        this.scroll(direction === "left" ? this.shiftWidth : -this.shiftWidth);
      });

    const upStream$ = fromEvent(arrow,"mouseup");
    // handle long press
    fromEvent(arrow,"mousedown")
      .pipe(
        takeUntil(this._destroyed$),mergeMap(event =>
          interval(100).pipe(
            delay(100),takeUntil(upStream$)
          )
        )
      )
      .subscribe(() => {
        this.scroll(direction === "left" ? this.shiftWidth : -this.shiftWidth);
      });

    return arrow;
  }

  private _refreshScroller() {
    const compareWith = this._scrollable ? -this.arrowWidth * 2 : 0;
    this._container.classList.toggle(
      "nav-wrapper--scrollable",this.rightBorder < compareWith
    );
    this._scrollable = this.rightBorder < compareWith;
    this.scroll(0);
  }
}

function wrap(elem,wrapperClass: string) {
  const wrapper = el("nav-wrapper");
  elem.parentNode.insertBefore(wrapper,elem);
  wrapper.appendChild(elem);
  return wrapper;
}

function el(className: string): HTMLElement {
  const div = document.createElement("div");
  div.className = className;
  return div;
}

现在一切都设置好了,在你的 html 中

<p-tabView appTabScroller>
  <p-tabPanel [header]="item.content" *ngFor="let item of items; let i = index" [selected]="i == 0">
  </p-tabPanel>
</p-tabView>

See Demo

来源:https://embed.plnkr.co/BX6UTrG7XTBXS2TNChAs/

,

我分叉了您的示例,并在顶部添加了一些示例按钮,可以转到上一个/下一个选项卡。当然,您可以通过几种不同的方式来做到这一点。

https://stackblitz.com/edit/primeng-tabview-ngif-2e96sb?file=src/app/app.component.html

让我知道 CSS 是否是更多问题,因为这主要是为了展示功能。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。