reactjs - 如何使用“onclick”事件更改 ListItem 元素的样式?
问题描述
我的目标是当我单击 ListItem 时,它应该更改background-color
and text: "line-through"
。然后,如果我再次单击,这些更改应该被取消。
但这对我来说发生得很奇怪。我只是不明白为什么只有在单击窗口的任何位置后才会ListItem
更改?background-color
为什么只有在我将指针移到元素之外之后,ListItem 中的文本才会被划掉
const styles = () => ({
listItem: {
borderRadius: "1em"
},
listItemDone: {
borderRadius: "1em",
backgroundColor: "#F6F6E8",
textDecoration: "line-through"
},
iconButton: {
padding: 5
},
important: {
color: "#00ACE9",
fontWeight: "bold"
}
});
class TodoListItem extends Component {
state = {
done: false
};
onClickItem = () => {
this.setState({
done: !this.state.done
});
};
render() {
const { label, important = false, classes } = this.props;
const { done } = this.state;
return (
<ListItem
onClick={this.onClickItem}
className={done ? classes.listItemDone : classes.listItem}
button
divider
>
<ListItemText
primary={label}
classes={{ primary: important ? classes.important : "" }}
/>
</ListItem>
);
}
}
解决方案
每当您尝试覆盖 Material-UI 样式并且它没有像您期望的那样工作时,最好的资源是源代码。这是ListItem
源代码的 URL:https ://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/ListItem/ListItem.js 。在大多数情况下,您只需要查看styles
源文件顶部附近的变量。
下面我复制了styles
处理backgroundColor
and的所有变量部分textDecoration
:
export const styles = theme => ({
/* Styles applied to the (normally root) `component` element. May be wrapped by a `container`. */
root: {
textDecoration: 'none',
'&$selected, &$selected:hover, &$selected:focus': {
backgroundColor: theme.palette.action.selected,
},
},
/* Styles applied to the inner `component` element if `button={true}`. */
button: {
transition: theme.transitions.create('background-color', {
duration: theme.transitions.duration.shortest,
}),
'&:hover': {
textDecoration: 'none',
backgroundColor: theme.palette.action.hover,
// Reset on touch devices, it doesn't add specificity
'@media (hover: none)': {
backgroundColor: 'transparent',
},
},
'&:focus': {
backgroundColor: theme.palette.action.hover,
},
},
/* Styles applied to the root element if `selected={true}`. */
selected: {},
});
导致困难的主要样式是button
悬停和焦点样式。为了在不诉诸“!important”的情况下成功覆盖这些内容,您需要具有适当的 CSS 特异性。
以下似乎可以解决问题:
listItemDone: {
borderRadius: "1em",
"&,&:focus,&:hover": {
backgroundColor: "#F6F6E8",
textDecoration: "line-through"
}
},
但是,以上内容可以防止对“完成”项目产生任何悬停效果,因此您可能想要做更多类似的事情:
listItemDone: {
borderRadius: "1em",
"&,&:focus": {
backgroundColor: "#F6F6E8",
textDecoration: "line-through"
},
"&:hover": {
textDecoration: "line-through"
}
},
这允许已完成项目的悬停背景颜色仍然是theme.palette.action.hover
. 如果您希望已完成项目的悬停颜色不同,则可以与 textDecoration 一起显式指定它。
还有一个细节需要注意。如果单击列表项使其处于“完成”状态,然后再次单击它,它将不再处于“完成”状态,但会button
应用焦点样式。为了删除该焦点样式,您还需要以下内容:
listItem: {
borderRadius: "1em",
"&,&:focus": {
backgroundColor: theme.palette.background.paper // or whatever color you want this to be
}
},
这是我修改后的沙箱版本:
推荐阅读
- python - 如何将 CSS 类分配给 many2one 字段并在 odoo 10 的看板视图中引用它?
- tensorflow-lite - 使用问答协议的 Python Tensorflow lite 运行时推理引擎
- swift - 删除表列时如何让 NSTableView 自动取消绑定对象?
- javascript - 将事件侦听器添加到 Google 地图标记的“标题”属性
- javascript - 如何使用 django rest 框架对用户进行身份验证
- php - 如何在PHP中合并两个不重复的多数组
- javascript - 如何正确转义此正则表达式构造中的字符
- css - Flex 半自举
- python - 最长和最短序列,Python
- retinanet - 训练 fizyr/keras-retinanet 的数据集中图像的最大标签数?