【问题标题】:How to wrap array of html span tags with more span tags?如何用更多跨度标签包装html跨度标签数组?
【发布时间】:2021-03-16 14:32:27
【问题描述】:

我制作了一个组件,它将我的文本的每个字母都包含在一个 span 标签中:

export default function Header({ text }) {
    let header = []

    for (let i = 0; i < text.length; i++) {
        const colours = ["red", "green", "yellow", "blue", "pink", "orange"]
        const rng = Math.floor((Math.random() * colours.length))

        header.push({
            color: colours[rng],
            letter: text.charAt(i) == ' ' ? <span className="white-space"></span> : text.charAt(i)
        })
    }

    return (
        <h1 id="header">
            {header.map((el, i) => (<span key={i} style={{ color: el.color }}>{el.letter}</span>))}
        </h1>
    )
}

这将产生这个结果(其中文本是“Hello World”):

<h1 id="header">
    <span>H</span>
    <span>e</span>
    <span>l</span>
    <span>l</span>
    <span>o</span>
    <span><span className="white-space"></span></span>
    <span>W</span>
    <span>o</span>
    <span>r</span>
    <span>l</span>
    <span>d</span>
</h1>

效果很好,但是当句子的大小大于浏览器窗口的大小时,它会包裹一些字母,有时会弄乱整个文本(而不是“Hello World”,你可以得到“Hello”, “我”,“rld”)。

为了解决这个问题,我现在需要将作为单词的跨度标签组包装在额外的跨度标签中,以达到此结果:

<h1 id="header">
    <span>
        <span>H</span>
        <span>e</span>
        <span>l</span>
        <span>l</span>
        <span>o</span>
    </span>
    <span><span className="white-space"></span></span>
    <span>
        <span>W</span>
        <span>o</span>
        <span>r</span>
        <span>l</span>
        <span>d</span>
    </span>
</h1>

我该怎么做?

【问题讨论】:

    标签: javascript html reactjs


    【解决方案1】:

    将文本更改为字符串数组。然后遍历单词并将它们拆分为字符:

    export default function Header({ words = ["hello", "world"] }) {
      const header = words.map((word, j) => {
        return (
          <>
            <span>
              {word.split("").map((letter, i) => {
                const colours = [
                  "red",
                  "green",
                  "yellow",
                  "blue",
                  "pink",
                  "orange",
                ];
                const rng = Math.floor(Math.random() * colours.length);
    
                return (
                  <span key={i} style={{ color: colours[rng] }}>
                    {letter}
                  </span>
                );
              })}
            </span>
            {j < words.length - 1 && <span className="white-space"></span>}
          </>
        );
      });
    
      return <h1 id="header">{header}</h1>;
    }
    

    【讨论】:

      【解决方案2】:

      即兴版:

      function wrapLetters(word) {
        const wrappedLetters = [];
        const colours = ["red", "green", "yellow", "blue", "pink", "orange"];
        for (let i = 0; i < word.length; i++) {
          const rng = Math.floor(Math.random() * colours.length);
          wrappedLetters.push(
            <span key={i} style={{ color: colours[rng] }}>
              {word[i]}
            </span>
          );
        }
        return wrappedLetters;
      }
      
      function wrapWord(wrappedLetters, i, notLast) {
        return (
          <span className="wrapper" key={i}>
            {notLast
              ? [...wrappedLetters, <span className="white-space" />]
              : wrappedLetters}
          </span>
        );
      }
      
      export default function Header({ text }) {
        const words = text.split(" ");
        const wrappedWords = words
         .map(wrapLetters)
         .map((wrappedLetters, i) => {
           return wrapWord(wrappedLetters, i, i < words.length - 1);
         });
        return <h1 id="header">{wrappedWords}</h1>;
      }
      

      沙盒:https://codesandbox.io/s/eloquent-sea-lvg6x?file=/src/Component.js:0-871


      我是这样写组件的。希望 cmets 是不言自明的。

      function wrapWord(word) {
        const lettersData = [];
        const colours = ["red", "green", "yellow", "blue", "pink", "orange"];
        for (let i = 0; i < word.length; i++) {
          const rng = Math.floor(Math.random() * colours.length);
          lettersData.push(
            <span key={i} style={{ color: colours[rng] }}>
              {word[i]}
            </span>
          );
        }
        return lettersData;
      }
      
      export default function Header({ text }) {
        const words = text.split(" "); // split text into an array if words
        const wordsData = words.map((word) => wrapWord(word)); // for each word create an array of spans
      
        // this method wraps each word with a span, and injects a space if it's not last word
        const combinedWords = wordsData.map((arr, i) => {
          return (
            <span className="wrapper" key={i}>
              {i < wordsData.length - 1
                ? [...arr, <span className="white-space" />]
                : arr}
            </span>
          );
        });
      
        return <h1 id="header">{combinedWords}</h1>;
      }
      

      代码沙箱:https://codesandbox.io/s/happy-hugle-6xpud?file=/src/Component.js:0-739

      【讨论】:

        猜你喜欢
        • 2021-02-20
        • 2023-02-09
        • 1970-01-01
        • 2014-07-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多