Search code examples
javascriptgoogle-chrome-extensiononclicklistenerreverse-engineeringnetflix

Not able to capture click event on Netflix seek bar


I have a chrome extension that relies on detecting click event on seek bar of Netflix. The div ([data-uia=timeline-bar]) is added dynamically to dom once user hovers over the video player, so I tried to use event bubbling to listen to the event.

    //after injecting jquery on page 
    $('body').on('click','[data-uia=timeline-bar]',function(e){
        console.log('click detected');
    })

It didn't work out so I tried to add listener at capture phase. All click events are being detected but the seek bar click.

document.addEventListener('click',
(e) => {console.log('click detected during capture phase')}
,true);

Is there a way to listen to the click event on ([data-uia=timeline-bar])?

Netflix screenshot


Solution

  • Indeed, your goal needs hard work, as dom elements are created and deleted permanently. The only approach I can propose can certainly be considered as dirty, but you can try it at least ;)

    $("[data-uia='player']").on("DOMSubtreeModified", function(){
        const ref = "div[data-uia='timeline-knob']";
    
        if($(ref)){
            $(ref).off("mouseover").on("mouseover", function(event){
                const that = $(this);
                const previousSibling = event.target.previousSibling;
    
                if(previousSibling.style.left){
                    console.log("Click presumed");
                }
                else {
                    console.log("released");
                }
            });
        };
    });
    

    The trick is to observe the timeline-knob object, and analyse the situation upon the previous sibling div, because some repaints occur when the mouse is over the timeline.

    It's just a workaround, I hope this can help you :) Have a nice day !

    [EDIT 1]

    A more elegant way :

    const ref = "div[data-uia='timeline'].active";
    const onclick = (e) => {
        console.log("clicked on", e);
    };
    const prepare = (obj, e) => {
        $(e.target).css("pointer-events","auto").css("border", "0.1px solid rgba(255,255,255,0)");
        $(obj).off("click.test").on("click.test", (clickevent) => {onclick(clickevent.target);});
    };
    
    $("[data-uia='player']").on("DOMSubtreeModified", function(modevent){
        $(ref).each(() => {
            prepare(ref,modevent);
        });
    });
    

    I had to face several difficulties :

    1. even the "timeline" node is regenerated, so we to attach the "click" event to it at each "player" modification
    2. basically, we often have to click on empty divs (for example exactly on the timeline), and then no "click" event is fired, so we apply an almost invisible layout to it to force the browser consider it as a clickable node.
    3. and not the least one : Netflix uses the "pointer-events" css property to some block "click" events, so we have to fix it back to "auto"

    I tested this code several times and it seems working fine ;)