今天来优化 Day24 做的色码挑战器,主要增加的功能如下:
因为要多显示一个色码表示法,将排版做了些微调整,改成下图的样子
这次学习的主要一个重点是复制功能,在浏览器中主要有三个方法可以实作复制功能,之後的实作会先采用第一种方法
Document.execCommand
document.execCommand('copy')
执行复制p
元素的方式const get = (text) => document.querySelector(text);
const p = get('p');
p.addEventListener('click', function() {
// 产生 range 物件
const range = document.createRange();
// 选取p节点作为range物件的内容
range.selectNode(p);
// 产生 selection 物件
const selection = window.getSelection();
// 清除选取范围
selection.removeAllRanges();
// 将选取到内容放入selection物件中
selection.addRange(range);
// 执行复制
document.execCommand('copy');
// 清除
selection.removeAllRanges();
})
Clipboard API
navigator.clipboard
Clipboard Event
认识有哪些方法可以对浏览器中的元素进行复制後,就开始来练习吧~
<!-- 显示颜色的区域 -->
<section class="display">
<!--总共有三个与下面同样结构的div -->
<div class="hex">
<div class="colorpad"></div>
<p class="colorCode">#808080</p>
</div>
<!--略 -->
</section>
<!-- 可以滑动slider的区域 -->
<section class="slider">
<!--总共有四个与下面同样结构的div:代表R/G/B/A的slider-->
<div class="alpha-group">
<span>A</span>
<input type="range" min="0" max="1" step="0.01" value="0.5" class="alpha">
<span class="range">0.5</span>
</div>
<!--略 -->
</section>
由於要增加 RGBA 的显示,我将原本的displayValue
函式拆解成两个函式:
displayDigit
: 负责 slider 中 R/G/B/A 个别数值显示displayColorCode
: 负责不同色码的显示这里会拆出来也是在更改的过程中,发现当我在添加 RGBA 的显示时,即便不是拖曳透明度的 slider,数值也会跟着做变化,见识到不必要的耦合现象!!!
其他的逻辑部分和 Day24 的实作没有太大的区别,所以以下直接看程序码
// 转换数值
function rgbToHex(R,G,B) {
const hexDigit = [R, G, B].map( item => {
return Number(item).toString(16).padStart(2, '0')
}).join('');
return '#'+ hexDigit;
}
// 显示 slider 个别数值
function displayDigits(e) {
const currentValue = e.target.value;
const alphaValue = currentValue;
e.target.nextElementSibling.innerHTML = currentValue;
}
// 显示颜色的不同表示法
function displayColorCode() {
const hexValue = (rgbToHex(red.value, green.value, blue.value)).toUpperCase();
const hexIndicator = get('.hex').children[1];
const rgbIndicator = get('.rgb').children[1];
const rgbaIndicator = get('.rgba').children[1];
hexIndicator.innerHTML = hexValue;
rgbIndicator.innerHTML = `RGB(${red.value},${green.value},${blue.value})`;
rgbaIndicator.innerHTML = `RGBA(${red.value},${green.value},${blue.value},${alpha.value})`;
}
//改变圆形图的颜色
function changeColor() {
const hexColorPad = get('.hex').children[0];
const rgbColorPad = get('.rgb').children[0];
const rgbaColorPad = get('.rgba').children[0];
hexColorPad.style.backgroundColor = `rgb(${red.value},${green.value},${blue.value})`;
rgbColorPad.style.backgroundColor = `rgb(${red.value},${green.value},${blue.value})`;
rgbaColorPad.style.backgroundColor = `rgba(${red.value},${green.value},${blue.value}, ${alpha.value})`;
}
//对 slider绑定事件监听器
rangeSliders.forEach(rangeSlider => {
//监听并改变RGB个别代码
rangeSlider.addEventListener('mousemove', displayDigits);
//监听并改变所有色码表示法
rangeSlider.addEventListener('mousemove', displayColorCode);
//监听并改变背景颜色
rangeSlider.addEventListener('mousemove', changeColor);
})
copy函式
changeDisplay函式
//做复制的功能
const buttons = getAll('.colorCode');
function copy() {
const range = document.createRange();
range.selectNode(this);
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
document.execCommand('copy');
selection.removeAllRanges();
}
// 改变颜色和文字内容
function changeDisplay(e){
e.target.style.backgroundColor = `rgb(247,157,128)`;
e.target.innerHTML = `复制好色码罗~`;
reset(e);
}
// 两秒後会回复到先前的状态
function reset(e){
setTimeout(()=> {
e.target.style.backgroundColor = `rgb(78,199,207)`;
displayColorCode();
}, 2000)
}
//对按钮绑定事件监听
buttons.forEach(button => {
button.addEventListener('click', copy);
button.addEventListener('click', changeDisplay);
});
完成~~~codepen连结
一开始只是为了回应馒头大大的一句话,想不到因而学习到浏览器的复制功该如何实作,也在增加功能的过程中再次体会到拆函式的重要性,不好好将函式拆好的下场就是改了 A 动了B,不断有出其不意的惊喜(令人崩溃的那种XD)
透过观察线上的色码转换器所包含的功能,想想这些功能是怎麽实作出来的,再逐步找相应语法尝试的过程真的很有趣~
谢谢神队友的修改建议和提问~~
参考资料:
RGBA and Hex Color Converter
剪贴簿复制操作
那些被忽略但很好用的 Web API / Clipboard
这应该是这次参赛的最後作品了 来挑战用jQuery做一个ToDoList 首先先写简单的架构 一个i...
玉山竞赛心得 从朋友口中得知玉山银行和趋势科技举办了中文手写字辨识的比赛,於是我们召集资策会夥伴们组...
是说在社群到处都在爆雷的《鱿鱼游戏》,我进度第一集,好想弃赛来追剧(我就废 然後谢谢没看鱿鱼游戏,...
鬼故事 - 不是,你偷这些干嘛 Credit: System32Comics 灵感来源:UCCU H...
建立一个放资料的地方,统一读取和写入这样比较方便 dataCenter.js const GetIn...