Why does IE have incorrect margins after my animation?
I'm using jQuery Masonry (google it, it's super awesome) for my site's dynamic layout.
For some reason, when i invoke Masonry after performing a .load() event, i don't get exactly the layout that is expected.
To see what I mean, go to http://keepskatinbro.com, then click on any box to expand it open, then you'll notice that the layout is adjusted so that closed boxes float around the opened box. The problem is that boxes below the opened box overlap with the bottom of the opened box.
If you resize your browser (restore, then maximize), you will then see the correct layout because Masonry fires when the browser size is changed. Notice after resizing your browser that there is now a margin below the big opened box.
This margin needs to be there after I dynamically open and inject content into the box.
It works perfectly in other browsers though.
This is the code that makes everything happen. Several functions, then finally the last block calls everything including masonize(). Masonize() works well by itself, but in a callback, i seem to have the described issue:
function masonize(the_duration, callback) {
$('#sort').masonry({
singleMode: false,
columnWidth: 175,
itemSelector: undefined,
appendedContent: undefined,
saveOptions: true,
resizeable: true,
animate: true,
animationOptions: {
easing: 'swing',
duration: the_duration
}
}, function() {
$(this).css({ margin: '10px' });
if (callback) {
$(this).delay(the_duration)
$(this).queue(function() {
callback();
$(this).dequeue();
});
}
});
}
function set_position($target_item, top_offset, left_offset) {
$target_item.css({ 'position':'absolute', 'top':top_offset+'px', 'left':left_offset+'px' });
}
function show_loader($target_box, callback) {
var $target_box_img = $target_box.find('img.wp-post-image'),
$target_img_offset = $target_box_img.offset(),
$target_img_width = $target_box_img.width(),
$target_img_height = $target_box_img.height();
set_position( $ajaxSpinner,
/*top*/ $target_img_offset.top + ($target_img_height / 2) - ($ajaxSpinner.width() / 2),
/*left*/ $target_img_offset.left + ($target_img_width / 2) - ($ajaxSpinner.height() / 2)
);
$ajaxSpinner.fadeIn(function() {
if (callback) { callback(); }
});
}
function hide_loader(callback) {
$ajaxSpinner.fadeOut(/*duration:*/0, function() {
if (callback) { callback(); }
});
}
function open_box($target_box, $target_path, $target_content, do_masonize, callback) {
$target_box.find('.opened_view')
.load(base + $target_path + ' ' + $target_content, function() {
$target_box.find('.closed_view').addClass('hidden');
$target_box.find('.thumbnail_wrapper').addClass('hidden');
$target_box.find('.ajax_trigger_title').addClass('opened_post_title');
$target_box.width(660);
$target_box.append('<a class="ajax_trigger_close" id="close_' + $target_box.attr('id') + '" href="' + base + '/">Close</a>');
if (do_masonize && callback) {
masonize(masonize_duration, function(){
callback();
});
}
else if (do_masonize && !callback) { masonize(masonize_duration); }
else if (callback) { callback(); }
});
}
function close_box($target_box, do_masonize, callback) {
$target_box.find('.opened_view').html('');
$target_box.width(310);
$target_box.find('.closed_view').removeClass('hidden');
$target_box.find('.thumbnail_wrapper').removeClass('hidden');
$target_box.find('.ajax_trigger_title').removeClass('opened_post_title');
$target_box.find('a.ajax_trigger_close').remove();
if (do_masonize && callback) {
masonize(masonize_duration, function(){
callback();
});
}
else if (do_masonize && !callback) { masonize(masonize_duration); }
else if (callback) { callback(); }
}
function scroll_to($target, duration, top_margin, callback) { //scrolls the page to the $target. $targ开发者_开发问答et can be a jQuery object or the number of pixels to scroll from the top.
if ($target instanceof $ || $target instanceof jQuery) {
$('html, body').animate({
scrollTop: $target.offset().top - top_margin
}, duration, function() {
if (callback) { callback(); }
});
}
//three ways to check for an integer below:
else if ($target === parseInt($target,10)) { //else if integer
//else if ( (typeof($target) == 'number') && ($target.toString().indexOf('.') == -1) ) { //else if integer
//else if ( !isNaN(parseInt($target)) ) { //else if integer
$('html, body').animate({
scrollTop: $target
}, duration, function() {
if (callback) { callback(); }
});
}
}
$.address.change(function(event) {
if (event.value !== '/' && $clicked_item) {
if ($target_close) { //if not first item to be opened then close previously opened item.
show_loader($target_open, function() {
open_box($target_open, /*path:*/event.value, '.entry-content', /*masonize:*/false, function() {
close_box($target_close, /*masonize:*/true, function() {
scroll_to($target_open, /*duration:*/360, /*top-margin:*/80);
});
hide_loader();
$target_close = $target_open;
});
});
}
else { //otherwise just open target item since it is the first item to be opened.
show_loader($target_open, function() {
open_box($target_open, /*path:*/event.value, '.entry-content', /*masonize:*/false, function() {
hide_loader();
masonize(masonize_duration, function() {
scroll_to($target_open, /*duration:*/360, /*top-margin:*/80);
});
$target_close = $target_open;
});
});
}
}
else if ( event.value === '/' && $clicked_item ) {
if ( $clicked_item.hasClass('ajax_trigger_close') && $clicked_item.attr('id') !== 'home_link' ) {
close_box($target_close, /*masonize:*/true);
scroll_to(/*offset:*/0, /*duration:*/360);
}
}
});
Any idea what might be the issue? Thank you in advance!
I've read about this bug that might be what is effecting you (it's an IE issue):
"jQuery $(anchor).offset().top seems to change the offset position calculation after a scrolling takes place. For example if you don't scroll the container, the position is 300 from the top. But if you start to scroll abit lower down, the position changes!
To fix this issue, I use document.getElementById(anchor).offsetTop"
So try replacing:
$target.offset().top
with
document.getElementById($target.attr('id')).offsetTop
and see if that does the trick for you.
The answer is that in IE masonry was completing before the content in the DOM was fully loaded after using a jQuery ajax call, so the boxes didn't have their final size yet.
精彩评论