前端css样式覆盖问题

综述

今天在使用 D3 的时候遇到一个 css 的问题,这里留作记录防止以后踩坑。

问题

在使用 d3 添加鼠标响应事件,想要修改 css,结果不会修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let rec = svg.append("rect")
.attr("class", "view")
.attr("x", 1)
.attr("y", 1)
.attr("width", width - 2)
.attr("height", height - 2)
.attr("fill", "gray")
.style("stroke", "red")
.style("stroke-width", "2px")
.on("mouseover", function() {
d3.select(this).classed("hover", true)
})
.on("mouseout", function() {
d3.select(this).classed("hover", false)
})
1
2
3
4
5
6
7
8
9
10
.view:hover {
stroke: blue;
stroke-width: 2;
}

.view {
stroke: gold;
stroke-width: 2;
pointer-events: all;
}

这里添加了 mouseovermouseout 事件,借此改变 rect 的样式,结果没有成功。

解决方法

折腾了好久,问了一下大佬立马解决。

打开 chrome 的调试工具。

chrome

可以看到这里 .view:hover.view 都是被 element.style 覆盖了。

这个 element.style 一般是内联样式,因此查看自己的代码,发现在定义 rect 的时候已经定义了 style.style("stroke", "red").style("stroke-width", "2px")

将这两句去掉,可以得到最终结果:

hover

hover

unhover

unhover

完整代码

D3Component.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import React from 'react';
import * as d3 from 'd3';
import './D3Component.css'

class D3Component extends React.Component {

componentDidMount() {
let svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
let rec = svg.append("rect")
.attr("class", "view")
.attr("x", 1)
.attr("y", 1)
.attr("width", width - 2)
.attr("height", height - 2)
.attr("fill", "gray")
// .style("stroke", "red")
// .style("stroke-width", "2px")
.on("mouseover", function() {
d3.select(this).classed("hover", true)
})
.on("mouseout", function() {
d3.select(this).classed("hover", false)
})
}

render() {
return (
<div>
<svg id="svg" width="100" height="100"></svg>
</div>
)
}
}

export default D3Component;

D3Component.css

1
2
3
4
5
6
7
8
9
10
.view:hover {
stroke: blue;
stroke-width: 2;
}

.view {
stroke: gold;
stroke-width: 2;
pointer-events: all;
}