4

I want to apply jquery lazyload plugin. For this to work I have to create a new attribute which is data-src place there the src value and then replace the src value with a specific value '...nothing.gif'. I found a solution on wordpress.org support

This is my adapted code -

function add_lazyload($content) 
{
    global $post;
    $search = '/src\=\"([^\s]+(?=\.(bmp|gif|jpeg|jpg|png))\.\2)\"/';
    $content = replacer($content, $search, '/src/', 'data-original');
    $search = '/img\ class\=\"/';
    $content = replacer($content, $search, '/class\=\"/', 'class="lazy ');
    $search = '/alt/';
    $content = replacer($content, $search, '/alt/', 'src="'.get_template_directory_uri().'/library/images/nothing.gif"');
    return $content;
}

function replacer($src, $search, $find, $replace)
{
    preg_match_all($search, $src, $result, PREG_OFFSET_CAPTURE);
    foreach($result[0] as $entry)
    {
        $org = $entry[0];
        $rep = preg_replace($find, $replace, $entry[0]);
        $org = "/" .str_replace(array("=",":","/",".","-","_",'"',"'"," "),     array("\=","\:","\/","\.","\-","\_",'\"',"\'","\ "), $org). "/";
        $src = preg_replace($org, $rep, $src);
    }
return $src;
}

add_filter('the_content', 'add_lazyload');

The problem with this code is that it replaces every alt string (for example in a paragraph) with .../library/images/nothing.gif, not just the alt image attribute.

Does anyone know how to solve this?

3 Answers 3

7

instead of replacing the alt tag you could add-an-attribute-to-a-tag

function add_lazyload($content) {
     $dom = new DOMDocument();
     @$dom->loadHTML($content);


     foreach ($dom->getElementsByTagName('img') as $node) {  
         $oldsrc = $node->getAttribute('src');
         $node->setAttribute("data-original", $oldsrc );
         $newsrc = ''.get_template_directory_uri().'/library/images/nothing.gif';
         $node->setAttribute("src", $newsrc);
     }
     $newHtml = $dom->saveHtml();
     return $newHtml;
}

note: i didn't quite tested this code, so be careful :)

4
  • 1
    Thank you very much, this solution works great!. Just one thing, you are missing a semicolon after $newHtml = $dom->saveHtml(). Thanks again!
    – Alvaro
    Commented Aug 5, 2012 at 9:26
  • ahhh! you're right! :))
    – pcarvalho
    Commented Aug 5, 2012 at 10:08
  • 1
    Be careful here, if you use this on a fragment of a post it may mess with UTF-8 encoding. Commented Dec 12, 2014 at 10:03
  • DOMDocument is expensive
    – Michele
    Commented Nov 11, 2020 at 11:08
7

I modified peteroak's excellent solution to convert to utf-8 and stripped the doctype, html, and body from the ouput.

function add_lazyload($content) {

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

    foreach ($dom->getElementsByTagName('img') as $node) {  
        $oldsrc = $node->getAttribute('src');
        $node->setAttribute("data-original", $oldsrc );
        $newsrc = ''.get_template_directory_uri().'/images/nothing.gif';
        $node->setAttribute("src", $newsrc);
    }
    $newHtml = preg_replace('/^<!DOCTYPE.+?>/', '', str_replace( array('<html>', '</html>', '<body>', '</body>'), array('', '', '', ''), $dom->saveHTML()));
    return $newHtml;
}
add_filter('the_content', 'add_lazyload');
1
  • Thanks! I was just about to comment this problem and found your answer.
    – Alvaro
    Commented Aug 7, 2012 at 15:24
1

I added some features to Shieeets solution:

  • srcset support (changes srcset to data-srcset)
  • noscript fallback (displays original image)
  • video/embed/iframe support (Youtube and co)
  • additional hook to affect thumbnails (in addition to post images)
  • classes "lazy" and "lazy-hidden" are added automatically

Here is the PHP code:

// Lazyload Converter
function add_lazyload($content) {

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

    // Convert Images
    $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() . '/images/placeholder.gif';
        $node->setAttribute('src', $newsrc);

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

        $classes = $node->getAttribute('class');
        $newclasses = $classes . ' lazy lazy-hidden';
        $node->setAttribute('class', $newclasses);

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


    // Convert Videos
    $videos = [];

    foreach ($dom->getElementsByTagName('iframe') as $node) {
        $videos[] = $node;
    }

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

        $oldsrc = $node->getAttribute('src');
        $node->setAttribute('data-src', $oldsrc );
        $newsrc = '';
        $node->setAttribute('src', $newsrc);

        $classes = $node->getAttribute('class');
        $newclasses = $classes . ' lazy lazy-hidden';
        $node->setAttribute('class', $newclasses);

        $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');

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.