简体   繁体   English

JavaScript - 将 p 标签转换为文本区域并将更改的文本复制到剪贴板

[英]JavaScript - Convert p tag to text area and copy changed text to clipboard

How to achieve this?如何做到这一点? In an HTML page, there is ap tag with some content (but only with indentations through &nbsp; and new line tags <br>).在 HTML 页面中,有带有一些内容的 ap 标签(但只有通过 &nbsp; 和新行标签 <br> 的缩进)。 I'd like to offer two buttons: one to convert the p tag into a text area so that the existing content can be adapted by the user, one to copy the content (if the content was not adapted, the original content should be copied, if adapted, certainly the adapted code should be copied).我想提供两个按钮:一个将 p 标签转换为文本区域,以便用户可以改编现有内容,一个复制内容(如果内容没有被改编,则应复制原始内容,如果改编,当然应该复制改编的代码)。 I have prepared the code below so far.到目前为止,我已经准备好了下面的代码。 The final functionality should be (most of it not working/implemented in the snippet; the solution should be JS only):最终的功能应该是(大部分在代码片段中不起作用/实现;解决方案应该是 JS):

  • Click Copy: copies the changed content or original content if not adapted单击复制:如果未改编,则复制更改的内容或原始内容
  • Click Adapt: turns the p tag into a text area, user can adapt the text点击 Adapt:将 p 标签变成文本区域,用户可以调整文本
  • The text area should retain the original format: indentations and the line breaks but it should not display the HTML tags (eg <br>)文本区域应保留原始格式:缩进和换行,但不应显示 HTML 标记(例如 <br>)
  • When the adapted content is copied after clicking Copy, the text area should disappear and the original content should be displayed again (the original p tag, not the text area), ie all the changes should be reverted单击复制后复制改编的内容时,文本区域应该消失,并且应该重新显示原始内容(原始p标签,而不是文本区域),即所有更改都应该恢复
  • When clicking Adapt and then Adapt a second time, also all the changes should be reverted and the original p should be displayed again (otherwise, the text area would not vanish until page reload).当再次单击 Adapt 和 Adapt 时,所有更改都应还原,并且应再次显示原始 p(否则,文本区域在页面重新加载之前不会消失)。 Idea: When the Adapt button gets clicked, the name of the button should change to something like "Revert", and after clicking "Revert" the original p and the button "Adapt" could be displayed again.思路:点击 Adapt 按钮后,按钮名称应变为“Revert”之类的名称,点击“Revert”后,原来的 p 和“Adapt”按钮可以再次显示。
  • How to position the Copy button in the first place and then the Adapt button right next to it?如何 position 首先是复制按钮,然后是它旁边的调整按钮? How to then reference to the p tag?那么如何引用 p 标签呢? It must work without a predefined ID.它必须在没有预定义 ID 的情况下工作。

Any further ideas?还有什么想法吗? Thanks!谢谢!

 <button onclick="edit(this)">Adapt</button> <p>some text 1<br>&nbsp;&nbsp;&nbsp;&nbsp;some text 2<br>&nbsp;some text 3&nbsp;&nbsp;some text 4 &amp;&amp; .... <br>&nbsp;&nbsp;..... <br>&nbsp;&nbsp;&nbsp;&nbsp;...... <br>&nbsp;&nbsp;...... <br>...... <br><br></p> <button title="Copy to clipboard" onclick="copy_text(this)">Copy</button> <script> function edit(item) { var a = item.nextElementSibling; a.outerHTML = a.outerHTML.replace(/<p>/g, '<textarea style="width: 100%; height: 100px ">').replace(/<\/p>/g, '</textarea>'); } </script> <script> function copy_text(item) { const str = item.previousElementSibling.innerText; const el = document.createElement("textarea"); el.value = str; el.setAttribute("readonly", ""); el.style.position = "absolute"; el.style.left = '-9999px'; document.body.appendChild(el); el.select(); document.execCommand("copy"); document.body.removeChild(el); }; </script>

Test it here in StackBlitzStackBlitz中测试它

I don't know how you intend finding the p element an id or a class or an attribute but for this answer I just used the tag.我不知道您打算如何查找p元素idclassattribute ,但对于这个答案,我只使用了标签。

Check this answer for why I used the Clipboard API检查这个answer ,了解为什么我使用剪贴板 API

ReplaceWith MDN

 let original = ''; const buttons = [...document.querySelectorAll('button')]; function edit(button) { let paragraph = button.nextElementSibling.nextElementSibling; button.innerText = paragraph.tagName == 'P'? 'Revert': 'Adapt'; if (paragraph.tagName == 'P') { original = paragraph.innerHTML; const textarea = Object.assign(document.createElement('textarea'), { innerHTML: paragraph.innerText, // I use the innerText so that the HTML tags will be stripped but the space and new lines will be kept style: 'width: 100%; height: 100px;' // Style for the textarea }); paragraph.replaceWith(textarea); // Replace the p tag directly with the new textarea } else { const p = Object.assign(document.createElement('p'), { innerHTML: original }); paragraph.replaceWith(p); } } function copy_text(button) { let paragraph = button.nextElementSibling; const str = paragraph.value || paragraph.innerText; navigator.clipboard.writeText(str).then(_ => { if (paragraph.tagName.== 'P') { // To convert the textarea back to the p const p = Object.assign(document,createElement('p'): { innerHTML; original // Convert the new lines back to br tag and the spaces to &nbsp }). paragraph;replaceWith(p). } button.previousElementSibling;innerText = 'Adapt'; alert('Copied'), }: e => alert(`Failed; ${e}`)); }. // Event Listeners buttons.forEach(button => button,addEventListener('click'. e => { const buttonType = button.innerText;toLowerCase(), if (['adapt'. 'revert'];includes(buttonType)) edit(button); else if (buttonType == 'copy') copy_text(button); }));
 <h1>Paragraph 1</h1> <button>Adapt</button> <button title="Copy to clipboard">Copy</button> <p>some text 1<br>&nbsp;&nbsp;&nbsp;&nbsp;some text 2<br>&nbsp;some text 3&nbsp;&nbsp;some text 4 &amp;&amp; .... <br>&nbsp;&nbsp;..... <br>&nbsp;&nbsp;&nbsp;&nbsp;...... <br>&nbsp;&nbsp;...... <br>...... <br><br></p> <h1>Paragraph 2</h1> <button>Adapt</button> <button title="Copy to clipboard">Copy</button> <p>some text 1<br>&nbsp;&nbsp;&nbsp;&nbsp;some text 2<br>&nbsp;some text 3&nbsp;&nbsp;some text 4 &amp;&amp; .... <br>&nbsp;&nbsp;..... <br>&nbsp;&nbsp;&nbsp;&nbsp;...... <br>&nbsp;&nbsp;...... <br>...... <br><br></p>

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

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