Chrome广告加载后,Javascript键绑定“中断”或“丢失页面焦点”

时间:2016-10-30 23:18:00

标签: javascript google-chrome adsense

我在网页上有箭头键的键事件绑定。这些绑定在页面加载时完美运行,但在页面上的Google AdSense广告加载时突然停止工作。这不会发生在每个页面/广告加载上,而是大约一半。

当发生这种情况时,如果我在页面加载期间反复按箭头键,绑定事件将成功激活,直到广告出现,此时事件停止工作,并且键的默认操作(滚动页面)开始发生因为我一直按下键。这很奇怪,因为我通过以下方法禁用了这些键的默认操作:

window.onkeydown = function(e) {
    // Spacebar, all four arrow keys
    if (e.keyCode == 32 || e.keyCode == 37 || e.keyCode == 38 || e.keyCode == 39 ||
        e.keyCode == 40) {
        e.preventDefault();
        return false;
    }
};

如果我随后点击页面主体上的任何位置,则键绑定将重新开始工作。

我猜测也许当广告完成加载时(在页面的其余部分之后),它会导致某种类型的中断“从页面中窃取焦点”(但显然不是窗口,因为滚动仍然发生?)。

实际的键绑定是使用Mousetrap完成的,虽然这似乎与问题没有任何关系,我只在Google Chrome中遇到过这个问题。我在Firefox中没有这种行为。如果我在Chrome上启用AdBlock,则问题不会发生,进一步显示触发此“中断”的广告。

有什么显而易见的,我不知道这可以完全打断这种方式的键绑定,同时仍然允许键滚动页面,直到用户再次点击身体?有没有办法阻止广告以这种方式破坏用户与页面的交互性?

1 个答案:

答案 0 :(得分:0)

有一项建议是捕获AdSense ADS_LOADED事件,但只有在视频中使用Google IMA SDK时才会显示此事件。

我提出的解决方案是监听所有模糊事件,当广告从文档正文中窃取焦点时,将焦点返回到窗口。这只有在window.focus()被包装在超时时才有效,这是我目前无法理解的。

isDescendant()函数取自this answer

function isDescendant(child, parent) {
    /*
    Test if child is contained within parent regardless of how many levels deep
    */
     var node = child.parentNode;
     while (node != null) {
         if (node == parent) {
             return true;
         }
         node = node.parentNode;
     }
     return false;
}

window.addEventListener('blur', function() {
    var ads = document.getElementsByClassName('ad');
    var n = ads.length;
    for (i=0; i<n; i++) {
        if (isDescendant(document.activeElement, ads[i])) {
            // This only works if wrapped in a timeout (why?)
            window.setTimeout(function () {
                window.focus();
            }, 0);
            break;
        }
    }
});