簡體   English   中英

如何在Angular10中點擊一定長度后隱藏和顯示文本?

[英]How to hide and reveal text on click after certain length in Angular10?

我有一個很長的文字。 我正在嘗試添加一個“顯示更多”和“顯示更少”按鈕,以使用 animation 在一定長度后顯示和隱藏文本。 我知道如何在點擊時顯示和隱藏特定文本。 但是,看起來不太好。 我也嘗試過使用 CSS: overflow屬性。 但是,它只是隱藏了文本。

我想在 15 個字符后隱藏 html 中的文本並顯示按鈕。 當我單擊按鈕時,它應該展開並顯示剩余的內容,並且按鈕內容應更改為“少顯示”

 function func(){ alert("hi"); }
 a { color: blue; text-decoration: underline; cursor: pointer; }
 <div class="more"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum laoreet, nunc eget laoreet sagittis, quam ligula sodales orci, congue imperdiet eros tortor ac lectus. Duis eget nisl orci. Aliquam mattis purus non mauris blandit id luctus felis convallis. Integer varius egestas vestibulum. Nullam a dolor arcu, ac tempor elit. Donec. </div> <a onClick="func()">Show more</a>

我想我可以提供部分解決方案。 這是一個Stackblitz

唯一的問題是,css 屬性overflowtext-overflow無法動畫,所以你不會有一個平滑的過渡......為此,你可以創建一個特定的 animation 或使用不同的 ZC7A628CBA22E28EB167B5F5C6AE2A 改變高度或方法使用不透明度和過渡延遲。 另外要檢查內容的長度,您需要更多的邏輯,我沒有包含在這個解決方案中,因為我認為沒有必要,因為您可以限制元素的寬度並因此剪切文本。

通過指令插入隱藏/顯示“面板”組件

在這種方法中,我們采用將指令附加到包含單個 textNode 作為直接后代的任意塊級元素的策略,目的是將此 textNode 包裝在一個組件中,該組件可以通過顯示/隱藏功能截斷其長度。

該解決方案將需要

  • 1 指令
  • 1 個組件

為什么采用這種方法

  • 我們不想關心每個必須實現此行為的組件中的隱藏/顯示邏輯 state,所以如果我們可以組件化並使其直接處理自己的 state 會更好
  • 我們希望能夠在所有用途中輕松更改顯示/隱藏功能的外觀/感覺。
  • 我們可以通過 Angular 動畫狀態在組件本身上應用所需的任何動畫。

組件

我們將首先創建我們的組件,因為我們的指令依賴它才能創建它。

controller

export class TruncateWrapperComponent implements OnInit {
  private _longText!: string
  private _shortText!: string;
  showLess = true;

  constructor(private change: ChangeDetectorRef) {
  }

  ngOnInit(): void {
  }

  setTruncateContent(truncateLength: number, textNode: Node) {
    this._longText = textNode.textContent ?? "";
    this._shortText = this._longText.slice(0, truncateLength);
    this.change.detectChanges();
  }

  get short() {
    return this._shortText
  }

  get long() {
    return this._longText;
  }
  
}

注意:我們必須導入 ChangeDetectorRef,因為我們將直接從 Angular ChangeDetection 循環之外的指令中設置 longText 和 shortText 私有屬性。

模板

<div>
  <ng-container *ngIf="showLess; else more">
    <div>
      {{short}}
    </div>
    <div>
      <button (click)="showLess = !showLess">Show more</button>
    </div>
  </ng-container>


  <ng-template #more>
      <div>
        {{long}}
      </div>
      <div>
        <button (click)="showLess = !showLess">Show Less</button>
      </div>
  </ng-template>
</div>

指令

現在我們有了一個組件,讓我們創建一個指令,我們可以在其他模板中使用它來插入組件。

@Directive({selector: '[truncate]'})
export class TruncateDirective implements AfterContentInit {
  @Input() truncate: number = 15;
  textNode!: Node;
  private readonly componentFactory: ComponentFactory<TruncateWrapperComponent>;

  constructor(private element: ElementRef<HTMLElement>,
              private render: Renderer2,
              private viewContainer: ViewContainerRef,
              factoryResolver: ComponentFactoryResolver) {
    // prime a component factory for creating the wrapper component.
    this.componentFactory = factoryResolver.resolveComponentFactory(TruncateWrapperComponent)
  }

  ngAfterContentInit() {
    if (this.shouldProcess()) {
      this.createWrapper();
    }
  }

  /**
   * shouldProcess checks the nativeElement which the directive is attached to for any direct descendent textNodes. The
   * first textNode encountered will be inserted into the TruncateWrapperComponent. Any original content other than
   * the first textNode encountered will be removed when the wrapper is created.
   *
   * If no direct textNode descendants are found no wrapper will be created and the original content will remain.
   */
  shouldProcess() {
    // check for textNodes, which is nodeType 3.
    const children = this.element.nativeElement.childNodes;
    for (let i = 0; i < children.length; i++) {
      if (children[i].nodeType == 3) {
        this.textNode = children[i];
        break;
      }
    }
    return Boolean(this.textNode);
  }

  createWrapper() {
    // clear current content
    this.render.setProperty(this.element.nativeElement, 'innerHTML', '');
    // attach new component to view.
    const wrapText = this.viewContainer.createComponent(this.componentFactory);
    wrapText.instance.setTruncateContent(this.truncate, this.textNode);
  }
}

StackBlitz

這是一個演示實現的 StackBlitz

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM