我一直在努力使一段文字可点击。我可以使其他文本可单击,并且单击此文本后该函数的行为与预期一致。麻烦的文本嵌套在某些东西中,我认为这就是为什么它与.on()
的行为不一样。我在文本片段中添加了id
以便于选择。
现在我终于有了一段代码,使文本可以点击,一切都按预期运行 - 但只有在Chrome开发者控制台中输入时才会这样做! :
d3.select("#patext").on("click", function() {toggleLine();})
在Chrome控制台中输入后,一切正常,但在index.html
文件中却无效。 ' patext'是我之前给它的id。 index.html
在顶部包含<style></style>
部分,然后在<body></body>
下面。在体内有两个<script></script>
第一个加载d3.js第二个是我的脚本。上面的d3.select()
行恰好位于toggleLine()
的函数定义之下。
已经完成了建议here和here并且我的脚本在正文和脚本中加载d3是一个单独的主脚本。有什么想法吗?
根据要求,以下是基于Bostock脚本的原始240行中的80行,希望我没有删除任何重要内容
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
/* background-color: #ffeda0;*/
}
.axis path
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var parseDate = d3.time.format("%Y-%m-%d").parse;
var x = d3.time.scale().range([0, width]);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
d3.csv("myfile.csv", function(error, data) {
if (error) throw error;
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "date"; }));
data.forEach(function(d) {
d.date = parseDate(d.date);
});
var cities = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {date: d.date, temperature: +d[name]}; // plus casts a string '55' to a number 55
})
};
});
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([
d3.min(cities, function(c) { return d3.min(c.values, function(v) { return v.temperature; }); }),
d3.max(cities, function(c) { return d3.max(c.values, function(v) { return v.temperature; }); })
]);
svg.append("rect") // fill it a colour
.attr("width", 830)
.attr("height", "100%")
.attr("fill", "AliceBlue");
svg.append("g")
.classed("axis x", true)
.call(xAxis2);
var city = svg.selectAll(".city")
.data(cities)
.enter().append("g")
.attr("class", "city");
city.append("path")
.style("stroke", function(d) {return color(d.name); })
.attr("class", "line")
.attr("id", function(d) {console.log((d.name).slice(0,3));return (d.name).slice(0,3);}) // for click fn below.
city.append("text")
.datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; })
.style("stroke", function(d) {return color(d.name); })
.transition()
.attr("x", 3)
.attr("dy", ".35em")
.text(function(d) { return d.name; })
.attr("id", function(d) {console.log((d.name).slice(0,2)+"text");return ((d.name).slice(0,2)+"text");}) // for click fn
});
function toggleLine() {
var active = gol.active ? false : true,
newOpacity = active ? 0 : 1;
d3.select("#gol").style("opacity", newOpacity);
gol.active = active;}
document.addEventListener("DOMContentLoaded", function(event) {
//... your code
d3.select("#patext").on("click", function() {toggleLine();});
//... more of your code
});
</script>
</body>
答案 0 :(得分:2)
原来有一个transition
并且延迟了DOM操作,这使得事件监听器在创建DOM元素之前绑定。
过渡是一种特殊类型的选择,操作员可以随着时间的推移而不是瞬间应用。您可以使用转换运算符从选择中转换。虽然转换通常支持与选择相同的运算符(例如attr和style),但并不支持所有运算符;例如,您必须在转换开始之前附加元素。提供了一个删除操作符,以便在转换结束时方便地删除元素。
解决方案是在click
之前绑定transition()
侦听器。
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
function toggleLine() {
var active = gol.active ? false : true,
newOpacity = active ? 0 : 1;
d3.select("#gol").style("opacity", newOpacity);
gol.active = active;
}
document.addEventListener("DOMContentLoaded", function(event) {
var parseDate = d3.time.format("%Y-%m-%d").parse;
var x = d3.time.scale().range([0, width]);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
d3.csv("myfile.csv", function(error, data) {
if (error) throw error;
// ...
city.append("text")
.datum(function(d) {
return {
name: d.name,
value: d.values[d.values.length - 1]
};
})
.attr("id", function(d) {
console.log((d.name).slice(0, 2) + "text");
return ((d.name).slice(0, 2) + "text");
}); // for click fn
// bind listener before transition
.on("click", function(d){
if(d3.select(this).attr('id') === "patext") {
toggleLine();
}
.style("stroke", function(d) {
return color(d.name);
})
.transition()
.attr("x", 3)
.attr("dy", ".35em")
.text(function(d) {
return d.name;
})
});
});
</script>
</body>
这允许在完全加载DOM后执行代码。
有关实现此目的的其他选项,请参阅$(document).ready equivalent without jQuery。