我目前正在为我的LED开发Web界面。所以我想有 3 个滑块,从中我可以向我的控制器发送十六进制值。
这是我到目前为止所拥有的:
<div class="main">
<div class="slideContainer">
<input type="range" class="slider" value="0" min="0" max="255" step="1" id="sliderRed" style="background: linear-gradient(to right, black 0%, red 70%);">
</div>
<div class="slideContainer">
<input type="range" class="slider" value="0" min="0" max="255" step="1" id="sliderGreen" style="background: linear-gradient(to right, black, green 70%);">
</div>
<div class="slideContainer">
<input type="range" class="slider" value="0" min="0" max="255" step="1" id="sliderBlue" style="background: linear-gradient(to right, black, blue 70%);">
</div>
</div>
和 JS 以获取我可以发送到控制器的十六进制值:
sliderRed.oninput = function () {
var red = sliderRed.value;
var green = sliderGreen.value;
var blue = sliderBlue.value;
color(red, green, blue);
}
sliderGreen.oninput = function () {
var red = sliderRed.value;
var green = sliderGreen.value;
var blue = sliderBlue.value;
color(red, green, blue);
}
sliderBlue.oninput = function () {
var red = sliderRed.value;
var green = sliderGreen.value;
var blue = sliderBlue.value;
color(red, green, blue);
}
function color(r, g, b) {
console.log(rgbToHex(r, g, b));
}
function rgbToHex(r, g, b) {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
我从上面的代码中得到的结果与我想要得到的#000000
和#ffffff
之间的值并不接近。 相反,如果我移动滑块,我会得到类似#86122240
的值,即使如果我从按钮输入静态值,函数color()
确实有效。
您正在尝试将 rgb 值作为字符串推送到rgbToHex()
函数。只需先使用 parseInt(( 函数在color()
函数中将它们转换为整数,然后将转换后的 rgb 值发送到rgbToHex()
函数。
此外,所有三个输入侦听器都在做同样的事情,因此只需创建一个名为 say、assignRGB()
的单独函数,并在调用这三个滑块中的任何一个输入事件时调用该函数。
还可以通过使用 querySelectorAll(( 方法来检索所有三个输入并将输入侦听器添加到每个输入,从而进一步清理代码。
检查并运行以下代码片段以获取上述方法的实际示例:
const rgbSliders = document.querySelectorAll('.slider');
function assignRGB() {
var red = sliderRed.value;
var green = sliderGreen.value;
var blue = sliderBlue.value;
color(red, green, blue);
}
rgbSliders.forEach(function(slider){
slider.addEventListener('input', assignRGB);
});
function color(r, g, b) {
const x = parseInt(r);
const y = parseInt(g);
const z = parseInt(b);
console.log(rgbToHex(x,y,z));
}
function rgbToHex(r, g, b) {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
<div class="main">
<div class="slideContainer">
<input type="range" class="slider" value="0" min="0" max="255" step="1" id="sliderRed" style="background: linear-gradient(to right, black 0%, red 70%);">
</div>
<div class="slideContainer">
<input type="range" class="slider" value="0" min="0" max="255" step="1" id="sliderGreen" style="background: linear-gradient(to right, black, green 70%);">
</div>
<div class="slideContainer">
<input type="range" class="slider" value="0" min="0" max="255" step="1" id="sliderBlue" style="background: linear-gradient(to right, black, blue 70%);">
</div>
</div>
输入元素的.value
属性将始终返回一个字符串。
在JavaScript中,+
可以添加数字,也可以连接字符串。
这就是脚本这一部分的问题:
((1 << 24) + (r << 16) + (g << 8) + b)
r
、g
和b
是字符串。 移位运算符将它们转换为实数,因此(r << 16)
和(g << 16)
将产生正确的值。
但是还有b
...
如果您尝试"添加"两个变量,其中一个是字符串,则结果也将是一个字符串。
((1 << 24) + (r << 16) + (g << 8) + b)
本质上是:
(<number> + <number> + <number> + <string>)
结尾为:
((<number> + <number> + <number>).toString() + <string>)
让我们添加一些数字(实际上是脚本中的字符串(->r = g = b = "1"
:
/*1*/ (("1" << 24) + ("1" << 16) + ("1" << 8) + "1")
/*2*/ (16777216 + 65536 + 256 + "1")
/*3*/ (16843008 + "1")
/*4*/ ("16843008" + "1")
/*5*/ "168430081"
现在让我们用一个代码片段和你的公式来测试这个假设:
console.log((("1" << 24) + ("1" << 16) + ("1" << 8) + "1").toString(16).slice(1));
tl;dr:
将r
、g
和b
的值转换为实际数字,然后再在公式中使用它们
console.log(((1 << 24) + (1 << 16) + (1 << 8) + 1).toString(16).slice(1));
工作示例:
sliderRed.oninput = function() {
var red = sliderRed.value;
var green = sliderGreen.value;
var blue = sliderBlue.value;
color(red, green, blue);
}
sliderGreen.oninput = function() {
var red = sliderRed.value;
var green = sliderGreen.value;
var blue = sliderBlue.value;
color(red, green, blue);
}
sliderBlue.oninput = function() {
var red = sliderRed.value;
var green = sliderGreen.value;
var blue = sliderBlue.value;
color(red, green, blue);
}
function color(r, g, b) {
r = parseInt(r, 10);
g = parseInt(g, 10);
b = parseInt(b, 10);
console.log(rgbToHex(r, g, b));
}
function rgbToHex(r, g, b) {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
<div class="main">
<div class="slideContainer">
<input type="range" class="slider" value="0" min="0" max="255" step="1" id="sliderRed" style="background: linear-gradient(to right, black 0%, red 70%);">
</div>
<div class="slideContainer">
<input type="range" class="slider" value="0" min="0" max="255" step="1" id="sliderGreen" style="background: linear-gradient(to right, black, green 70%);">
</div>
<div class="slideContainer">
<input type="range" class="slider" value="0" min="0" max="255" step="1" id="sliderBlue" style="background: linear-gradient(to right, black, blue 70%);">
</div>
</div>