在多个设备之间同步 JS 时间
我正在使用精彩的 reveal.js 库来创建 HTML 幻灯片.我唯一的问题是我需要它在多个设备之间进行同步.
I'm using the wonderful reveal.js library to create a HTML slideshow. My only problem is that I need it to synchronise across multiple devices.
目前我正在从服务器向时间发出 AJAX 请求,并为页面保留一个内部时钟.
At the moment I am making a AJAX request to the the time from the server and keep an internal clock for the page.
function syncTime() {
// Set up our time object, synced by the HTTP DATE header
// Fetch the page over JS to get just the headers
console.log("syncing time")
var r = new XMLHttpRequest();
r.open('HEAD', document.location, false);
r.send(null);
var timestring = r.getResponseHeader("DATE");
systemtime = new Date(timestring); // Set the time to the date sent from the server
}
虽然这可以让我在 1 秒左右的时间内获得准确度,但我需要做得更好.当幻灯片自动前进时,差异非常明显.
Whilst this gets me within 1 or so seconds of accuracy, I need to do better. The difference is really noticeable when the slideshow is auto advancing.
代码将在同一平台上运行,因此无需担心跨浏览器兼容性.
The code is going to be running all on the same platform, so cross-browser compatibility is nothing to worry about.
这是我整理出来的
有什么想法吗?
推荐答案
换一种方法怎么样:谁在乎时间?(您不会可靠地将系统时钟与 JavaScript 同步.)
How about a different approach: who cares about time? (You're not going to reliably sync the system clock with JavaScript.)
改为使用 Node 服务器和 socket.io 在您的客户推进幻灯片时进行同步.不是客户端决定何时前进,而是服务器告诉他们前进.
Instead, use a Node server with socket.io to synchronize when your clients advance the slideshow. Instead of the clients deciding when to advance, the server tells them to.
这种方法带来了额外的好处,即能够在幻灯片运行时手动调整幻灯片.在下面的示例中,我添加了一个 下一个 按钮,该按钮使所有连接的客户端立即前进到下一张幻灯片.
This approach comes with the added bonus of being able to manually fiddle with the slideshow while it's running. In the example that follows, I've added a Next button that causes all connected clients to immediately advance to the next slide.
var express = require('express')
, app = express.createServer()
, io = require('socket.io').listen(app)
, doT = require('dot')
, slide = 0
, slides = [
'http://placekitten.com/700/400?image=13',
'http://placekitten.com/700/400?image=14',
'http://placekitten.com/700/400?image=15',
'http://placekitten.com/700/400?image=16',
'http://placekitten.com/700/400?image=1',
'http://placekitten.com/700/400?image=2',
'http://placekitten.com/700/400?image=3',
'http://placekitten.com/700/400?image=4',
'http://placekitten.com/700/400?image=5',
'http://placekitten.com/700/400?image=6',
'http://placekitten.com/700/400?image=7',
'http://placekitten.com/700/400?image=8',
'http://placekitten.com/700/400?image=9',
'http://placekitten.com/700/400?image=10',
'http://placekitten.com/700/400?image=11',
'http://placekitten.com/700/400?image=12',
];
app.listen(70); // listen on port 70
app.register('.html', doT); // use doT to render templates
app.set('view options', {layout:false}); // keep it simple
doT.templateSettings.strip=false; // don't strip line endings from template file
app.get('/', function(req, res) {
res.render('index.html', { slide: slide, slides: slides });
});
app.post('/next', function(req, res) {
next();
res.send(204); // No Content
});
setInterval(next, 4000); // advance slides every 4 seconds
function next() {
if (++slide >= slides.length) slide = 0;
io.sockets.emit('slide', slide);
}
views/index.html
此文件作为 doT 模板处理.
<!DOCTYPE html>
<html>
<head>
<title>Synchronized Slideshow</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
var curslide = {{=it.slide}}; // the slide the server is currently on.
$(function() {
$('#slide' + curslide).css('left',0);
$('#next').click(function() {
$.post('/next');
});
});
var socket = io.connect('http://localhost:70');
socket.on('slide', function(slide) {
$('#slide' + curslide).animate({left:-700}, 400);
$('#slide' + slide).css('left',700).show().animate({left:0}, 400);
curslide = slide;
});
</script>
<style>
#slideshow, .slide { width:700px; height:400px; overflow:hidden; position:relative; }
.slide { position:absolute; top:0px; left:700px; }
</style>
</head>
<body>
<div id="slideshow">
{{~it.slides :url:i}}
<div id="slide{{=i}}" class="slide"><img src="{{=url}}"></div>
{{~}}
</div>
<button id="next">Next ></button>
</body>
</html>
将这两个文件复制到一个文件夹中,然后运行
Copy these two files into a folder, then run
$ npm install express socket.io dot
$ node app.js
并在几个不同的窗口中导航到 http://localhost:70
,然后看看魔法.
and navigate to http://localhost:70
in several different windows, then see the magic.
相关文章