jQuery - 点击时 * 选择器触发次数太多



我想记录用户每次单击元素的完整 css 路径,我按照这个答案创建一个函数来获取点击元素的 css 路径

$('body').on('click',"*",function(){
var rightArrowParents = [];
$(this).parents().addBack().not('html').each(function(e) {
var entry = this.tagName.toLowerCase();
if($(this).attr('id')){
entry += "#" + $(this).attr('id');
}
if (this.className) {
entry += "." + this.className.replace(/ /g, '.');
}
rightArrowParents.push(entry);
});
console.log(rightArrowParents.join(" > "));
})

但我注意到当我单击一个被多个元素包装的元素时,这个函数被调用了很多次,

例如,当我点击 h1 时:

body > div.sample1.sample2 > div.sample3.sample4 > h1.test1.test2.test3
body > div.sample1.sample2 > div.sample3.sample4
body > div.sample1.sample2

当我在console.log之后添加return false时,它只会输出h1的完整css路径,这是预期的结果,但是如果我这样做,某些元素将无法正常工作,例如<a>不会重定向到另一个网站

以下是我尝试过的:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<title>Document</title>
</head>
<body>
<div class="sample1 sample2">
<div class="sample3 sample4">
<h1 class="test1 test2 test3">some example text</h1>
</div>
</div>
<div>
<h1 class="test1 test2 test3">some sample text</h1>
</div>
<div class="sample1 sample2">
<div class="sample3 sample4">
<a class="test1 test2 test3" href="https://www.google.com/">henlo</a>
</div>
</div>
<script>
jQuery(function($){
$('body').on('click',"*",function(){
var rightArrowParents = [];
$(this).parents().addBack().not('html').each(function(e) {
var entry = this.tagName.toLowerCase();
if($(this).attr('id')){
entry += "#" + $(this).attr('id');
}
if (this.className) {
entry += "." + this.className.replace(/ /g, '.');
}
rightArrowParents.push(entry);
});
console.log(rightArrowParents.join(" > "));
//can't do this, since it will make some element malfunction
//return false
})
})
</script>
</body>
</html>

我应该怎么做才能使jQuery正常工作?

如果我清楚地理解你的问题,你需要做的就是在你的函数function(e)添加一个事件参数,然后在最后使用e.stopPropagation()来防止它通过父元素的事件处理程序。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<title>Document</title>
</head>
<body>
<div class="sample1 sample2">
<div class="sample3 sample4">
<h1 class="test1 test2 test3">some example text</h1>
</div>
</div>
<div>
<h1 class="test1 test2 test3">some sample text</h1>
</div>
<div class="sample1 sample2">
<div class="sample3 sample4">
<a class="test1 test2 test3" href="https://www.google.com/">henlo</a>
</div>
</div>
<script>
jQuery(function($) {
$('body').on('click', "*", function(e) {
var rightArrowParents = [];
$(this).parents().addBack().not('html').each(function() {
var entry = this.tagName.toLowerCase();
if ($(this).attr('id')) {
entry += "#" + $(this).attr('id');
}
if (this.className) {
entry += "." + this.className.replace(/ /g, '.');
}
rightArrowParents.push(entry);
});
console.log(rightArrowParents.join(" > "));

e.stopPropagation();
})
})
</script>
</body>
</html>

这个解决方案可能看起来有点笨拙,但它可以完成工作。 沿着这些思路,可能还有一个更优雅的解决方案(比如比较取消事件的某些属性。

jQuery(function($){
$('body').on('click',"*",function(e) {
// mark the event as seen and cancel it it was seen
if (e.seen) return;
e.seen = true;

var rightArrowParents = [];
$(this).parents().addBack().not('html').each(function(i, o) {
var entry = this.tagName.toLowerCase();
if($(this).attr('id')){
entry += "#" + $(this).attr('id');
}
if (this.className) {
entry += "." + this.className.replace(/ /g, '.');
}
rightArrowParents.push(entry);
});
console.log(rightArrowParents.join(" > "));
})
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<title>Document</title>
</head>
<body>
<div class="sample1 sample2">
<div class="sample3 sample4">
<h1 class="test1 test2 test3">some example text</h1>
</div>
</div>
<div>
<h1 class="test1 test2 test3">some sample text</h1>
</div>
<div class="sample1 sample2">
<div class="sample3 sample4">
<a class="test1 test2 test3" href="https://www.google.com/">henlo</a>
</div>
</div>
</body>
</html>

最新更新