blazy
blazy copied to clipboard
blazy issue in safari - Mac OS, iOS - not loading images in viewport for the first time
I am facing issue in loading the images for the first time in Safari - Mac OS and in iOS using blazy.
When you load the page for the first time - the images in the view port are not rendering, when scrolled down the other images are rendering properly. This issue occurs only in Safari browser on Mac OS and in iOS and works fine in Chrome, Mozilla.
When we refresh the page, all the images are loaded properly.
How to resolve the above issue ??
Hi, I have the same issue !
But for background images, it's ok !
Hey @smanikandan7 and @Bcld-net.
Do you have a live example? Do you see the same behavior on my examples page (http://dinbror.dk/blazy/examples/)?
Hi @dinbror,
An example in this site: http://gitelevaldesfees.fr/Location-de-velos-a-assistance-electrique
In your examples page, I don't have the issue...
Thanks
@Bcld-net
Try
- move you script to the bottom of your body. (so it wont block rendering).
- Since your're using jquery initialize blazy on dom.ready
Hi @dinbror,
- I have try to move script at the bottom of the body but without success !
- I already initialized blazy on DOM.ready !
For the moment, I use a poor solution and it's ok in Safari (MacOS and iOS):
setTimeout(function() { bLazy.revalidate(); }, 1000);
Thanks
Unfortunately, this fix won´t work. When I am changing the window width until the image dimension is reached the image is shown. Until that bLazy is not triggered. I am using srcsets in a
I have the same issue, just updated to the most recent version of the plugin but the problem persists. It seems it only affects Safari when using preloading / loading images out of the viewport. On initial load the images in the viewport do not display, when scrolling down, the other images are loaded correctly. The first images only show after reloading the page.
Hey @dgorges, @philspbr
Do you have a live example? Do you see the same issue on my example page: http://dinbror.dk/blazy/examples/
Hey @dinbror , unfortunately this is a .htaccess protected page. I use modernizr to load my js.
<script> Modernizr.load([ { load : ['[/Resources/Public/JavaScript/lib/jquery.min.js', '[/Resources/Public/JavaScript/lib/jquery.plugins.min.js', 'ielt9![/Resources/Public/JavaScript/lib/selectivizr.min.js'] }, { test : Modernizr.mq('only all'), nope : '[/Resources/Public/JavaScript/lib/respond.min.js' }, '[/Resources/Public/JavaScript/lib/blazy.min.js','[/Resources/Public/JavaScript/main.min.js','[/Resources/Public/JavaScript/global.min.js']); </script>
In my main.min.js I have the bLazy plugin
`var B = B || {}; (function($) { // main init function is called on document ready B.initialize = function() { B.lazy.initialize(); }; /** * lazy loading for images */ B.lazy = { settings: { selector: '.bJS_lazy' } , initialize: function() { this.events(); } , events: function() {
var
me = this
,s = me.settings;
var bLazy = new Blazy({
selector: s.selector
, offset: 350
, successClass: 'b_loaded'
, validateDelay: 5
});
B.lazyimage = bLazy;
}
};
/**
* on document ready
*/
$(document).ready(function() {
B.initialize();
});
})(jQuery);`
In the global.min.js I have some plugins (i.e. flexslider) where I revalidate the lazy images
` $('.JM_obj-slider').flexslider({ animation: 'slide', controlNav: true, directionNav: false, pauseOnAction: true, // pauseOnHover: true, start: function(slider){
B.lazyimage.revalidate();
},
before: function (slider) { // fires asynchronously with each slider animation
B.lazyimage.revalidate();
}
});`
Thank you in advance for your help.
@dgorges Looks ok to me. Do you see the same issue on my example page: http://dinbror.dk/blazy/examples/
@dinbror @smanikandan7 @Bcld-net I solved the issue. This is a bug in the new version of Safari.
I tracked the source code(v1.8.2) and found the problem at 205 line(in function loadElment) : The value of ele.offsetHeight is zero in Safari (but it is not zero in Chrome, IE etc. ), so the condition of (ele.offsetWidth > 0 && ele.offsetHeight > 0) is false and the image can never be loaded.
How to solve it ? We just need to set the css property min-height: 1px to these lazy images, and the issue will be solved.
Hope to help you!
Hi yswang0927,
That's great!!
Hi @yswang0927
For me, it's OK !
Thanks
I'm using this library in combination with the Drupal integration (drupal.org/project/blazy) and can confirm this problem. I tracked down the source problem to this part of the blazy.js code:
// start lazy load setTimeout(function() { initialize(scope); }); // "dom ready" fix
We need a proper trigger here. Something like DOMContentLoaded
. I'm trying it out and report back here.
Update: I tried with the help of domready (https://github.com/ded/domready) and replaced above code with:
setTimeout(function() {
domready(function () {
initialize(scope);
});
}); // "dom ready" fix
Now the problem is gone away. Hint: Drupal core already includes domready via the core/domready library. I'm considering to create a fork which makes use of Drupal's core/domready library.
Update 2: Instead of creating the fork, I decided to write a custom Blazy loader which revalidates on the load event of the window object.
@mxhaupt, I'm encountering the same issue. Could you please provide your custom loader and how you implemented this? Thanks in advance 👍
@fabianmarz This is my current implementation, a modification of blazy.load.js of the Drupal blazy module:
/**
* @file
* Provides bLazy loader. Modified for lighter loading and to be compatible with Safari browsers.
*/
(function (Drupal, drupalSettings, _db, window) {
'use strict';
/**
* Blazy public methods.
*
* @namespace
*/
Drupal.blazy = Drupal.blazy || {
init: null,
windowWidth: 0,
done: false,
globals: function () {
var me = this;
var settings = drupalSettings.blazy || {};
var commons = {
success: me.clearing,
error: me.clearing
};
return _db.extend(settings, commons);
},
clearing: function (el) {
var ie = _db.hasClass(el, 'b-responsive') && el.hasAttribute('data-pfsrc');
// The .b-lazy element can be attached to IMG, or DIV as CSS background.
el.className = el.className.replace(/(\S+)loading/, '');
// The .is-loading can be .grid, .slide__content, .box__content, etc.
var loaders = [
_db.closest(el, '.is-loading'),
_db.closest(el, '[class*="loading"]')
];
// Also cleans up closest containers containing loading class.
_db.forEach(loaders, function (wrapEl) {
if (wrapEl !== null) {
wrapEl.className = wrapEl.className.replace(/(\S+)loading/, '');
}
});
// @todo: Remove when Blazy library fixes this.
// @see http://scottjehl.github.io/picturefill/
if (window.picturefill && ie) {
window.picturefill({
reevaluate: true,
elements: [el]
});
}
},
loadGlobally: function () {
if (this.init == null) {
this.init = new Blazy(this.globals());
}
else {
this.init.revalidate();
}
}
};
/**
* Add an extra listener to the window load event and perform revalidation.
* This makes sure that Safari also loads images on initial requests.
*/
window.addEventListener('load', function () {
Drupal.blazy.loadGlobally();
});
/**
* Attaches blazy behavior to HTML element identified by [data-blazy].
*
* @type {Drupal~behavior}
*/
Drupal.behaviors.blazy = {
attach: function (context, settings) {
Drupal.blazy.loadGlobally();
}
};
}(Drupal, drupalSettings, dBlazy, window));
I'm overriding the library definition this way:
/**
* Implements hook_library_info_alter().
*/
function mymodule_library_info_alter(&$libraries, $extension) {
if ($extension === 'blazy') {
$libraries['load']['js'] = ['/' . drupal_get_path('module', 'mymodule') . '/js/blazy.load.js' => ['weight' => -1, 'minified' => FALSE]];
}
}
Thanks for providing the code. It seems to work now. 🎉