Как отобразить show more только при переполнении текста из div с использованием чистого css javascript in reactjs - PullRequest
0 голосов
/ 19 марта 2020

У меня есть компонент, который получает динамический c текст. Я показываю многоточие, когда текст переполняет ширину div. Теперь я показываю show more, и когда пользователь нажимает на него, я показываю весь текст и показываю show less ссылку.

import React from "react";
import "./styles.css";

export default function App(props) {
  const [showMore, setShowMore] = React.useState(true);
  const onClick = () => {
    setShowMore(!showMore);
  }
  return (
    <>
      <div className={showMore ? '' : "container"}>{props.text}</div>
      <span className="link" onClick={onClick}>{showMore ? 'show less' : 'show more'}</span>
    </>
  );
}

.container {
  overflow-x: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: block !important;
  width: 250px;
  background-color: #eaeaea;
}

enter image description here

enter image description here

Приведенный выше код показывает ссылку show more, даже если текст не переполняется.

enter image description here

Но я хочу показывать show more ссылку только при переполнении текста. Как мне этого добиться?

РЕДАКТИРОВАТЬ

Из комментария Crays я нашел это stackoverflow anwser

Теперь я попробовал используя ссылку для доступа к следующим стилям

import React from "react";
import "./styles.css";

export default function App(props) {
  const [showMore, setShowMore] = React.useState(false);
  const onClick = () => {
    setShowMore(!showMore);
  };

  const checkOverflow = () => {
    const el = ref.current;
    const curOverflow = el.style.overflow;

    if ( !curOverflow || curOverflow === "visible" )
        el.style.overflow = "hidden";

    const isOverflowing = el.clientWidth < el.scrollWidth 
        || el.clientHeight < el.scrollHeight;

    el.style.overflow = curOverflow;

    return isOverflowing;
  };

  const ref = React.createRef();

  return (
    <>
      <div ref={ref} className={showMore ? "container-nowrap" : "container"}>
        {props.text}
      </div>
      {(checkOverflow()) && <span className="link" onClick={onClick}>
        {showMore ? "show less" : "show more"}
      </span>}
    </>
  )
}

Я также пытался использовать forwardref

export const App = React.forwardRef((props, ref) => {
  const [showMore, setShowMore] = React.useState(false);
  const onClick = () => {
    setShowMore(!showMore);
  };

  const checkOverflow = () => {
    const el = ref.current;
    const curOverflow = el.style.overflow;

    if (!curOverflow || curOverflow === "visible") el.style.overflow = "hidden";

    const isOverflowing =
      el.clientWidth < el.scrollWidth || el.clientHeight < el.scrollHeight;

    el.style.overflow = curOverflow;

    return isOverflowing;
  };

  return (
    <>
      <div ref={ref} className={showMore ? "container-nowrap" : "container"}>
        {props.text}
      </div>
      {checkOverflow() && (
        <span className="link" onClick={onClick}>
          {showMore ? "show less" : "show more"}
        </span>
      )}
    </>
  );
});

Но я получаю ошибку Cannot read property 'style' of null

1 Ответ

0 голосов
/ 15 апреля 2020

Я думаю, что вы можете go использовать другой подход, вместо того, чтобы зависеть от того, что происходит визуально внутри браузера

Допустим, текст будет переполнен только тогда, когда у вас больше N символов (определите это число как себя) например 100 символов

import {useState} from 'react';

export const Accordion = ({ text, limit = 100 }) => {
  const isExpandable = text.length > limit;
  const [viewText, setViewText] = useState(
    isExpandable ? text.slice(0, limit) : text
  );
  const isExpanded = text.length === viewText.length;
  return (
    <>
      <p>{viewText}</p>
      {isExpandable && (
        <button
          onClick={() => setViewText(isExpanded ? text.slice(0, limit) : text)}
        >
          {isExpanded ? "show less" : "show more"}
        </button>
      )}
    </>
  );
};

код песочницы ссылка здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...