整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

原生 js 实现点击按钮复制文本

作者:JavaScript前端(梓超)
注:此文章为头条号原创,特此声明!

一、原理分析

浏览器提供了 copy 命令 ,可以复制选中的内容

document.execCommand("copy")

如果是输入框,可以通过 select() 方法,选中输入框的文本,然后调用 copy 命令,将文本复制到剪切板

但是 select() 方法只对 <input> 和 <textarea> 有效,对于 <p> 就不好使

最后我的解决方案是,在页面中添加一个 <textarea>,然后把它隐藏掉

点击按钮的时候,先把 <textarea> 的 value 改为 <p> 的 innerText,然后复制 <textarea> 中的内容

二、代码实现

HTML 部分

按 Ctrl+C 复制代码

按 Ctrl+C 复制代码

JS 部分

 <script type="text/javascript">
 function copyText() {
 var text = document.getElementById("text").innerText;
 var input = document.getElementById("input");
 input.value = text; // 修改文本框的内容
 input.select(); // 选中文本
 document.execCommand("copy"); // 执行浏览器复制命令
 alert("复制成功");
 }
 </script>

亲测,Firefox 48.0,Chrome 60.0,IE 8 都能用

推荐阅读:

最好的JavaScript数据可视化库都在这里了

js 中原型和原型链深入理解

JavaScript基础知识系列:不再彷徨:完全弄懂JavaScript中的this

最好的JavaScript数据可视化库都在这里了

JavaScript基础知识系列:判断类型(上)

TML的作用

HTML是用来开发网页的,它是开发网页的语言

HTML的定义

全称HyperText Mark-up Language,超文本标记语言

标记就是标签

<标签名称></标签名称> 比如 <html></html> <h1></h1>等,标签大多数都是成对出现的。

超文本 两层含义:

  1. 因为网页中还可以有图片、视频、音频等内容(超越文本限制)
  2. 它还可以在网页中跳转到另一个网页,与世界各地主机的网页链接(超链接文本)

HTML的基本结构

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>网页标题</title>
    </head>
    <body>
        网页显示内容
    </body>
</html>

第一行<!DOCTYPE html>是文档声明

用来指定页面所使用的html的版本, 这里声明的是一个html5的文档

<html>...</html>标签是开发人员在告诉浏览器

整个网页是从<html>这里开始的,到</html>结束

也就是html文档的开始和结束标签

<head>...</head>标签用于定义文档的头部

是负责对网页进行设置标题、编码格式以及引入css和js文件的

<body>...</body>标签是编写网页上显示的内容

网页文件的后缀是.html, 一个html文件就是一个网页,html文件用编辑器打开显示的是文本,可以用文本的方式编辑它,如果用浏览器打开,浏览器会按照标签描述内容将文件渲染成网页

VS Code 安装

VS Code全拼是 Visual Studio Code 是由微软研发的一款免费、开源的跨平台代码编辑器

目前是前端(网页)开发使用最多的一款软件开发工具

下载网址: https://code.visualstudio.com/Download

选择对应的安装包进行下载:

安装一切默认

VS Code 的插件安装

  • Chinese(Simplified) Language Pack for VS Code 中文汉化包
  • open in browser 右击在浏览器打开html

常用的HTML标签

1 标签不区分大小写,但是推荐使用小写

2 根据标签的书写形式,标签分为双标签(闭合标签)和单标签(空标签) 2.1 双标签是指由开始标签和结束标签组成的一对标签,这种标签允许嵌套和承载内容,比如: div标签 2.2 单标签是一个标签组成,没有标签内容, 比如: img标签

标签的使用形式

  1. 成对出现的标签
  2. 标签的嵌套
  3. 单个出现的标签
  4. 带属性的标签


列表标签

  1. 无序列表标签(ul标签)
  2. 有序列表标签(ol标签)

网页效果

表格标签

<table>标签:表示一个表格

<tr>标签:表示表格中的一行

<td>标签:表示表格中的列

<th>标签:表示表格中的表头

属性设置

border: 1px solid black:设置边框和颜色

border-collapse: collapse:设置边框合并



网页效果

表单标签

表单用于搜集不同类型的用户输入的数据,然后可以把用户数据提交到web服务器

<form>标签 表示表单标签,定义整体的表单区域

一个表单中有很多信息组成,比如 姓名,爱好,地址等,这些内容有很多其他标签来承载

这些标签称为表单元素标签

网页效果

表单提交

表单用于搜集不同类型的用户输入的数据,然后可以把用户数据提交到web服务器

  • action属性 设置表单数据提交地址
  • method属性 设置表单提交的方式,一般有“GET”方式和“POST”方式, 不区分大小写

两种方式的区别:

  • “GET”方式 : 没有请求体
  • “POST”方式 : 有请求体

表单元素属性设置

  • name: 表单元素的名称,用于作为提交表单数据时的参数名
  • value: 表单元素的值,用于作为提交表单数据时参数名所对应的值

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<meta http-equiv="X-UA-Compatible" content="ie=edge">

<title>Document</title>

</head>

<body>

<!--

姓名 type="text" 定义单行文本输入框

密码 type="password" 定义密码输入框

性别 type="radio" 定义单选框

爱好 type="checkbox" 定义复选框

照片 type="file" 定义上传文件

个人描述 <textarea></textarea> 定义多行文本输入框

地址 <select></select> 定义下拉列表

提交 type="submit" 定义提交按钮

重置 type="reset" 定义重置按钮

按钮 type="button" 定义一个普通按钮

-->

<form action="http://192.168.1.106:8080" method="POST">

<label>姓名:</label>

<input type="text" name="username" >

<br>

<label>密码:</label>

<input type="password" name="password">

<br>

<label>性别:</label>

<input type="radio" name="sex" value="1">男

<input type="radio" name="sex" value="0">女

<br>

<label>爱好:</label>

<input type="checkbox" name="like" value="睡觉">睡觉

<input type="checkbox" name="like" value="吃饭">吃饭

<input type="checkbox" name="like" value="打豆豆">打豆豆

<br>

<label>照片:</label>

<input type="file" name="pic">

<br>

<label>个人描述:</label>

<textarea name="desc"></textarea>

<br>

<label>地址:</label>

<select name="addr">

<option value="1">北京</option>

<option value="2">上海</option>

<option value="3">广州</option>

<option value="4">深圳</option>

</select>

<br>

<input type="submit" value="提交">

<input type="reset" value="重置">

<input type="button" value="按钮">

</form>

</body>

</html>


点击提交:

可以看到服务器收到了请求报文。

一篇文章Stimulus:连接HTML和JavaScript的桥梁,实现简单的controller,并学习了Stimulus是如何连接HTML与JavaScript的。现在我们使用Stimulus来实现复制文本到粘贴板的按钮。

比如说,我们现在有一个需求,就是帮助用户生成密码,在密码旁边放置一个按钮,点击按钮后密码就被拷贝到粘贴板上了,这样就方便用户使用这个密码了。

打开public/index.html,修改body内容,填充一个简单的按钮,如下:

<div>
    PIN: <input type="text" value="1234" readonly>
    <button>Copy to Clipboard</button>
</div>



下一步,创建src/controllers/clipboard_controller.js,然后添加一个copy()方法:

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
    copy() {
    }
}

然后,给div添加data-controller=“clipboard”。只要是给元素添加了data-controller属性,Stimulus就会连接一个controller实例。

<div data-controller="clipboard">

我们还需要一个对输入框的引用,这样我们就可以在调用粘贴板API之前获取输入框的内容。给文本框添加data-clipboard-target=“source“:

PIN: <input data-clipboard-target="source" type="text" value="1234" readonly>

在controller中定义一个target,然后就可以通过this.sourceTarget访问文本框了。

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
    static targets = [ "source" ]
    
    copy() {
    }
}


解释一下这个targets:

当Stimulus加载你的controller类时,它会查看静态数组targets的字符串元素,对于每一个字符串,Stimulus会在controller中添加3个属性。在这里,对于“source”,会添加如下属性:

this.sourceTarget 在controller的域内的第一个source

this.sourceTargets 在controller的域内所有的source组成的一个数组

this.hasSourceTarget 在controller的域内是否有source


我们希望点击按钮时调用controller中的copy()方法,所以我们需要添加data-action=“clipboard#copy“

<button data-action="clipboard#copy">Copy to Clipboard</button>

你可以已经注意到在上面的动作描述符中省略了click->。那是因为Stimulus给button设置了click作为它默认的事件。


某些其他元素也有默认事件。下面是个全部列表:

元素

默认事件

a

click

button

click

details

toggle

form

submit

input

input

input type=“submit”

click

select

change

textarea

input

最终,在copy()方法中,我们获取输入框的内容,调用粘贴板API

copy() {
    navigator.clipboard.writeText(this.sourceTarget.value)
}


刷新页面,点击按钮,然后快捷键粘贴到Greet按钮前到输入框,可以看到1234。



到目前为止,在页面上同一时间只有一个controller实例。在页面上同时有一个controller的多个实例也是很正常的。


我们的controller是可以复用的,只要你需要在页面上添加复制内容的按钮,无论是哪个页面,只要把对应的属性值写好,我们的controller都是生效的。


还是上面的例子,再添加另外一个复制按钮:

<div data-controller="clipboard">
    PIN: <input data-clipboard-target="source" type="text" value="3737" readonly>
    <button data-action="clipboard#copy" class="clipboard-button">Copy to Clipboard</button>
</div>


刷新页面,验证一下两个复制按钮是否都生效。

我们再添加一个可以复制的元素,不用button,我们用a标签,

<div data-controller="clipboard">
    PIN: <input data-clipboard-target="source" type="text" value="6666" readonly>
    <a href="#" data-action="clipboard#copy" class="clipboard-button">Copy to Clipboard</a>
</div>



Stimulus允许我们使用任何元素,只要它设置了合适的data-action属性,就可以触发复制。

这个例子里,要注意一点,点击链接会使浏览器追踪a标签内的href属性跳转,可以取消这种默认行为,只需要在action中调用 event.preventDefault()就可以了。

copy(event) {
    event.preventDefault()    
    navigator.clipboard.writeText(this.sourceTarget.value)
}


还有另外一个方法,拷贝粘贴板上

copy(event) {
    event.preventDefault()    
    this.sourceTarget.select()
    document.execCommand("copy")
}


在本文中,我们看了一个在现实中把浏览器API包装在Stimulus的controller中的例子。还有一个controller的多个实例如何同时出现在页面上,我们还探索了actions和targets如何保持HTML和JavaScript的松散耦合。


下一篇文章,我们将优化一下这个复制粘贴板的功能,让它运行起来更加健壮。

Stimulus:浏览器不支持复制或者弱网条件下,怎么办?