使用React将文本拆分为单个字符

最近,我需要为标题元素中的各个字符设置动画。我希望有一个类似于CSS的方便的CSS专用解决方案:nth-child(i),但不幸的是不存在。因此,我决定研究如何实现类似且可访问的内容。

的HTML

我的第一个想法是<span>手动将每个字符包装在单独的元素中。

<h1>
    <span>T</span>
    <span>e</span>
    <span>x</span>
    <span>t</span>
</h1>

但是,此方法存在两个问题:

  1. 辅助功能:通过这样分割文本,屏幕阅读器将单独读取每个字符,这对依赖屏幕阅读器的人们来说是一种痛苦的体验。
  2. 可伸缩性:这样写出整个单词或句子是一个烦人的过程,每次都必须手动重复,并且不适用于动态加载的文本。

具有HTML和JavaScript的可访问且可扩展的解决方案

我在css-irl上找到了解决这些问题的解决方案,使用aria元素来实现可访问性,并使用javascript来自动执行文本拆分。它以您想要拆分的文本作为输入,并以如下方式返回它:

<h1 aria-label="Text">
    <span aria-hidden="true">T</span>
    <span aria-hidden="true">e</span>
    <span aria-hidden="true">x</span>
    <span aria-hidden="true">t</span>
</h1>

屏幕阅读器将阅读内部定义的文本,aria-label但忽略标记为的元素aria-hidden="true"。但是,当我在Mac上的VoiceOver上尝试此操作时,我发现还必须向role父级添加一个元素才能使其正常工作。

<h1 aria-label="Text" role="heading"> ... </h1>

反应组件

由于我在React中做了很多工作,因此我决定在可重用组件中创建一个类似的解决方案。

从前面的示例中我们知道,我们至少有两个变量信息:必须显示的文本(this.props.copy)和元素的角色(this.props.role)。

基于此,我们可以从创建SplitText可重用组件开始:

<SplitText copy="This is the text that will be split" role="heading" />

SplitText组件的render函数中,我们首先要使用aria-label={this.props.copy}和渲染一个父元素role={this.props.role}。这将使屏幕阅读器阅读原始文本。

然后,我们需要遍历副本,并使用返回返回包裹在span元素中的每个元素aria-hidden="true"。这将在视觉上呈现字符串的每个字符,但屏幕阅读器将跳过它。我们可以使用.split("")函数将文本变成数组来遍历文本。

render(){
    return(
        <span aria-label={this.props.copy} role={this.props.role}>
        {this.props.copy.split("").map(function(char, index){
            return <span aria-hidden="true" key={index}>{char}</span>;
        })}
        </span>
    );
}

在此扩展

现在我们有了基础,我们还可以扩展此逻辑,并在其中添加更多功能SplitText,例如自定义类名称或条件样式。我将编写第二个教程,在其中我们将更深入地介绍一些示例。

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/261880.html

(0)
上一篇 2022年5月25日
下一篇 2022年5月25日

相关推荐

发表回复

登录后才能评论