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

javascript - How can I get a play or click event to a video element using Angular 7? - Stack Overflow

programmeradmin1浏览0评论

I inherited a project that needs some minor analytics, more specifically, video plays analytics.

It's an Angular project that gets a html body from a SQL server.

It parses a string and injects in a page. So I can't add extra html to solve this issue, I can only add some Angular code.

Current analytics is Matomo, I'm using ngx-matomo to monitor views and visits.

AFAIK when a video is played I need to send the notification to the server, but the thing is, how do I get the event when a video is played?

My jQuery habits would say that monitoring events and waiting for a video element would suffice, but here's the gist, I can't get click events on video elements.

I wrote this small piece of code that mimics what I'm trying to do?

//our root app ponent
import {Component, NgModule, VERSION, ViewChild} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'

@Component({
  selector: 'my-app',
  template: `
    <div (click)="anyClick($event)" style="padding: 10px">
      <div> not the video </div>
      <video width="320" height="240" controls>
        <source src=".ogg" type="video/ogg">
      Your browser does not support the video tag.
      </video>
    </div>
  `,
})

export class App {  

  anyClick(event: String) {
    console.log(event);
  }  
}

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App],
  bootstrap: [ App ]
})
export class AppModule {
}

There's a plnkr here

If you click anywhere on the page, you'll get the event on the console, but the same is not true if you click the video, which is the event I need.

I can attach a listener to a play event using a tag like this

 ngOnInit(){
    let video = document.querySelector('video');
    video.onplay = (event) => {
      console.log('The Boolean paused property is now false. Either the ' + 
      'play() method was called or the autoplay attribute was toggled.');
    };
  }

If worked on Plunker, but it feels wrong...

Specifying the issue with more details:

The HTML file is actually just a

<div [innerHTML]="innerHTML"></div>

The ponent TS is

import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { Observable } from 'rxjs';
import { Product } from 'src/app/entities/product';
import { Version } from 'src/app/entities/version';
import { ProductService } from '../product.service';

@Component({
  selector: 'app-content',
  templateUrl: './contentponent.html',
  encapsulation: ViewEncapsulation.None,
  styleUrls: ['./contentponent.scss']
})
export class ContentComponent implements OnInit {

  @Input() product: Product;
  @Output() load = new EventEmitter<{ title: string, href: string }>();
  conteudo$: Observable<Version>;
  innerHTML: SafeHtml;

  constructor(
    private productService: ProductService,
    private sanitizer: DomSanitizer
  ) { }

  ngOnInit() {    
    var pathToLoad;

    this.productService.getVersion(pathToLoad).subscribe(version => {
      this.innerHTML = this.sanitizer.bypassSecurityTrustHtml(version.conteudo);

      const el = document.createElement('html');
      el.innerHTML = version.conteudo;
      const sections = el.getElementsByTagName('section');
      for (let i = 0; i < sections.length; i++) {
        const section = sections.item(i);
        if (section.hasAttribute('id')) {

          this.load.emit({
            title: section.getElementsByTagName('h2').item(0).textContent,
            href: section.getAttribute('id')
          });
        }
      }
    });
  }

}

I inherited a project that needs some minor analytics, more specifically, video plays analytics.

It's an Angular project that gets a html body from a SQL server.

It parses a string and injects in a page. So I can't add extra html to solve this issue, I can only add some Angular code.

Current analytics is Matomo, I'm using ngx-matomo to monitor views and visits.

AFAIK when a video is played I need to send the notification to the server, but the thing is, how do I get the event when a video is played?

My jQuery habits would say that monitoring events and waiting for a video element would suffice, but here's the gist, I can't get click events on video elements.

I wrote this small piece of code that mimics what I'm trying to do?

//our root app ponent
import {Component, NgModule, VERSION, ViewChild} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'

@Component({
  selector: 'my-app',
  template: `
    <div (click)="anyClick($event)" style="padding: 10px">
      <div> not the video </div>
      <video width="320" height="240" controls>
        <source src="http://download.blender/peach/trailer/trailer_400p.ogg" type="video/ogg">
      Your browser does not support the video tag.
      </video>
    </div>
  `,
})

export class App {  

  anyClick(event: String) {
    console.log(event);
  }  
}

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App],
  bootstrap: [ App ]
})
export class AppModule {
}

There's a plnkr here http://plnkr.co/edit/ALk16AiaHtgqYYrw

If you click anywhere on the page, you'll get the event on the console, but the same is not true if you click the video, which is the event I need.

I can attach a listener to a play event using a tag like this

 ngOnInit(){
    let video = document.querySelector('video');
    video.onplay = (event) => {
      console.log('The Boolean paused property is now false. Either the ' + 
      'play() method was called or the autoplay attribute was toggled.');
    };
  }

If worked on Plunker, but it feels wrong...

Specifying the issue with more details:

The HTML file is actually just a

<div [innerHTML]="innerHTML"></div>

The ponent TS is

import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { Observable } from 'rxjs';
import { Product } from 'src/app/entities/product';
import { Version } from 'src/app/entities/version';
import { ProductService } from '../product.service';

@Component({
  selector: 'app-content',
  templateUrl: './content.ponent.html',
  encapsulation: ViewEncapsulation.None,
  styleUrls: ['./content.ponent.scss']
})
export class ContentComponent implements OnInit {

  @Input() product: Product;
  @Output() load = new EventEmitter<{ title: string, href: string }>();
  conteudo$: Observable<Version>;
  innerHTML: SafeHtml;

  constructor(
    private productService: ProductService,
    private sanitizer: DomSanitizer
  ) { }

  ngOnInit() {    
    var pathToLoad;

    this.productService.getVersion(pathToLoad).subscribe(version => {
      this.innerHTML = this.sanitizer.bypassSecurityTrustHtml(version.conteudo);

      const el = document.createElement('html');
      el.innerHTML = version.conteudo;
      const sections = el.getElementsByTagName('section');
      for (let i = 0; i < sections.length; i++) {
        const section = sections.item(i);
        if (section.hasAttribute('id')) {

          this.load.emit({
            title: section.getElementsByTagName('h2').item(0).textContent,
            href: section.getAttribute('id')
          });
        }
      }
    });
  }

}
Share Improve this question edited Mar 20, 2020 at 17:11 Johnny Bigoode asked Mar 19, 2020 at 17:21 Johnny BigoodeJohnny Bigoode 5912 gold badges12 silver badges31 bronze badges 4
  • 1 If you get a reference to the video element, you should theoretically be able to listen to the "onplay" and "onpause" events emitted from the video element. I'll try to provide some code examples soon. :) – saglamcem Commented Mar 19, 2020 at 17:50
  • 2 w3/2010/05/video/mediaevents.html – M A Salman Commented Mar 19, 2020 at 18:04
  • 1 html.spec.whatwg/multipage/media.html#mediaevents – M A Salman Commented Mar 19, 2020 at 18:06
  • 1 You posted the javascript solution. If you want to try to find an angular solution, then post the HTML that the server sends to the app. – rickz Commented Mar 20, 2020 at 14:40
Add a ment  | 

2 Answers 2

Reset to default 7

See https://developer.mozilla/en-US/docs/Web/API/HTMLMediaElement/play_event
the play event doesn't bubble. In your plunker, add event binding to your video tag

<video (play)="anyClick($event)"  

You can use onplay="script or function call"

 <video width="320" onplay="console.log('hello im playing')" height="240" controls>
   <source src="http://download.blender/peach/trailer/trailer_400p.ogg" type="video/ogg">
      Your browser does not support the video tag.
      </video>

If you are receiving html from the server and it is stored in a string variable like

 let htmlString=`<video width="320" height="240" controls>
  <source src="http://download.blender/peach/trailer/trailer_400p.ogg" 
  type="video/ogg">
  Your browser does not support the video tag.
  </video>`;

You can do add the onplay inside the string like this

htmlString.replace(/(video)/,"$1 onplay='onPlay($event)'");

HTML:

<div [innerHTML]="htmlString"></div>

and then

onPlay($event:any){
  console.log($event.target.id);
  console.log($event.target.width);
}

Run this code below in js

let htmlString=`<video width="320" id="vid20" height="240" controls>
<source src="http://download.blender/peach/trailer/trailer_400p.ogg" type="video/ogg">
Your browser does not support the video tag.
</video>`;
document.querySelector("#main").innerHTML=htmlString.replace(/(video)/,"$1 onplay='onPlay(event)'");;

function onPlay(event){
      console.clear();
      console.log(event.target.id);
}
<div id="main"></div>

发布评论

评论列表(0)

  1. 暂无评论