用特定类替换图像元素上延迟加载插件的图像属性

Posted

技术标签:

【中文标题】用特定类替换图像元素上延迟加载插件的图像属性【英文标题】:Replace image attributes for lazyload plugin on image elements with specific class 【发布时间】:2017-11-04 12:50:15 【问题描述】:

我正在使用 WordPress,我想仅对某些图像应用延迟加载。我在这里找到了一种创建 data-src 属性并将 src 属性替换为正确图像https://wordpress.stackexchange.com/questions/60792/replace-image-attributes-for-lazyload-plugin-data-src 的方法。现在我的代码将延迟加载应用于所有图像,我只想将其应用于具有延迟加载类的图像。

这就是我的代码的样子

// Lazyload Converter
function add_lazyload($content) 

$content = mb_convert_encoding($content, 'html-ENTITIES', "UTF-8");
$dom = new DOMDocument();
@$dom->loadHTML($content);

$images = [];

foreach ($dom->getElementsByTagName('img') as $node) 
    $images[] = $node;


foreach ($images as $node) 
    $fallback = $node->cloneNode(true);

    $oldsrc = $node->getAttribute('src');
    $node->setAttribute('data-src', $oldsrc );
    $newsrc = get_template_directory_uri() . '/assets/placeholders/squares.svg';
    $node->setAttribute('src', $newsrc);

    $oldsrcset = $node->getAttribute('srcset');
    $node->setAttribute('data-srcset', $oldsrcset );
    $newsrcset = '';
    $node->setAttribute('srcset', $newsrcset);

    $noscript = $dom->createElement('noscript', '');
    $node->parentNode->insertBefore($noscript, $node);
    $noscript->appendChild($fallback);


$newHtml = preg_replace('/^<!DOCTYPE.+?>/', '', str_replace( array('<html>', '</html>', '<body>', '</body>'), array('', '', '', ''), $dom->saveHTML()));
return $newHtml;

add_filter('the_content', 'add_lazyload');
add_filter('post_thumbnail_html', 'add_lazyload');

如何通过类而不是标签来获取元素?

【问题讨论】:

【参考方案1】:

您可以为此使用xpath(与domxpath); xpath 是一种从 XML/HTML 文档中选择节点的查询语言。

不幸的是,选择具有独立短语lazy-load 的类的元素与xpath 有点复杂;它不像css-selectors 所习惯的那样简洁; xpath 没有 @attr~="lazy-load" 等速记属性选择器。

这是一个示例,说明如何选择具有 lazy-load 类的所有 &lt;img&gt; 元素:

// create a DOMXPath instance that operates on your DOMDocument instance $dom
$xpath = new DOMXPath( $dom );

// select nodes by some criteria (returns a non-live¹ DOMNodeList)
$images = $xpath->query( '//img[contains(concat(" ", normalize-space(@class), " "), " lazy-load ")]' );

// then apply the same operations to the nodes again as in your last foreach loop
foreach ($images as $node) 
  $fallback = $node->cloneNode(true);
  // etc.

1) 尽管在任何地方都没有正式记录(据我所知),DOMXPath 返回的 DOMNodeList 不是“实时的”,而不是 DOMDocument 返回的 DOMNodeLists , 我相信。因此,您的第一个 foreach() 应该是不必要的。但是你必须试一试,这是肯定的。

我建议不要执行以下任何操作,但如果您确定那些&lt;img&gt; 元素将拥有的唯一类是lazy-load,即class 属性将始终完全是lazy-load,没有任何空格和/或其他类,您也可以使用这个更简单的查询来代替:

$images = $xpath->query( '//img[@class="lazy-load"]' );

或者,如果&lt;img&gt; 元素可以有多个类,但永远不会有任何其他类包含短语lazy-load(例如class="thumbnail lazy-loading"),您可以使用:

$images = $xpath->query( '//img[contains(@class,"lazy-load")]' );

【讨论】:

以上是关于用特定类替换图像元素上延迟加载插件的图像属性的主要内容,如果未能解决你的问题,请参考以下文章

简单的JavaScript图像延迟加载库Echo.js

如何在延迟加载期间在图像占位符上显示“加载”gif图像

延迟加载 Flash 对象

延迟 5 秒后用文字替换图像

UITableView 中多张图片的延迟加载

具有延迟加载和下载图像的 ListView [重复]