gpt4 book ai didi

javascript - 阻止 div 的 childNodes 响应 div 的事件监听器

转载 作者:行者123 更新时间:2023-11-28 03:38:51 25 4
gpt4 key购买 nike

我正在使用 d3 显示数据集中的数据。显示屏显示了层次结构的三个元素:

  • 顶层:“组织维持事件”
  • 中级:“极限运动”
  • 底层:“跳伞管理”

当点击代表中层的 DOM 时,会出现底层。当第二次点击中间层时,底层消失。这一切都很好。

问题是我的用户总是想点击底部级别,这样做会使底部级别消失。我想做到这样,只有当单击中间层时,底层才会消失。

我尝试过的:

我尝试将事件监听器放在中层文本元素而不是 div 上。这导致错误d.key is not a function

我还尝试在 on.click 之前使用 div.parentNodedivs2.parentNode 但收到消息 divs2.parentNode is未定义。

这是我的代码

var doc = URL.createObjectURL(new Blob([`TooltipInfo	Category	Function1	Function2
Records relating to the skydiving. Includes halters, parachutes, and altimeters.<ul><li>For records relating to rock climbing, see <b>rock climbing</b>.</li><li>For travel expenses, see <b>Procurements & Purchasing</b>.</li></ul>Retention:<ul><li>Keep records for seven years from the date of record creation, then send to <mark>archives.</mark></li><li>Keep all other records for seven years from the date of record creation, then destroy.</li></ul> • Skydiving Management Extreme Sports > Organization-sustaining Activities`]))


d3.tsv(doc)
.row(function(d) {
return {
University: d.University,
TooltipInfo: d.TooltipInfo,
Searchterms: d.Searchterms,
Category: d.Category,
Function1: d.Function1,
Function2: d.Function2,
MaxRetentionRounded: d.MaxRetentionRounded,
ModifiedRetention: d.ModifiedRetention
};
})
.get(function(error, data) {

var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0)

var height = 150,
width = 300;


var nest = d3.nest()
.key(function(d) {
return d.Function2;
})
.key(function(d) {
return d.Function1;
})
.key(function(d) {
return d.Category;
})
.entries(data);


var height = 80,
width = 150;


var divs = d3.select(".container")
.selectAll(null)
.data(nest)
.enter()
.append("div")
.attr("class", "innerdiv");

divs.append("p")
.html(function(d) {
return d.key;

});



var divs2 = divs.selectAll(null)
.data(function(d) {
return d.values;
})
.enter()
.append('div')
.attr("class", "first")
.style("cursor", "pointer")
.on("click", function(d, i) {
const curColour = this.childNodes[1].attributes["height"].nodeValue;
if (curColour == '0px') {
d3.selectAll(this.childNodes).attr("height", "20px");
} else if (curColour == '0') {
d3.selectAll(this.childNodes).attr("height", "20px");
} else {
d3.selectAll(this.childNodes).attr("height", "0px");

}
});

divs2.append("text")
.attr('class', 'label1')
.attr('x', 0)
.attr('y', 0)
.style("font-size", "21px")
.text(function(d) {
return d.key;
})


var svgs2 = divs2.selectAll(null)
.data(function(d) {
return d.values;
})
.enter()
.append('svg')
.attr("class", "second")
.attr("height", 0)
.attr("width", function(d) {
return String(d3.select(this).value).length * 31.5
})
svgs2.append("text")
.attr('class', 'label2')
.attr('x', 10)
.attr('y', 17)
.style("font-size", "14px")
.text(function(d) {
return d.key;
})
.attr('text-anchor', 'start')
.style("cursor", "pointer")
.on("mouseover", function(d, i) {
div.transition()
.duration(200)
.style("opacity", .9);
div.html(d3.select(this).datum().values[0].TooltipInfo)

})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
});

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.9.1/d3.min.js"></script>

<div class="container"></div>

更新:我尝试在子节点上放置“停止传播”:

.on("mouseover", function(event) {
event.stopPropagation();
div.transition()
.duration(200)
.style("opacity", .9);
div.html(d3.select(this).datum().values[0].TooltipInfo)

但它似乎停止了 child 的 Action (工具提示出现)而不是 parent 的 Action ( child 消失)。

更新#2:stopPropagation似乎不适用于鼠标悬停,仅适用于点击。以下给出了我想要的行为(但我仍然需要弄清楚如何消失工具提示):

.on("click", function() {
event.stopPropagation();
div.transition()
.duration(200)
.style("opacity", .9);
div.html(d3.select(this).datum().values[0].TooltipInfo)

最佳答案

当您单击底层 SVG 时,浏览器会尝试从鼠标(更一般地说,指针)位置的最底部元素开始,为生成的 click 事件找到合适的处理程序。如果在该元素上没有找到处理程序,浏览器将向上遍历 DOM 树,检查任何封闭的元素,即父元素 - 已注册处理程序的元素,直到找到一个处理程序或到达根元素。这个过程称为事件冒泡,如果您不熟悉它,您可能需要花一些时间深入研究这个概念,因为它将有助于理解 JavaScript 事件处理方面的许多误解。有许多涉及该主题的资源,例如:

要阻止 click 事件向上冒泡到中层元素,导致其切换底层元素的可见性,您需要在底部注册一个 click 处理程序级别元素本身。在该处理程序中,您可以使用事件的 stopPropagation方法来防止事件进一步冒泡。

.on("click", () => d3.event.stopPropagation());

这样做,如果您单击底层元素,则中级元素的处理程序将不会被执行,而如果您单击中级元素本身,中级元素仍然可以访问。

看看下面的工作演示:

var doc = URL.createObjectURL(new Blob([`TooltipInfo	Category	Function1	Function2
Records relating to the skydiving. Includes halters, parachutes, and altimeters.<ul><li>For records relating to rock climbing, see <b>rock climbing</b>.</li><li>For travel expenses, see <b>Procurements & Purchasing</b>.</li></ul>Retention:<ul><li>Keep records for seven years from the date of record creation, then send to <mark>archives.</mark></li><li>Keep all other records for seven years from the date of record creation, then destroy.</li></ul> • Skydiving Management Extreme Sports > Organization-sustaining Activities`]))


d3.tsv(doc)
.row(function(d) {
return {
University: d.University,
TooltipInfo: d.TooltipInfo,
Searchterms: d.Searchterms,
Category: d.Category,
Function1: d.Function1,
Function2: d.Function2,
MaxRetentionRounded: d.MaxRetentionRounded,
ModifiedRetention: d.ModifiedRetention
};
})
.get(function(error, data) {

var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0)

var height = 150,
width = 300;


var nest = d3.nest()
.key(function(d) {
return d.Function2;
})
.key(function(d) {
return d.Function1;
})
.key(function(d) {
return d.Category;
})
.entries(data);


var height = 80,
width = 150;


var divs = d3.select(".container")
.selectAll(null)
.data(nest)
.enter()
.append("div")
.attr("class", "innerdiv");

divs.append("p")
.html(function(d) {
return d.key;

});



var divs2 = divs.selectAll(null)
.data(function(d) {
return d.values;
})
.enter()
.append('div')
.attr("class", "first")
.style("cursor", "pointer")
.on("click", function(d, i) {
const curColour = this.childNodes[1].attributes["height"].nodeValue;
if (curColour == '0px') {
d3.selectAll(this.childNodes).attr("height", "20px");
} else if (curColour == '0') {
d3.selectAll(this.childNodes).attr("height", "20px");
} else {
d3.selectAll(this.childNodes).attr("height", "0px");

}
});

divs2.append("text")
.attr('class', 'label1')
.attr('x', 0)
.attr('y', 0)
.style("font-size", "21px")
.text(function(d) {
return d.key;
})


var svgs2 = divs2.selectAll(null)
.data(function(d) {
return d.values;
})
.enter()
.append('svg')
.attr("class", "second")
.attr("height", 0)
.attr("width", function(d) {
return String(d3.select(this).value).length * 31.5
})
svgs2.append("text")
.attr('class', 'label2')
.attr('x', 10)
.attr('y', 17)
.style("font-size", "14px")
.text(function(d) {
return d.key;
})
.attr('text-anchor', 'start')
.style("cursor", "pointer")
.on("mouseover", function(d, i) {
div.transition()
.duration(200)
.style("opacity", .9);
div.html(d3.select(this).datum().values[0].TooltipInfo)

})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
})
.on("click", () => d3.event.stopPropagation());

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.9.1/d3.min.js"></script>

<div class="container"></div>

关于javascript - 阻止 div 的 childNodes 响应 div 的事件监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57468513/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com