保持列表项突出显示,react.js

时间:2018-06-08 22:27:45

标签: javascript css reactjs

我想保留当前点击列表项的背景颜色和颜色。我已经通过CSS使用以下代码突出显示它:

.segmentsList:hover {
    background: black;
    color: white;
    cursor: pointer;
}

我试图将onClickFunction附加到li上的onClick事件,如下所示:

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.log(e);
        // e.target.element.class="newBlackColor";
    }

    render() {


        console.log(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.log(rawFile.responseText);
                    const lines = splitLines(text);
                    // console.log(lines);
                    const words = splitWords(lines[0]);
                    // console.log(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

检查事件对象,我们看到目标是null:

target:null

我做错了什么?

我也读过:

CSS Change List Item Background Color with Class

How to give a different color to a selected list item with CSS?

Highlight item 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.log(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.log(rawFile.responseText);
                    const lines = splitLines(text);
                    // console.log(lines);
                    const words = splitWords(lines[0]);
                    // console.log(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.log(e.target.className);
        if (!this.state.highlighted) {
            console.log('highlight');
            e.target.className = 'segmentsListSelected';
        } else {
            console.log('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;

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

您没有正确使用React,我会 HIGHLY 建议您花一些时间阅读有关如何使用组件的文档。话虽这么说,在这种情况下,您应该使用state来存储加载的单词以及活动选择。同样 DONT 我重复不要在渲染方法中打开一个文件!...渲染周期可能会发生很多,这意味着每次渲染都会打开文件,是一个坏主意。

// 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;
}