skip to Main Content

I am trying to bind click event on video but it is not working. I need to fire event whenever user click on anywhere on the video or controls of video element. I have tried following:

component.html

         <video
          [src]="url"
          (loadeddata)="onVideoLoaded($event)"
          (click)="doSomething($event)"
        >
        </video>

component.ts

   onVideoLoaded(event) {
    const videoEl = event.target as HTMLVideoElement;
    videoEl.onclick = (event) => this.doSomething(event)
    videoEl.addEventListener('mousedown', this.doSomething);
  }

  doSomething(event){
    console.log(event)
 }

None of the above approach to bind video click event is working. How can I do it?

2

Answers


  1. I think you can approach it another way. Wrap the video in a div and handle the click event on it

    Login or Signup to reply.
  2. Generally you cannot bind a click into the area of the video object AND also including its controls.
    The controls are outside of the DOM (so your code cannot reach them, although they will still accept being given a <style> setting).

    Since the browser’s built-in HTML5 controls are not reachable by code…

    The best option would be to disable those controls and just use your own custom interface. Then the container Div (of custom controls) is clickable, and JS can report such clicks as you wish to know.

    Players like VideoJS and JWplayer etc all use custom controls. This problem doesn’t exist if you use some custom controls instead of the browser’s own controls (along with any given browser limitations).

    If still keeping the browser’s built-in HTML5 controls, then you have two options:

    Option (1): Capture any click attempt on the Video area.

    This will disable any/all clicks on the <video> element itself. If you needed that user-click to do something, then you will have to trigger it manually (eg: if they click at the x/y of the "play" button, then use JS to cause the required play/pause result, or even use JS to send a .click() command to that button where possible).

    In the HTML, setup a Div and Video object separately. Put the Div on a layer above the Video object by using z-index (which itself needs a position attribute to also exist, so for testing here I used absolute. Change the position as needed for your project’s display layout)

    <div id="click_hotspot" 
    style="position: absolute; z-index: 2;">
    </div>
    
    <video id="myvid" controls
    style="position: absolute" width="320" height="240">
    <source src="movie.mp4" type="video/mp4">
    </video>
    

    Then this JS code will give feedback (x/y pos) of the clicked area.

    var hspot = document.getElementById("click_hotspot");
    
    //# CSS "background-color" --> becomes --> JS ".backgroundColor"
    hspot.style.backgroundColor = "rgb(255, 0, 255)";
    hspot.style.opacity = "40%";
    
    //# make the hotpot Div have a same size as Video object
    hspot.style.width = ( myvid.width + "px" );
    hspot.style.height = ( myvid.height + "px" );
    
    //# handle clicks on hotspot (placed above Video object)
    hspot.onclick = (event) => { on_evt_vidclick(event); };
    
    function on_evt_vidclick( in_evt ) 
    { 
        console.log("clicked on Video area: " + "n" + 
        "x: " + in_evt.clientX + "n" +
        "y: " + in_evt.clientY 
        );
    }
    

    Option (2): Detect events related to clicking on a Video object

    Another approach is to simply detect events that would only come from clicking on video area. Events such as play, pause, seeking, and volumechange will be useful.

    The HTML is a simple Video tag with ID

    <video id="myvid" width="320" height="240" controls>
    <source src="movie.mp4" type="video/mp4">
    </video>
    

    Then this JS code lets you know if a Video event happened whilst the mouse is located over the Video object’s area. From there you can do_Something() as required…

    //# is true when mouse is over the Video object's Div
    var bool_mouse_pos = false;
    
    var myvid = document.getElementById("myvid");
    
    //# handle mouse versus hotspot Div
    myvid.onpointerover = (event) => { on_mouse_over_elem(event); };
    myvid.onpointerout = (event) => { on_mouse_out_elem(event); };
    
    //# handle clicks on video object or its "controls" buttons
    myvid.onclick = (event) => { on_evt_vidclick(event); };
    myvid.onplay = (event) => { on_evt_vidclick(event); };
    myvid.onpause = (event) => { on_evt_vidclick(event); };
    myvid.onseeking = (event) => { on_evt_vidclick(event); };
    myvid.onvolumechange = (event) => { on_evt_vidclick(event); };
    myvid.onfullscreenchange = (event) => { on_evt_vidclick(event); };
    
    function on_mouse_over_elem() { bool_mouse_pos = true; }
    
    function on_mouse_out_elem() { bool_mouse_pos = false; }
    
    
    function on_evt_vidclick( in_evt ) 
    { 
        if( in_evt.target == myvid )
        { 
            console.log(
            "event type : " + in_evt.type + "n" +
            "is on Video area? : " + bool_mouse_pos
            );
        }
        
        if( bool_mouse_pos == true )
        {
            //# Do Something ... 
            //# because a click has happened inside the Video area
        }
        
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search