繁体   English   中英

从服务器中的文档中获取HTML元素,并在客户端中动态显示它们

[英]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标签使用某种延迟加载 (但它可以很容易地扩展到其他标签,如audiovideo )。

我所做的是用另一个名称替换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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM