我在网页上有箭头键的键事件绑定。这些绑定在页面加载时完美运行,但在页面上的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,则问题不会发生,进一步显示触发此“中断”的广告。
有什么显而易见的,我不知道这可以完全打断这种方式的键绑定,同时仍然允许键滚动页面,直到用户再次点击身体?有没有办法阻止广告以这种方式破坏用户与页面的交互性?
答案 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;
}
}
});