【问题标题】:First attempt at lazy loading (deferring the load of embedded YouTube videos) - how can I do this more gracefully?第一次尝试延迟加载(延迟加载嵌入的 YouTube 视频)——我怎样才能更优雅地做到这一点?
【发布时间】:2013-02-19 11:16:38
【问题描述】:

昨天我决定改进我的网站加载 YouTube 视频的方式,仅在用户请求时才嵌入它们。有时,一个页面可能包含多达 30 个视频,而这需要很长时间才能加载。

这是我第一次尝试“延迟加载”任何东西的方法,我认为这很值得一问:

我可以做些什么来改进这一点?

我怎样才能让它更优雅一点?

这是否完全忽略了延迟加载的要点?

JSFiddle.

忽略样式,因为这在这里无关紧要。


其工作方式是首先在包含视频 ID 的页面上放置一个锚点:

<a href="#" data-video="FzRH3iTQPrk" class="youtube-video">

然后后面的 jQuery 循环遍历每个 a.youtube-video 并创建一个以视频缩略图作为背景的透明跨度:

$('a.youtube-video').each(function() {
    var videoId = $(this).attr('data-video');
    var videoThumbnail = "http://img.youtube.com/vi/" + videoId + "/0.jpg";

    var videoBackground = $('<span class="youtube-thumbnail"></span>');

    videoBackground.css({
        background:"#fff url('"+videoThumbnail+"') no-repeat"
    })
    ...

然后它会修改锚标记的样式(这里这样做是为了防止影响禁用 JavaScript 的浏览器):

    $(this).css({
        height:315,
        width:460,
        position:"relative",
        display:"block",
        textAlign:"center",
        color:"#fff",
        fontSize:26
    });

然后它通过将跨度添加到锚点来完成循环:

    $(this).text('Click to load video');
    $(this).append(videoBackground);
});

在锚点点击时加载嵌入的 YouTube 视频对象:

$('a.youtube-video').click(function(e) {
    e.preventDefault();
    var videoId = $(this).attr('data-video');
    var videoThumbnail = "http://img.youtube.com/vi/" + videoId + "/0.jpg";
    var videoEmbed = $('<object> ... </object>');      
        ...

最后通过将嵌入代码添加到锚的父级并删除锚:

    $(this).parent().append(videoEmbed);
    $(this).hide();
});

【问题讨论】:

  • 您在点击处理程序上使用 videoThumbnail 做什么?我正在做类似的事情,我遇到的一个问题是每个视频发生的重绘数量。你的经历可能会有所不同。另外,考虑在初次点击后自动播放视频,这样用户就不必点击两次。
  • 啊,我现在已经删除了。那是因为我最初只是使用小缩略图 - 点击时会扩大图像并用更大的缩略图替换它。
  • 你看过 youtube 提供的用于方便嵌入视频的 API,它们有一个 jS api(developers.google.com/youtube/js_api_reference) 和一个 iframe api(developers.google.com/youtube/iframe_api_reference)
  • iFrame 的问题在于它会显示在 iFrame 本身生成的控制台错误。但是,我不知道这里的 iFrame API 是否相同。不过,我会阅读 JS API,谢谢!
  • 很确定您可以删除 href="#" 并仍然触发 onclick。将其取出将阻止您使用实际上不执行任何操作的字符污染 URL 栏中的 URL。如果需要,您可以在 CSS 中更改指针(用于“这是可点击的”指示)。

标签: jquery html lazy-loading embedding deferred


【解决方案1】:

您应该设置 href 以便人们知道他们将要加载什么。这可以在页面生成时在 a 元素上完成,也可以在 JS 中完成。如果您希望您的页面为禁用 Javascript 的人工作,它必须在元素上。

var url = "http://www.youtube.com/watch?v=" + videoId;
$(this).attr('href', url);

你还应该通过设置标题告诉人们如果他们点击其中一个会发生什么:

$(this).attr('title', "Click to play video");

或者通过创建类似SMH 的叠加层,这使得点击图像将播放视频更加明显。或两者兼而有之。

此外,当人们按住 ctrl 或命令键时,您不应中断在新窗口中打开内容。我更新了fiddle,但基本上在您需要的点击事件中:

 var isCtrlPressed = e.ctrlKey || e.metaKey;
 if (isCtrlPressed == true){
    return;
 } 

我知道你说过忽略样式,但如果占位符的背景颜色与页面背景明显不同,我更喜欢它。如果一个页面加载缓慢,我可以知道那里会加载一些东西,而不是只是一个空白的页面。

这是否完全忽略了延迟加载的要点?

不完全是,但在这种情况下有点毫无意义。当正在加载的东西非常复杂(例如,一个巨大的表格)时,通常会使用延迟加载,这样会大大增加页面大小,这会使页面的初始渲染在用户点击链接后很长时间.

尽管 youtube 视频加载速度可能很慢,但它们实际上不应阻止页面的其余部分同时加载和呈现,因此延迟加载视频只会给您带来一点好处,但需要做很多工作。

我想您应该衡量某人查看页面的速度,滚动到底部,然后点击播放最后一个视频。如果延迟加载速度更快,因为其他视频 Flash 播放器没有加载,那么它仍然值得。

【讨论】:

    【解决方案2】:

    下面的代码有一个jsfiddle here。 (播放器没有正确显示,我认为 jsfiddle 不能很好地与“嵌入方法”一起使用。我知道它可以在 jsfiddle 上使用 iframe 方法,但你提到你想避免 iframe)。

    如前所述,一大改进是使用swfobject 生成播放器嵌入。使用此方法时,您必须为播放器元素创建一个占位符。单击链接时,占位符将被删除并替换为嵌入。 我强烈建议为链接和播放器创建一个父 div。为了防止在生成嵌入时调整元素的大小,您还应该明确设置容器元素的宽度/高度。

    我认为这是很好地使用延迟加载。尽管 Flash 播放器在加载时不会阻塞,但它们仍然会占用大量资源,我希望最初显示为缩略图集的页面。

    标记

    <script src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
    </script>
    
    <div class="container">
        <div id="placeholder_FzRH3iTQPrk"></div>
        <a href="#" data-video="FzRH3iTQPrk" class="youtube-video"></a>
    </div>
    <div class="container">
        <div id="placeholder_go43XeW6Wg4"></div>
        <a href="#" data-video="go43XeW6Wg4" class="youtube-video"></a>
    </div>
    

    JavaScript

    $(document).ready(function() {
        $('a.youtube-video').each(function() {
            var videoId = $(this).attr('data-video');
            var videoThumbnail = "http://img.youtube.com/vi/" + videoId + "/0.jpg";
            var videoBackground = $('<span class="youtube-thumbnail"></span>');
            videoBackground.css({
                background:"#fff url('"+videoThumbnail+"') no-repeat"
            });
    
            // also set the parent container size to prevent flicker
            $(this).add($(this).parent()).css({
                height:315,
                width:460,
                position:"relative",
                display:"block",
                textAlign:"center",
                color:"#fff",
                fontSize:26
            });
            $(this).text('Click to load video');
            $(this).append(videoBackground);
        });
    
        $('a.youtube-video').click(function(e) {
            e.preventDefault();
            var videoId = $(this).attr('data-video');
            var params = { allowScriptAccess: "always", allowFullScreen: "true" };
            var atts = { id: 'player_'+videoId };
            $(this).hide();
            swfobject.embedSWF(
                "http://www.youtube.com/v/"+videoId+"?enablejsapi=1&playerapiid=ytplayer&version=3", 
                'placeholder_'+videoId, "460", "315", "8", null, null, params, atts);
    
        });
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-11
      相关资源
      最近更新 更多