我正在使用Packey.js[http://packery.metafizzy.co/],我在页面加载方面遇到了一些布局问题。我看过Masonry、Isotope和Packey的文档(所有插件都非常相似,都是由David DeSandro开发的),其中讨论了在加载所有图像以及任何网络字体后应该触发布局的问题。
http://packery.metafizzy.co/appendix.html
我让Packey处理图像很好Loaded。。。但我不知道如何将谷歌网页字体加载程序与之联系起来。下面是我加载字体的代码,后面是imagesLoaded Packey Layout。如果有人能在Web字体和图像加载后提出让Packey火起来的方法,我将永远感激。
// before <body>
<script type="text/javascript">
WebFontConfig = {
google: {
families: [ 'Bitter:400,700,400italic:latin' ]
},
typekit: {
id: // hidden for obvious reasons
}
};
(function() {
var wf = document.createElement('script');
wf.src = ('https:' == document.location.protocol ? 'https' : 'http') + '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
wf.type = 'text/javascript';
wf.async = 'true';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(wf, s);
})();
</script>
// after </body>
// jquery and plugins are loaded prior to the following code
jQuery(document).ready(function($) {
var $container = $('section.home-page main');
imagesLoaded( $container, function() {
$container.packery({
itemSelector: 'article',
columnWidth: '.grid-sizer',
gutter: '.gutter-sizer'
});
});
});
这一切都是为了创建解决问题的最佳算法,这需要对问题进行稳健的分析,然后找到所有可能的解决方案,并最终应用最佳解决方案。
问题:
- 为您的页面创建Masony效果,这取决于不同不相关元素(网络字体和图像)的加载,或者换句话说,它取决于不相关页面元素的异步加载
可能的算法:
-
加载一个项目(webfont或图像优先),成功加载第一个项目后,开始加载另一个
-
使用标志,并根据返回的标志异步调用两个加载函数,开发人员可以决定要做什么
第一个算法肯定是错误的
-
就像在一个系列调用中一样,如果一个调用由于任何原因失败,其余的调用将不会发生,因为它取决于另一个项加载回调。
-
由于正在发生事件,加载项目所花费的时间将更长以串联的方式,而不是以并联的方式。
第二种算法似乎可以
解决方案:
参考webfontloader的两个文档,imagesLoaded
-
创建两个标志变量
var imagesAreLoaded = false , fontsAreLoaded = false
-
在成功回调加载事件时将每个标志设置为true
对于webfontloader,如果您想对仅在包插件中使用的字体给予最高优先级,则应使用fontactive
,如果该插件依赖于多个系列,则最好使用active
:
WebFontConfig = {
active: function() { // set fontsAreLoaded to true here },
fontactive: function(familyName, fvd) { // set fontsAreLoaded to true here }
};
WebFontConfig是您传递给webfontloader load
方法的对象。
对
imagesLoaded
事件执行相同操作$('#container').imagesLoaded()
.done(函数(实例){//在此处将imagesAreLoaded设置为true})
请注意,imagesLoaded的jQuery插件返回一个jQuery Deferred对象。这允许您使用.always()
、.done()
、.fail()
和.progress()
,类似于发出的事件。
通常一切都应该运行良好,通常字体会在图像加载之前加载,但一个好的开发人员应该处理所有可能的场景。
$(document).load(function){
//如果这两个标志都是真的,继续加载你的砖石。//否则,如果任一标志为假,则显示警告,重试加载,或者你认为更好的})
注意:我的答案并没有提供太多的编码,因为从我看来,这两个插件的文档都很清楚,但我认为问题是如何使用正确的算法来处理这个问题。
这非常有效。
<script>
function loadIsotope(){
var $container = $('section.home-page main');
imagesLoaded( $container, function() {
$container.packery({
itemSelector: 'article',
columnWidth: '.grid-sizer',
gutter: '.gutter-sizer'
});
});
}
WebFont.load({
google: {
families: ['Bitter']
},
active: function() {
// This event is triggered when the fonts have rendered.
loadIsotope();
},
inactive:function(){
// This event is triggered when the browser does not support
// linked fonts or if none of the fonts could be loaded.
loadIsotope();
}
});
</script>
正如ProlyGeek所说,异步解决方案更合理。代码可能看起来像这样(我测试过了——它有效):
<script>
var loadedImages = false;
var loadedFonts = false;
function loadedEverything() {
return (loadedImages && loadedFonts);
}
function loadMasonry() {
console.log("Loading masonry");
}
WebFontConfig = {
google: {
families: ['Droid Sans']
},
active: function() {
loadedFonts = true;
if (loadedEverything()) loadMasonry();
}
};
imagesLoaded( document.querySelector('.container'), function(instance) {
loadedImages = true;
if (loadedEverything()) loadMasonry();
});
</script>
任何加载速度较慢的都会启动您需要的活动。