Я хотел бы сохранить цвет фона и цвет текущего элемента списка, по которому щелкнули мышью. Я сделал это для выделения с помощью CSS с помощью следующего кода:
.segmentsList:hover {
background: black;
color: white;
cursor: pointer;
}
Я попытался прикрепить onClickFunction к событию onClick в li следующим образом:
import React, {Component} from 'react';
import Link from "react-router-dom/es/Link";
import {Button} from 'reactstrap';
import cabeza from '../atlas/json/cabeza.json';
const parte = getParameterByName('parte') || 0;
export default class SegmentsList extends Component {
onClickFunction(e) {
console.info(e);
// e.target.element.class = "newBlackColor";
}
render() {
console.info(cabeza[parte].etiquetas);
readTextFile(cabeza[parte].etiquetas);
function readTextFile(url) {
const rawFile = new XMLHttpRequest();
rawFile.open("GET", url, false);
rawFile.overrideMimeType('text/xml; charset=iso-8859-1');
rawFile.onreadystatechange = function () {
if (rawFile.readyState === 4) {
const text = rawFile.responseText;
// console.info(rawFile.responseText);
const lines = splitLines(text);
// console.info(lines);
const words = splitWords(lines[0]);
// console.info(words);
window.words = words;
}
return;
function splitLines(text) {
return text.split('\n');
}
function splitWords(line) {
return line.split('" "').slice(1);
}
};
rawFile.send();
}
return (
<div>
<ol>
{window.words.map((word, index) =>
<li
onClick = {this.onClickFunction}
className='segmentsList'
key = {index}>{word}</li>
)}
</ol>
<Button
color='primary'
className='mt-3 ml-3'
>
<Link to='/'/>
Volver a la portada
</Button>
</div>
);
}
}
function getParameterByName(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
Когда я нажимаю на элемент списка, консоль говорит:
Uncaught TypeError: Cannot set property 'class' of undefined
И проверяя объект события, мы видим, что цель равна нулю:
target:null
Что я делаю неправильно?
Я также читал:
Цвет фона элемента списка изменений CSS с классом
Как с помощью CSS изменить цвет выделенному элементу списка?
Выделите элемент onClick - React.js
Обновлено:
Я хотел бы выделить нажатый и убрать выделение с предыдущего.
Я написал способ выделить элемент списка и держать его выделенным, пока вы не нажмете на него еще раз:
SegmentsList.js
import React, {Component} from 'react';
import Link from "react-router-dom/es/Link";
import {Button} from 'reactstrap';
import cabeza from '../atlas/json/cabeza.json';
import SegmentsListItem from "./SegmentsListItem";
const parte = getParameterByName('parte') || 0;
export default class SegmentsList extends Component {
constructor(props) {
super(props);
}
render() {
console.info(cabeza[parte].etiquetas);
readTextFile(cabeza[parte].etiquetas);
function readTextFile(url) {
const rawFile = new XMLHttpRequest();
rawFile.open("GET", url, false);
rawFile.overrideMimeType('text/xml; charset=iso-8859-1');
rawFile.onreadystatechange = function () {
if (rawFile.readyState === 4) {
const text = rawFile.responseText;
// console.info(rawFile.responseText);
const lines = splitLines(text);
// console.info(lines);
const words = splitWords(lines[0]);
// console.info(words);
window.words = words;
}
return;
function splitLines(text) {
return text.split('\n');
}
function splitWords(line) {
return line.split('" "').slice(1);
}
};
rawFile.send();
}
return (
<div>
<ol>
{window.words.map((word, index) =>
<SegmentsListItem word = {word} key = {index}/>
)}
</ol>
<Button
color='primary'
className='mt-3 ml-3'
>
<Link to='/'/>
Volver a la portada
</Button>
</div>
);
}
}
function getParameterByName(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
SegmentsListItem.js
import React, {Component} from 'react';
class SegmentsListItem extends Component {
constructor(props) {
super(props);
this.state = {highlighted: false};
}
highlight = (e) => {
console.info(e.target.className);
if (!this.state.highlighted) {
console.info('highlight');
e.target.className = 'segmentsListSelected';
} else {
console.info('remove highlight');
e.target.className = 'segmentsList';
}
this.setState({highlighted: !this.state.highlighted})
};
render() {
return (
<li
onClick = {this.highlight}
className='segmentsList'
key = {this.props.index}>{this.props.word}</li>
);
};
}
export default SegmentsListItem;
Спасибо за помощь.
Привет, просто чтобы уточнить, вы хотите, чтобы элемент списка оставался выделенным? Я согласен с Deadron, что вы не используете React для того, для чего он создан. Я бы использовал встроенный стиль и установил цвета, используя состояние компонентов. Если вы не догадались до сегодняшнего вечера, я отвечу на него рабочим образцом.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы неправильно используете React, и я бы рекомендовал ОЧЕНЬ потратить некоторое время на чтение документации о том, как следует использовать компонент. При этом, в этом случае вы должны использовать состояние для хранения загружаемых слов, а также для активного выбора. Также НЕ Я повторяю НЕ открыть файл в методе рендеринга! ... Циклов рендеринга может быть много, и это будет означать, что вы открываете файл каждый раз, когда происходит рендеринг, что является плохой идеей.
// these are more helper functions.. either define them on your class or just define them in a helpers/utility file. or just put as a global above the class
function splitLines(text) {
return text.split('\n');
}
function splitWords(line) {
return line.split('" "').slice(1);
}
export default class SegmentsList extends Component {
constructor(props) {
super(props);
this.state = { words: [], activeWord: -1 }
}
onClickFunction = (idx) => {
// set the state to only have a current word selection which will unselect the previous selection
this.setState({activeWord: idx})
}
readTextFile = (url) => {
const rawFile = new XMLHttpRequest();
rawFile.open("GET", url, false);
rawFile.overrideMimeType('text/xml; charset=iso-8859-1');
rawFile.onreadystatechange = () => {
if (rawFile.readyState === 4) {
const text = rawFile.responseText;
const lines = splitLines(text);
const words = splitWords(lines[0]);
this.setState({words});
}
return;
};
rawFile.send();
}
componentDidMount() {
this.readTextFile(cabeza[parte].etiquetas);
}
render() {
return (
<div>
<ol>
{this.state.words.map((word, index) =>
<li
onClick = {this.onClickFunction.bind(null, index)}
className = {`segmentsList${this.state.activeWord === index ? ' selected' : ''}`}
key = {index}
>
{word}
</li>
)}
</ol>
<Button
color='primary'
className='mt-3 ml-3'
>
<Link to='/'/>
Volver a la portada
</Button>
</div>
);
}
}
то последнее, что нужно сделать, это добавить класс для выбора в ваш css
.segmentsList:hover, .segmentsList.selected {
background: black;
color: white;
cursor: pointer;
}
Первоначально я отправил ответ, но здесь слишком много неправильного. Здесь вы неправильно используете реакцию, и это большая проблема.