无法捕获 Netflix 搜索栏上的点击事件

Not able to capture click event on Netflix seek bar

我有一个 chrome 扩展,它依赖于检测 Netflix 搜索栏上的点击事件。一旦用户将鼠标悬停在视频播放器上,div ([data-uia=timeline-bar]) 就会动态添加到 dom,所以我尝试使用事件冒泡来监听事件。

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

它没有成功,所以我尝试在捕获阶段添加侦听器。正在检测所有点击事件,但搜索栏点击。

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

有没有办法监听 ([data-uia=timeline-bar]) 上的点击事件?

向 [data-uia=timeline-bar] 元素的父元素添加一个 MutationObserver 以观察其子元素何时发生变化,例如添加了时间轴栏?并在添加时间线栏元素后在回调中附加一个侦听器?

// The timeline-bar's parent's data-uia is "timeline" in the Netflix player DOM.

let parent = document.querySelector("[data-uia=timeline]"),
    options = {
      childList: true
    },
    observer = new MutationObserver(mCallback);

observer.observe(parent, options);

function mCallback (mutations) {
  for (let mutation of mutations) {
    if (mutation.type === 'childList') { 
      for(let node of mutation.addedNodes){
        if(node.getAttribute("data-uia") === "timeline-bar"){
           node.addEventListener('click', () => {
             alert("clicked");
            // Do click stuff...
           });
        }
      }
    }
  }
}

// To test the observer
btnAttr.addEventListener('click', function () {
  let el = document.createElement("div");
  el.setAttribute("data-uia", "timeline-bar");
  el.innerText = "A TIMELINE-BAR";
  parent.appendChild(el);
}, false);

代码笔在这里:https://codepen.io/freedruk/pen/powaKBy

的确,您的目标需要努力实现,因为 dom 元素是永久创建和删除的。我能提出的唯一方法当然可以被认为是肮脏的,但你至少可以尝试一下;)

$("[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");
            }
        });
    };
});

技巧是观察timeline-knob对象,分析上一个sibling的情况div,因为当鼠标悬停在timeline上时会发生一些重绘。

这只是一个变通方法,希望对您有所帮助:)祝您有愉快的一天!

[编辑 1]

更优雅的方式:

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);
    });
});

我不得不面对几个困难:

  1. 甚至重新生成了“timeline”节点,所以我们在每次修改“player”时将“click”事件附加到它
  2. 基本上,我们经常需要点击空白的 divs(例如恰好在时间轴上),然后不会触发“点击”事件,因此我们对其应用几乎不可见的布局以强制浏览器将其视为可点击节点。
  3. 而且并非最不重要的一个:Netflix 使用“指针事件”css 属性 来阻止某些“点击”事件,因此我们必须将其修复回“自动”

我多次测试此代码,似乎 工作正常 ;)