最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to translate "get element by id" into typescript - Stack Overflow

programmeradmin8浏览0评论

My Project runs on Angular 8 with typescript.

Im trying to get an html audio element by id and store it in a variable. Then i want to get the duration out of the Element and store it in another variable.

As seen in a working example, in Javascript, this would go as:

HTML

<audio id="music" preload="true">
  <source src="./assets/img/hollywood.mp3">

JS

var music = document.getElementById('music'); 
var duration = music.duration;

now my translation to typescript is this:

TS

public music = <HTMLAudioElement>document.getElementById("music");
public duration = this.music.duration;

But when i load the page, i get the error "Uncaught (in promise): TypeError: this.music is null" and i dont get why.

My Project runs on Angular 8 with typescript.

Im trying to get an html audio element by id and store it in a variable. Then i want to get the duration out of the Element and store it in another variable.

As seen in a working example, in Javascript, this would go as:

HTML

<audio id="music" preload="true">
  <source src="./assets/img/hollywood.mp3">

JS

var music = document.getElementById('music'); 
var duration = music.duration;

now my translation to typescript is this:

TS

public music = <HTMLAudioElement>document.getElementById("music");
public duration = this.music.duration;

But when i load the page, i get the error "Uncaught (in promise): TypeError: this.music is null" and i dont get why.

Share Improve this question asked Apr 29, 2020 at 12:04 DuB loxxDuB loxx 2352 gold badges6 silver badges14 bronze badges 5
  • And if you remove this from this.music.duration ? I am not familiar with TS. – Fasani Commented Apr 29, 2020 at 12:08
  • 1 It's not a typescript error. preload=true tells the browser to fetch the audio first. But it's not done loading by the time you execute the script – MonteCristo Commented Apr 29, 2020 at 12:09
  • 1 @Fasani, if i remove this, the variable music is not recognized – DuB loxx Commented Apr 29, 2020 at 12:11
  • @MonteCristo if i remove that, the same error is printed – DuB loxx Commented Apr 29, 2020 at 12:12
  • Access DOM-elements in ngAfterViewInit() instead – Salmin Skenderovic Commented Apr 29, 2020 at 12:12
Add a ment  | 

2 Answers 2

Reset to default 1

You could use ViewChild and ElementRef using a template reference variable to keep things the Angular way. Try the following

Template

<audio #stream autoplay (play)="onPlay()">
  <source src="https://upload.wikimedia/wikipedia/mons/c/c8/Example.ogg">
</audio>

Controller

import { Component, ViewChild, ElementRef } from '@angular/core';

@Component({
  selector: 'my-app'
})
export class AppComponent {

  audioPlayer: HTMLAudioElement;

  @ViewChild('stream') set playerRef(ref: ElementRef<HTMLAudioElement>) {
    this.audioPlayer = ref.nativeElement;
  }

  onPlay() {
    console.log(this.audioPlayer.duration);
  }
}

It binds the nativeElement of the element reference to the audioPlayer variable using set.

ngAfterViewInit() cannot guarantee accessing the duration would return the correct value since the audio may not have started playing. In that case, it would return null. So I bound it to the play event to get the duration.

Working example: Stackblitz

Add #nameForYourRef

<audio #myAudio preload="true">
  <source src="./assets/img/hollywood.mp3">
</audio>

Then access your element on viewInit

@ViewChild('myAudio') myAudioRef: ElementRef;

  ngAfterViewInit() {
    // Console log some methods to see that it is working
    console.log(
      this.myAudioRef.nativeElement.play,
      this.myAudioRef.nativeElement.pause,
    )
  }

Demo: https://stackblitz./edit/angular-a8jahz

发布评论

评论列表(0)

  1. 暂无评论