[英]Get HTML elements from a document in the server and show them dynamically in the client
我正在申请在没有互联网接入的无线局域网中向大约50名观众展示同步的HTML5幻灯片。
我在其中一台计算机上运行一个Node.js服务器,并通过Socket.IO与50个客户端连接(顺便说一句,只有其中一个控制演示文稿)。
硬件是国内无线802.11b / g路由器和50个移动设备(平板电脑,上网本,智能手机)。
幻灯片启动时,客户端需要花费太长时间(大约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>
一开始,我想将slides-container
元素加载完全为空。
然后,我通过幻灯片前进,我想从服务器获取div
表示下一个幻灯片,并追加到DOM所以,只有当做到这一点,客户端开始下载图片和othet东西只对于那张幻灯片 (因此,显着减少了我的网络过载)。
另一个相关的事实是幻灯片(包括slidesplayer.js
)是从外部软件自动生成的,该软件将PowerPoint演示文稿解析为HTML5格式,并且我们将使用许多已在PowerPoint中制作的演示文稿。
我的第一印象是我应该通过使用jQuery-ajax来实现这一点,但我不知道如何以好方式完成它,因为我的想法只是将div.slide
元素复制到单独的文件中。
更新: 这个答案建议在显示之前使用jQuery进行DOM操作。 似乎jQuery每次操作DOM对象时都会请求资源,即使它没有插入到当前的DOM中。 因此,一种可能的解决方案是仅使用字符串。 你可以看到更多的关于这个问题在这个和这个问题。
一种解决方案是将其视为前端解决方案。 前端应该可以说只吃任何时候都可以吃的东西。
我假设它是外部资源(图像等),而不是幻灯片标记本身构成5MB的大部分,在这种情况下,DOM不应该尝试在需要之前调用这些资源。
我建议将整个幻灯片文档提供给ajax调用,但只在每个幻灯片调用时引入标记。 像这样的东西:
$.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)您不应该使用SocketIO来传输有效负载。 插座是为低负载而制造的。 如果您需要传输en-masse,我建议使用标准的HTTP AJAX请求。 然后,您可以使用Socket.IO来控制您所在的幻灯片。
2)尝试AngularJS。 他们基本上已经完成了关于视图切换的所有想法(这基本上就是你在做什么)。 他们有一个很棒的教程,这很有帮助。
3)为简化Socket调用,我建议在客户端和服务器端使用ConversationJS。
正如我在问题中所说,操纵DOM元素将导致浏览器下载资源,即使您没有在DOM中插入使用该资源的元素。
在我的情况下,我可以做的最好的解决方案是至少对img
标签使用某种延迟加载 (但它可以很容易地扩展到其他标签,如audio
和video
)。
我所做的是用另一个名称替换src
属性(在本例中为xsrc
),并为所有img标签添加一个自定义的空src
属性。
<img id="someImg" src="#" xsrc="foo.png"></img>
然后,使用jQuery,每当我需要下载图像时,我将src
属性值更改为xsrc
值。
// When I want the image to be downloaded from the server
$('#someImg').attr( 'src' , $('#someImg').attr('xsrc') )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.