效果圖:
動畫實現的方案是縮減上方div的高度帶動整體上滑,然後用Js操作dom將最上方的div移到最下方。
主要css:
.continer {
display: flex;
justify - content: center;
align - items: center;
font - size: 40 px;
}
.scroll {
width: 100 px;
height: 100 px;
position: relative;
overflow: hidden;
display: inline - block;
border: 1 px solid gray;
}
.scroll span {
display: flex;
height: 100 px;
width: 100 px;
text - align: center;
font - size: 40 px;
box - sizing: border - box;
justify - content: center;
align - items: center;
}
.bar {
position: relative;
top: -200 px;
}
@keyframes close {
0 % {
height: 100 px;
}
100 % {
height: 0 px;
}
}
頁面主要部分:
<div class="continer">
<div id="scroll6"></div>
<div id="scroll5"></div>:
<div id="scroll4"></div>
<div id="scroll3"></div>:
<div id="scroll2"></div>
<div id="scroll1"></div>
</div>
Js根據時間動態生成dom方法:
var timeArray = [9, 5, 9, 5, 13, 2];
// 生成dom結點
function init_dom(date) {
var s = [date.getHours(), date.getMinutes(), date.getSeconds()].reduce(function(total, item) {
return total + (item > 9 ? item : "0" + item);
}, "");
var scrollDiv, barDiv, span, i, j;
var columns = [],
col, s_num;
// 計算每一列的值
for (i = 0; i < timeArray.length; i++) {
col = [], s_num = parseInt(s[timeArray.length - i - 1]);
for (j = 0; j <= timeArray[i]; j++) {
col.push((s_num - 1 + j + timeArray[i]) % (timeArray[i] + 1) % 10);
}
// 對小時進行特殊處理
if (i === 4 && parseInt(s[0]) >= 2) {
col = col.slice(10).concat(col.slice(0, 10));
}
if (i === 5) {
for (j = 0; j <= timeArray[i]; j++) {
col.push((s_num - 1 + j + timeArray[i]) % (timeArray[i] + 1));
}
}
columns.push(col);
}
for (i = 0; i < columns.length; i++) {
scrollDiv = document.getElementById("scroll" + (i + 1));
scrollDiv.innerHTML = "";
scrollDiv.className = "scroll";
barDiv = document.createElement("div");
barDiv.className = "bar";
for (j = 0; j < columns[i].length; j++) {
span = document.createElement("span");
span.innerHTML = columns[i][j];
barDiv.appendChild(span);
}
scrollDiv.appendChild(barDiv);
}
};
滾動實現與進位觸發:
// 啓動方法;
function scroll() {
var scrollDiv = document.getElementById("scroll1");
SI = setInterval(function() {
var dom = scrollDiv.children[0].children[0];
dom.style.animation = "close 0.5s linear";
if (scrollDiv.children[0].children[3].innerHTML == "0") {
tickSec(1);
}
dom.addEventListener("animationend", function(event) {
var ev = event || window.event;
var target = ev.target;
var node = document.createElement("span");
node.innerHTML = target.innerHTML;
target.parentNode.removeChild(target);
scrollDiv.children[0].appendChild(node);
})
}, 1000)
};
// 觸發器
function tickSec(index) {
var scrollDiv = document.getElementById("scroll" + (index + 1));
var dom = scrollDiv.children[0].children[0];
dom.style.animation = "close 0.5s linear";
if (index < timeArray.length - 1 && scrollDiv.children[0].children[3].innerHTML == "0") {
tickSec(index + 1);
}
dom.addEventListener("animationend", function(event) {
var ev = event || window.event;
var target = ev.target;
var node = document.createElement("span");
node.innerHTML = target.innerHTML;
scrollDiv.children[0].removeChild(target);
scrollDiv.children[0].appendChild(node);
})
}
由於獲取的時間與系統當前時間仍有1000ms以內的差值,所以還要有用來糾正時間差值的啓動方法:
// 啓動
function start() {
// 毫秒差糾正
var date = new Date();
var pad = 1000 - date.getMilliseconds();
var st = setTimeout(function() {
scroll();
clearTimeout(st);
}, pad)
init_dom(new Date(date.getTime() + pad));
}
以上就實現了基本的滾動樣式實現;
但值得注意的是,當瀏覽器最小化或者頁面不可見時,定時程序是停止運行的,所以會出現時間與當前時間並不匹配的情況。
這可以通過監聽頁面的顯隱解決,代碼如下:
// 設置隱藏屬性和改變可見屬性的事件的名稱
var hidden, visibilityChange;
if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
hidden = "hidden";
visibilityChange = "visibilitychange";
} else if (typeof document.msHidden !== "undefined") {
hidden = "msHidden";
visibilityChange = "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
hidden = "webkitHidden";
visibilityChange = "webkitvisibilitychange";
}
// 處理頁面可見屬性的改變
document.addEventListener(visibilityChange, function() {
clearInterval(SI);
start();
}, false);
完整代碼更新地址:github地址