简体   繁体   English

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

[英]Keep a list item highlighted, react.js

I would like to keep the background-color and color of the current clicked list item. 我想保留当前单击列表项的背景颜色和颜色。 I have made it to be highlighted via CSS with the following code: 我通过以下代码通过CSS突出显示了它:

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

I have tried to attach an onClickFunction to the onClick event inn the li as follows: 我尝试将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, " "));
}

When I click on the list item, the console says: 当我单击列表项时,控制台会显示:

Uncaught TypeError: Cannot set property 'class' of undefined

And inspecting the event object we see that the target is null: 并检查事件对象,我们看到目标为空:

target:null

What am I doing wrong? 我究竟做错了什么?

I have also read: 我也读过:

CSS Change List Item Background Color with Class CSS更改列表项的背景色(带类)

How to give a different color to a selected list item with CSS? 如何使用CSS为选定的列表项赋予不同的颜色?

Highlight item onClick - React.js 突出显示项目onClick-React.js

EDIT: 编辑:

I would like to highlight the clicked one and remove the highlight of the previous clicked one. 我想突出显示单击的内容,并删除上一个单击的内容的突出显示。

I have written a way to highlight the list element and keep it highlighted until you clicked on it again: 我编写了一种突出显示列表元素并保持突出显示的方法,直到您再次单击它为止:

SegmentsList.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 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;

Thank you for your help. 谢谢您的帮助。

You aren't using React correctly and I would HIGHLY recommend you spend some time reading the docs on how a component should be used. 您没有正确使用React,我强烈建议您花一些时间阅读有关如何使用组件的文档。 That being said, in this instance you should use state to store the words that get loaded and also for an active selection. 话虽这么说,在这种情况下,您应该使用状态来存储加载的单词,并用于活动选择。 Also DONT I repeat DONT open a file in the render method!... render cycles can happen a lot and that would mean you open the file every time render happens, which is a bad idea. 此外DONT我再说一遍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>

        );
    }
}

then the last thing is to add a class for the selection in your css 那么最后一件事是在CSS中添加一个用于选择的类

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM