如何在HTML textarea中使用Action Text(Trix)保留富文本样式与剪贴板功能
问题根因
<textarea>原生仅支持纯文本渲染,无法解析展示粗体、斜体等富文本样式- 现有代码调用了
to_plain_text方法,本身就已经过滤掉了所有富文本格式标签,输出内容为纯文本,不可能保留样式效果
解决方案
不需要依赖<textarea>实现剪贴板复制功能,直接用普通div容器渲染Action Text富文本,调整Stimulus剪贴板控制器的取值逻辑即可同时满足富文本渲染+复制需求。
1. 修改页面模板代码
替换textarea为富文本渲染容器,直接输出Action Text原始富文本内容,保留剪贴板target绑定:
<div class="article-code" data-controller="clipboard" data-clipboard-success-content="Copied !"> <div class="article-code-content"> <div class="trix-content" data-clipboard-target="source"> <%= article.content %> </div> </div> <div type="image" class="card-copy" data-action="clipboard#copy"> <button class="btn-copy" type="button" data-action="clipboard#copy" data-clipboard-target="button">Copy</button> </div> </div>
2. 调整剪贴板Stimulus控制器逻辑
原逻辑针对textarea使用.value取值,针对div容器需要换成对应取值属性:
- 代码块/纯文本复制场景:取容器的
innerText - 需要保留富文本格式复制场景:取容器的
innerHTML,配合Clipboard API的write方法写入富文本内容
参考控制器代码:
import { Controller } from "@hotwired/stimulus" export default class extends Controller { static targets = ["source", "button"] copy() { // 纯文本复制使用 const copyContent = this.sourceTarget.innerText // 富文本复制替换为以下逻辑 // const copyContent = this.sourceTarget.innerHTML navigator.clipboard.writeText(copyContent).then(() => { const originalBtnText = this.buttonTarget.innerText this.buttonTarget.innerText = this.data.get("clipboard-success-content") setTimeout(() => { this.buttonTarget.innerText = originalBtnText }, 2000) }) } }
内容的提问来源于stack exchange,提问作者Keyvan Sabras
相关产品推荐
相关产品推荐

