2

I want to apply lozad.js script to my wordpress/woocommerce frontend. For this to work, I had to create a new attribute which is data-src and place 'loading.gif' in the normal src attribute. The code is working fine but it also applies to the backend but I'm not loading the lozad.js script in the backend so the images in my product list view are not displayed but the loading.gif. How can I just target the product page and blog page (front page)? I tried function is_admin() without luck. This is the code I am using:

 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 = 'https://d1zczzapudl1mr.cloudfront.net/preloader/loader_150x150.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 . ' lozad';
     $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');
  • +1 for using proper HTML parsing, but beware that the_content do not have to be a properly balanced HTML, and in any case you might want to use hiegher priority to let other plugins manipulate it. – Mark Kaplun Mar 1 '18 at 17:55
0

Solution is simple, check that is_admin() returns false before doing any modifications to the content, or hook on admin_init to add you hooks.

I don't think that the_content is used in the context of admin, but thumbnail generation might be used.

Another thing to keep in your mind is that those hooks might be triggered when AJAX/REST responses are generate (depending on their content), at which case it is not obvious whether you should still use lazy loading at all.

| improve this answer | |
  • Thanks it works :) But now I have found another problem. On my page, I have an Ajax Search (the search shows the product images) and there I have the same problem like in the backend. Only the gif is showing and no data-loaded="true" attribute. So there must be some conflict. I tried to change the priority but without luck. – nibor90 Mar 2 '18 at 12:28
  • you will need to re-apply the JS after the AJAX request returns, or check which hook the ajax request is using and hook on it before it is being handled and set some global flag that the content should not be modified – Mark Kaplun Mar 2 '18 at 14:13
  • Oh ok how do I re-apply the JS after the AJAX request returns? I can't seem to get this right. Do you maybe have some example how I could do this? – nibor90 Mar 2 '18 at 17:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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