JS 代码块复制按钮

JS 代码块复制按钮

之前在文章WordPress 代码高亮方案:Prism中实现了代码高亮功能,但是没有实现其他细节,现在为其添加一个点击复制的按钮。点击复制的基本逻辑如下:

  • 为每个代码块添加一个复制按钮
  • 为复制按钮添加click事件
  • 获取对应的代码
  • 添加 <textarea> DOM节点,将获取的代码写入
  • 选中textarea内的代码
  • 复制选中的内容
  • 删除节点

实现代码

JS 代码:

$(function() {
	//添加复制按钮
	$("pre[class*='language-']").prepend("<div class='copy_code'>复制</div>");
	
	//为复制按钮添加click事件
	$(".copy_code").on("click", function() {
		//初始化
		$("textarea").remove("#targetId");
		
		//获取对应的代码
		var codePre = $(this).next("code");
		var codeText = codePre[0].textContent;
		
		//添加 <textarea> DOM节点,将获取的代码写入
		var target = document.createElement("textarea");
		target.style.position = "absolute";
		target.style.left = "-9999px";
		target.style.top = "0";
		target.id = "targetId";
		codePre.append(target);
		target.textContent = codeText;

		//选中textarea内的代码
		target.focus();
		target.setSelectionRange(0, target.value.length);

		// 复制选中的内容
		document.execCommand("copy");
		
		//删除添加的节点
		$("textarea").remove("#targetId");
		$(this).html("成功").css("background", "rgba(100,100,100,.8)");
		var thisCopied = $(this);
		setTimeout(function() {
			thisCopied.html("复制").css("background", "").css("color", "");
		}, 2000)
	})
})

CSS 样式

pre[class*="language-"]:hover .copy_code {
	background: rgba(200, 200, 200, .9);
}

.copy_code {
	line-height: 1.6;
	vertical-align: middle;
	color: #fff;
	padding: 0 .5em;
	position: absolute;
	right: .5em;
	top: .5em;
	border-radius: 3px;
	background: rgba(220, 220, 220, .9);
	z-index: 2;
	transition: .5s;
}

.copy_code:hover {
	background: rgba(200, 200, 200, .9);
	cursor: pointer;
}

.copy_code:active {
	background: rgba(170, 170, 170, .9);
}

存在的bug

由于代码块中没有设置强制换行,如果宽度超出后出现拖拉条,拖动时copy按钮会随之移动:

解决方案是将copy按钮放在pre[class*="language-"]之外,此处未实现。

参考:click-button-copy-to-clipboard-using-jquery