草庐IT

javascript - 使用 <noscript> 回退的 DRY 延迟加载图像

coder 2025-02-12 原文

我知道(少数)非 JavaScript 用户在那里,我想迎合他们,而不是仅仅因为他们的偏好(出于隐私原因或其他原因)而给他们较差的体验。

大多数延迟加载 JS 库似乎以相同的方式解决这个问题,例如参见 lazysizes :

<style>
    .no-js img.lazyload {
        display: none;
    }
</style>

<noscript>
    <img src="image.jpg" />
</noscript>
<img src="grey.jpg" data-src="image.jpg" class="lazyload" />

主要是出于好奇,我想知道是否有可能从 <noscript> 中撤回回退。标记并使用 JavaScript 以编程方式将其添加到 DOM,这样图像源就不必在两个图像标记中重复,这只会让我:

<noscript>
    <img src="image.jpg" class="lazyload" width="600" height="400"/>
</noscript>

这是我拼凑的:

(function(attribute) {
    Array.prototype.forEach.call(document.getElementsByTagName("noscript"), function(node) {
        var parser = new DOMParser,
            el = parser.parseFromString(node.textContent, "text/xml").documentElement, // XML => <img/> required
            img = ("img" == el.tagName) ? el : el.getElementsByTagName("img")[0]; // allow for <img/> in <picture>

        img.setAttribute(attribute, img.getAttribute("src"));
        img.setAttribute("src", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC");

        node.insertAdjacentHTML("beforebegin", el.outerHTML);
    });
})("data-src"); // different libraries use different data attribute names

这似乎在所有地方(Chrome、Safari、Opera、Firefox)都有效,除了 Internet Explorer(自然)。我知道 .textContent在 IE9 之前不可用,但 IE9+ 似乎都在最后的障碍上失败了 - .outerHTML .我注定要失败并且不得不在我的标记中重复自己吗?

更新:澄清一下,我希望能够在图像标签中使用任意属性(alt、标题等),甚至使用响应式标记:

<noscript>
    <picture>
        <source ... />
        <source ... />
        <img src="image.jpg" />
    </picture>
</noscript>

最佳答案

我是 lazySizes 的创建者。这种方法有多个问题:

  1. noscript 元素永远不会被渲染,这意味着它是不可检测的,无论它是否可见(或者更好的说法是它总是不可见的)
  2. 您不能使用有状态类 lazyloadinglazyload 向用户提供反馈
  3. 您不能为懒惰的嵌入内容预先占用空间(这对于 a) 用户体验(无内容跳转)和 b) 性能(无回流)都很重要
  4. (在旧版浏览器中有问题)
  5. 不能使用data-sizes="auto" 特性

但是,如果 4. 和 5. 对您来说不是问题,则可以结合使用 noscript 子元素和 lazyload 父元素来实现此目的.

标记可能看起来像这样:

<div class="lazyload" data-noscript="">
    <noscript>
        <p>any kind of content you want to be unveiled</p>
    </noscript>
</div>

lazySizes 插件代码看起来像这样:

(function(){
    'use strict';

    var supportPicture = !!window.HTMLPictureElement;

    addEventListener('lazybeforeunveil', function(e){
        if(e.defaultPrevented || e.target.getAttribute('data-noscript') == null){return;}
        var imgs, i;
        var noScript = e.target.getElementsByTagName('noscript')[0] || {};
        var content = noScript.textContent || noScript.innerText || '';
        e.target.innerHTML = content;

        if(supportPicture){return;}

        imgs = e.target.querySelectorAll('img[srcset], picture > img');

        for(i = 0; i < imgs.length; i++){
            lazySizes.uP(imgs[i]);
        }
    });
})();

如果你喜欢这个,我可能会为此制作一个官方插件。这是插件:https://github.com/aFarkas/lazysizes/tree/master/plugins/noscript

关于javascript - 使用 <noscript> 回退的 DRY 延迟加载图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29145354/

有关javascript - 使用 <noscript> 回退的 DRY 延迟加载图像的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  5. ruby-on-rails - rails : keeping DRY with ActiveRecord models that share similar complex attributes - 2

    这似乎应该有一个直截了当的答案,但在Google上花了很多时间,所以我找不到它。这可能是缺少正确关键字的情况。在我的RoR应用程序中,我有几个模型共享一种特定类型的字符串属性,该属性具有特殊验证和其他功能。我能想到的最接近的类似示例是表示URL的字符串。这会导致模型中出现大量重复(甚至单元测试中会出现更多重复),但我不确定如何让它更DRY。我能想到几个可能的方向...按照“validates_url_format_of”插件,但这只会让验证干给这个特殊的字符串它自己的模型,但这看起来很像重溶液为这个特殊的字符串创建一个ruby​​类,但是我如何得到ActiveRecord关联这个类模型

  6. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  7. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  8. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  9. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  10. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

随机推荐