Chrome扩展中HTML元素碰撞检测函数始终返回false的修复咨询
修复Chrome扩展中坐标与HTML元素碰撞检测函数返回false的问题
我正在开发一款能给网站添加emoji shmeji的Chrome扩展,写了一个检测X、Y坐标是否和HTML元素碰撞的函数,但它总是返回false,明明坐标确实和部分元素有碰撞。怎么修复?
原代码:
var emoji = document.createElement('span'); // ... var hold = false; var emojix = Math.round(window.innerWidth / 2); var emojiy = Math.round(window.innerHeight / 2); var emojively = 0; var emojivelx = 0; var emojis = ["😃","😄","😉","😊","☺","😎","😢","😱","😖", "🙂", "🙂", "🙂", "🙂", "🙂"]; var skip = false // ... function htmlcol(x, y) { var elements = document.querySelectorAll('body *'); // 获取body内所有元素 for (var i = 0; i < elements.length; i++) { var rect = elements[i].getBoundingClientRect(); // 获取元素边界 if ( x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom ) { return true break } else { return false} } } function update() { // ... if (chckycol(emojiy) || htmlcol(emojix, emojiy)) { emojively = 0; } else { if (!hold) { emojively += 0.07; } else { emojively = 0; } } // ... } // ... updates = setInterval(update,10);
问题分析与修复方案
你的碰撞检测函数有三个核心问题:
循环提前终止返回false
原函数里,只要第一个元素不匹配碰撞条件,就直接return false,根本不会检查后面的元素。必须遍历完所有元素都没碰撞时,才返回false。误检测自身元素
document.querySelectorAll('body *')会把你创建的emoji span也包含进去,导致坐标在emoji自身位置时被误判,需要排除这个元素。检测了不可见元素
页面里很多隐藏元素(比如display:none、visibility:hidden,或者宽高为0的元素)不需要参与碰撞检测,过滤掉这些元素能提升准确性和性能。
修复后的htmlcol函数
function htmlcol(x, y) { var elements = document.querySelectorAll('body *'); for (var i = 0; i < elements.length; i++) { // 跳过emoji元素自身 if (elements[i] === emoji) continue; var rect = elements[i].getBoundingClientRect(); var style = window.getComputedStyle(elements[i]); // 过滤不可见或无尺寸的元素 if (style.display === 'none' || style.visibility === 'hidden' || rect.width === 0 || rect.height === 0) { continue; } // 碰撞检测逻辑 if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) { return true; } } // 所有元素都检查完才返回false return false; }
内容的提问来源于stack exchange,提问作者user22155941
相关产品推荐
相关产品推荐

