我正在尝试自学javascript,而且我显然还没有完全理解。
我想要的是一个盒子,当你点击它时,背景颜色会从黑色平滑变为某种颜色。为此,我创建了一个函数,该函数接受HSV值并以#rrggbb格式吐出一个字符串。因此,要淡入,我只需使用for循环将V值从0递增到100,增量为1。
我所拥有的是一个盒子,当你点击它时,它会暂停并改变我正在使用的背景颜色。我也记录了输出,并在最后用RGB十六进制值计算和更新一次。
所以,显然,我不了解在中间步骤刷新DOM所需的知识。我为此获得的所有搜索都提供了使用jQuery等的解决方案。这很好,我打算通过jQuery等人的方式,但首先,我想让这样的事情发挥作用,这样我就可以更彻底地了解幕后发生的事情。< / p>
代码在这里:http://codepen.io/anon/pen/QbzQJG
代码:
HTML:
<title>Color test</title>
<body>
<div id="colorbox" onclick="javascript:fadeIn()"></div>
<div id="console"></div>
</body>
CSS:
body {
background: #000;
color: #999;
}
#colorbox {
background: #000;
border: 1px solid #333;
width: 250px;
height: 250px;
margin: 0 auto;
}
使用Javascript:
var c = function() {
return ({
log: function(msg) {
consoleDiv = document.getElementById('console');
para = document.createElement('p');
text = document.createTextNode(msg);
para.appendChild(text);
consoleDiv.appendChild(para);
}
});
}();
function toRGB(H, S, V) {
S /= 100;
V /= 100;
var C = V * S;
H /= 60;
var X = C * (1 - Math.abs((H % 2) - 1));
var R = 0;
var G = 0;
var B = 0;
if (0 <= H && H < 1) {
R = C;
G = X;
B = 0;
} else if (1 <= H && H < 2) {
R = X;
G = C;
B = 0;
} else if (2 <= H && H < 3) {
R = 0;
G = C;
B = X;
} else if (3 <= H && H < 4) {
R = 0;
G = X;
B = C;
} else if (4 <= H && H < 5) {
R = X;
G = 0;
B = C;
} else if (5 <= H && H < 6) {
R = C;
G = 0;
B = X;
} else {
R = 0;
G = 0;
B = 0;
}
var m = V - C;
R = Math.round(255 * (R + m)).toString(16);
R.length < 2 ? R = "0" + R : R = "" + R;
G = Math.round(255 * (G + m)).toString(16);
G.length < 2 ? G = "0" + G : G = "" + G;
B = Math.round(255 * (B + m)).toString(16);
B.length < 2 ? B = "0" + B : B = "" + B;
var RGB = "#" + R + G + B;
return RGB;
}
function pause(milliseconds) {
var dt = new Date();
while ((new Date()) - dt <= milliseconds) { /* Do nothing */ }
}
function fadeIn() {
var colorbox = document.querySelector("#colorbox");
for (var i = 0; i <= 100; i++) {
colorbox.style.backgroundColor = toRGB(150, 80, i);
c.log(toRGB(150, 80, i));
pause(10);
}
}
有什么想法吗?
答案 0 :(得分:2)
您的问题在于理解浏览器中的事件流(以及一般的JS)。 (标准)JavaScript作为单线程异步进程工作。因此,任何事情发生在&#34;之间&#34;你的代码,你需要以某种方式返回执行到调用上下文。嵌套在JavaScript代码中的调用堆栈中以及当您希望&#34;看到&#34;时,这是真的。代码在浏览器窗口中的效果。
您的问题是pause
暂停任何事情。它忙着等待。您需要将控制权返回给浏览器。
你可以实现这样的目标:
function fadeIn() {
var colorbox = document.querySelector("#colorbox");
var i = 0;
var interval = setInterval(function() {
if(i > 100) {
clearInterval(interval);
return;
}
colorbox.style.backgroundColor = toRGB(150, 80, i);
c.log(toRGB(150, 80, i));
i++
}, 10);
}
此解决方案中不需要 pause
。
答案 1 :(得分:1)
您的传递功能可使处理器保持忙碌状态。由于JavaScript是单线程和基于事件的,因此在代码运行时不会更新DOM。通过使用setTimeout
暂停执行而不是繁忙的循环,您可以在更改之间进行DOM更新,从而显示您的淡化效果。
在这种情况下,fadeIn
的代码如下所示:
function fadeIn(i) {
if (i >= 100) {return;}
var colorbox = document.querySelector("#colorbox");
colorbox.style.backgroundColor = toRGB(150, 80, i);
c.log(toRGB(150, 80, i));
setTimeout(function(){fadeIn(i + 1);},10);
}
使用此代码,您的HTML调用应为fadeIn(0)
。
关于JavaScript的单线程模型的更广泛的解释可以在this回答中找到。
代码的代码堆的分叉,改进版本为here。
答案 2 :(得分:0)
你过度复杂了。您应该使用CSS转换,只需添加/删除一个类。因此,对于#colorbox
,您应该添加transition
属性:
#colorbox {
background: #000;
border: 1px solid #333;
width: 250px;
height: 250px;
margin: 0 auto;
-webkit-transition: all 500ms ease;
-moz-transition: all 500ms ease;
-ms-transition: all 500ms ease;
-o-transition: all 500ms ease;
transition: all 500ms ease;
}
然后让我们说你有一个班级.new-bckgr
:
.new-bckgr {
background: #76430; /* or whatever colour you want */
}
现在你需要做的就是这样:
$("#colorbox").on('click', function(){
$(this).addClass('new-backgr');
});
然而,你会顺利地从黑色渐变到你在.new-bckgr
课程中的颜色。如果您删除该课程,它将淡出将恢复为黑色。