目录
textarea
,把需要的文本放进 textarea
中textarea
元素插入 body
中。HTMLInputElement.select()
方法选择 textarea
中的文本内容document.execCommand('copy')
复制 textarea
中的文本内容到剪贴板body
删除 textarea
元素const copyToClipboard = str => {
const el = document.createElement('textarea');
el.value = str;
document.body.appendChild(el);
el.select();
document.execCommand('copy');
document.body.removeChild(el);
};
复制代码
const copyToClipboard = str => {
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);
};
复制代码
DocumentOrShadowRoot.getSelection(), Selection.rangeCount, Selection.getRangeAt(), Selection.removeAllRanges() and Selection.addRange()
这些方法存储用户选择的文本内容和解决范围选择的问题const copyToClipboard = str => {
const el = document.createElement('textarea'); // Create a element</span>
el.value = str; <span class="hljs-comment">// Set its value to the string that you want copied</span>
el.setAttribute(<span class="hljs-string">'readonly'</span>, <span class="hljs-string">''</span>); <span class="hljs-comment">// Make it readonly to be tamper-proof</span>
el.style.position = <span class="hljs-string">'absolute'</span>;
el.style.left = <span class="hljs-string">'-9999px'</span>; <span class="hljs-comment">// Move outside the screen to make it invisible</span>
<span class="hljs-built_in">document</span>.body.appendChild(el); <span class="hljs-comment">// Append the <textarea> element to the HTML document</span>
<span class="hljs-keyword">const</span> selected =
<span class="hljs-built_in">document</span>.getSelection().rangeCount > <span class="hljs-number">0</span> <span class="hljs-comment">// Check if there is any content selected previously</span>
? <span class="hljs-built_in">document</span>.getSelection().getRangeAt(<span class="hljs-number">0</span>) <span class="hljs-comment">// Store selection if found</span>
: <span class="hljs-literal">false</span>; <span class="hljs-comment">// Mark as false to know no selection existed before</span>
el.select(); <span class="hljs-comment">// Select the <textarea> content</span>
<span class="hljs-built_in">document</span>.execCommand(<span class="hljs-string">'copy'</span>); <span class="hljs-comment">// Copy - only works as a result of a user action (e.g. click events)</span>
<span class="hljs-built_in">document</span>.body.removeChild(el); <span class="hljs-comment">// Remove the <textarea> element</span>
<span class="hljs-keyword">if</span> (selected) { <span class="hljs-comment">// If a selection existed before copying</span>
<span class="hljs-built_in">document</span>.getSelection().removeAllRanges(); <span class="hljs-comment">// Unselect everything on the HTML document</span>
<span class="hljs-built_in">document</span>.getSelection().addRange(selected); <span class="hljs-comment">// Restore the original selection</span>
}
};
<span class="copy-code-btn">复制代码</span></code></pre><h2 class="heading" data-id="heading-6">使用react和typescript改写和优化一下</h2>
<ul>
<li>学习了上面的文章,结合产品的需求改写一下相关代码。</li>
<li>思路
<ul>
<li>1、首先创建一个 targetNode,设置绝对布局,赢藏我们的元素</li>
<li>2、document.getSelection() 已经由 window.getSelection() 替代了,具体流程如上</li>
<li>3、创建一个 result 标记能否能正常 使用剪贴功能,不能的返回 false</li>
<li>4、删除这个 targetNode</li>
</ul>
</li>
</ul>
<pre><code class="hljs js copyable" lang="js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createNode</span>(<span class="hljs-params">text</span>) </span>{
<span class="hljs-keyword">const</span> node = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>);
node.innerText = text;
node.style.cssText = <span class="hljs-string">'position:absolute; top: 0; left: 0; height:0; width:0; pointer-events: none;'</span>;
<span class="hljs-built_in">document</span>.body.appendChild(node);
<span class="hljs-keyword">return</span> node;
}
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">copyMe</span>(<span class="hljs-params">text</span>) </span>{
<span class="hljs-keyword">const</span> targetNode = createNode(text);
<span class="hljs-keyword">const</span> range = <span class="hljs-built_in">document</span>.createRange();
<span class="hljs-keyword">const</span> selection = <span class="hljs-built_in">window</span>.getSelection()!;
<span class="hljs-keyword">const</span> selected = selection.rangeCount > <span class="hljs-number">0</span>
? selection.getRangeAt(<span class="hljs-number">0</span>)
: <span class="hljs-literal">false</span>;
targetNode.focus(); <span class="hljs-comment">// focus 我们需要的文本</span>
range.selectNodeContents(targetNode);
<span class="hljs-keyword">if</span>(selected){
selection.removeAllRanges();
selection.addRange(range);
}
<span class="hljs-keyword">let</span> result;
<span class="hljs-keyword">try</span> {
result = <span class="hljs-built_in">document</span>.execCommand(<span class="hljs-string">'copy'</span>);
} <span class="hljs-keyword">catch</span> (e) {
result = <span class="hljs-literal">false</span>;
}
<span class="hljs-built_in">document</span>.body.removeChild(targetNode);
<span class="hljs-keyword">return</span> result;
}
<span class="copy-code-btn">复制代码</span></code></pre><h3 class="heading" data-id="heading-7">如何使用copyme</h3>
<pre><code class="hljs js copyable" lang="js"><span class="hljs-keyword">import</span> React, { Fragment } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> copyMe <span class="hljs-keyword">from</span> <span class="hljs-string">'utils/copyMe'</span>;
interface ItemProps {
value?: string | number;
}
<span class="hljs-keyword">const</span> Item: React.FC<ItemProps> = <span class="hljs-function"><span class="hljs-params">props</span> =></span> {
<span class="hljs-keyword">const</span> { value } = props;
<span class="hljs-keyword">const</span> copyme = <span class="hljs-function"><span class="hljs-params">()</span> =></span> {
alert(copyMe(value) ? <span class="hljs-string">'Copied!'</span> : <span class="hljs-string">'Failed!'</span>);
};
<span class="hljs-keyword">return</span> (
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">Fragment</span>></span>
{value && (
<span class="hljs-tag"><<span class="hljs-name">div</span>></span>
{value}
<span class="hljs-tag"><<span class="hljs-name">textarea</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{value}</span> <span class="hljs-attr">readOnly</span>></span><span class="hljs-tag"></<span class="hljs-name">textarea</span>></span>
<span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{copyme}</span>></span><span class="hljs-tag"></<span class="hljs-name">span</span>></span>
<span class="hljs-tag"></<span class="hljs-name">div</span>></span>
)}
<span class="hljs-tag"></<span class="hljs-name">Fragment</span>></span></span>
);
};
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Item;
<span class="copy-code-btn">复制代码</span></code></pre><h4 class="heading" data-id="heading-8">必要 api 参考</h4>
<ul>
<li><a target="_blank" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/getSelection" rel="nofollow noopener noreferrer">window/getSelection</a></li>
<li><a target="_blank" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Selection/getRangeAt" rel="nofollow noopener noreferrer">Selection/getRangeAt</a></li>
<li><a target="_blank" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Range/selectNodeContents" rel="nofollow noopener noreferrer">Range/selectNodeContents</a></li>
</ul>
<h2 class="heading" data-id="heading-9">原文参考</h2>
<ul>
<li><a target="_blank" href="https://hackernoon.com/copying-text-to-clipboard-with-javascript-df4d4988697f" rel="nofollow noopener noreferrer">hackernoon.com/copying-tex…</a></li>
</ul>
</div> <div class="image-viewer-box" data-v-78c9b824=""><!----></div>