[英]Get HTML elements from a document in the server and show them dynamically in the client
I am making an application for showing a synchronized HTML5 slideshow to about 50 spectators in a wireless LAN with no internet access. 我正在申请在没有互联网接入的无线局域网中向大约50名观众展示同步的HTML5幻灯片。
I run a Node.js server in one of the computers and connect with the 50 clients via Socket.IO (Btw, only one of them controlls the presentation). 我在其中一台计算机上运行一个Node.js服务器,并通过Socket.IO与50个客户端连接(顺便说一句,只有其中一个控制演示文稿)。
The hardware is a domestic wireless 802.11b/g router and 50 mobile devices (tablets, netbooks, smartphones). 硬件是国内无线802.11b / g路由器和50个移动设备(平板电脑,上网本,智能手机)。
When the slideshow starts, it takes too long (about 10 minutes or more for a 5 MB slideshow) for the clients to see it, since the router has to send the complete slideshow to all the clients at the same time. 幻灯片启动时,客户端需要花费太长时间(大约10分钟或更长时间才能播放5 MB幻灯片),因为路由器必须同时向所有客户端发送完整的幻灯片。
<html>
<head>
<title>My Slideshow</title>
<script src="javascripts/slidesplayer.js"></script>
<link rel="stylesheet" href="/stylesheets/style.css">
</head>
<body>
<div id="slides-containter">
<div class="slide" id="slide_1">
<!--Contents such as images, text, video and audio sources -->
</div>
<div class="slide" id="slide_2">
<!--Contents -->
</div>
<!--A bunch of slides here-->
</div>
<script>
// Here I load the slides
</script>
</body>
</html>
At the beginning, I would like to load the slides-container
element completely empty. 一开始,我想将slides-container
元素加载完全为空。
Then, as I advance through the slideshow, I'd like to GET from the server the div
representing the next slide, and append it to the DOM so that only when that is done, the client starts to download the pictures and othet stuff only for that slide (thus, decreasing significantly my network overload). 然后,我通过幻灯片前进,我想从服务器获取div
表示下一个幻灯片,并追加到DOM所以,只有当做到这一点,客户端开始下载图片和othet东西只对于那张幻灯片 (因此,显着减少了我的网络过载)。
Another relevant fact is that the slideshow (including the slidesplayer.js
) is automatically generated from an external software that parses PowerPoint presentations to this HTML5 format and that we will use a lot of presentations that are already made in PowerPoint. 另一个相关的事实是幻灯片(包括slidesplayer.js
)是从外部软件自动生成的,该软件将PowerPoint演示文稿解析为HTML5格式,并且我们将使用许多已在PowerPoint中制作的演示文稿。
My first impression is that I should accomplish this by using jQuery-ajax, but I don't know exactly how to do it the good way, since my idea is just copying the div.slide
elements in separate files. 我的第一印象是我应该通过使用jQuery-ajax来实现这一点,但我不知道如何以好方式完成它,因为我的想法只是将div.slide
元素复制到单独的文件中。
Update: This answer suggests using jQuery for DOM manipulation before displaying. 更新: 这个答案建议在显示之前使用jQuery进行DOM操作。 It seems that jQuery requests the resources everytime you manipulate a DOM object, even if it is not inserted into your current DOM. 似乎jQuery每次操作DOM对象时都会请求资源,即使它没有插入到当前的DOM中。 So, one possible solution would be working only with strings. 因此,一种可能的解决方案是仅使用字符串。 You can see more about this issue in this and this questions. 你可以看到更多的关于这个问题在这个和这个问题。
One solution would be to treat this as a front-end solution. 一种解决方案是将其视为前端解决方案。 The front-end should arguably only eat as much as it can take at any one time. 前端应该可以说只吃任何时候都可以吃的东西。
I'm assuming it's external resources (imagery etc) as opposed to the slideshow markup itself that's making up the most of those 5MB, in which case the DOM should not attempt to call those resources until they are necessary. 我假设它是外部资源(图像等),而不是幻灯片标记本身构成5MB的大部分,在这种情况下,DOM不应该尝试在需要之前调用这些资源。
I would suggest serving the whole slide document to an ajax call but only introducing the markup to each slide as it is called. 我建议将整个幻灯片文档提供给ajax调用,但只在每个幻灯片调用时引入标记。 Something like this: 像这样的东西:
$.ajax('path/to/slides', {
async: false,
complete: function ajaxCallback(slidesDOM){
// Pull out the individual slides from your slideshow HTML
$slides = $(slidesDOM).find('.slide');
// For each of these...
$slides.each(function prepareSlide(){
// Store a reference to the slide's contents
var $slideContent = $($(this).html());
// Empty the contents and keep only the slide element itself
var $slideWrapper = $(this).empty();
$slideWrapper
// Put the slide where you want it
.appendTo('.slidesContainer')
// And attach some kind of event to it
// (depending on how your slideware works, you might want to bind this elsewhere)
.on('focus', function injectContent(){
// Put the content in — NOW external resources will load
$slideWrapper.append($slideContent);
// Unbind this function trigger
$slideWrapper.off('focus', injectContent);
});
})
}
});
1) You shouldn't be streaming payloads with SocketIO. 1)您不应该使用SocketIO来传输有效负载。 Socket is made for low-load. 插座是为低负载而制造的。 If you need to transmit en-masse, I'd recommend using a standard HTTP AJAX request. 如果您需要传输en-masse,我建议使用标准的HTTP AJAX请求。 Then, you can use Socket.IO to control which slide you are on. 然后,您可以使用Socket.IO来控制您所在的幻灯片。
2) Try AngularJS. 2)尝试AngularJS。 They've basically done all the thinking for you regarding view switching (which is essentially what you are doing). 他们基本上已经完成了关于视图切换的所有想法(这基本上就是你在做什么)。 They have a great tutorial, which helps alot. 他们有一个很棒的教程,这很有帮助。
3) To simplify you Socket calls, I'd recommend using ConversationJS both client and server side. 3)为简化Socket调用,我建议在客户端和服务器端使用ConversationJS。
As I said in the question, manipulating DOM elements will cause the browser to download the resources, even if you don't insert the elements that use that resources in your DOM. 正如我在问题中所说,操纵DOM元素将导致浏览器下载资源,即使您没有在DOM中插入使用该资源的元素。
In my case, the best solution I could make was to use some sort of lazy loading at least for the img
tags (but it could be easily extended for other tags, such as audio
and video
). 在我的情况下,我可以做的最好的解决方案是至少对img
标签使用某种延迟加载 (但它可以很容易地扩展到其他标签,如audio
和video
)。
What I did was replacing replacing the src
attribute with another name ( xsrc
in this case) and adding a custom empty src
attribute to all img tags. 我所做的是用另一个名称替换src
属性(在本例中为xsrc
),并为所有img标签添加一个自定义的空src
属性。
<img id="someImg" src="#" xsrc="foo.png"></img>
Then, with jQuery I changed the src
attribute value to that of xsrc
whenever I needed to dowload the image. 然后,使用jQuery,每当我需要下载图像时,我将src
属性值更改为xsrc
值。
// When I want the image to be downloaded from the server
$('#someImg').attr( 'src' , $('#someImg').attr('xsrc') )
You can see more about the idea behind this in the questions I already mentioned ( this and this ). 您可以在我已经提到过的问题中看到更多关于这背后的想法( 这个和这个 )。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.