2

私は自分のサイトの動的レイアウトにjQueryMasonry(google it、それはとても素晴らしい)を使用しています。

何らかの理由で、.load()イベントを実行した後にMasonryを呼び出すと、期待されるレイアウトが正確に得られません。

私が何を意味するかを確認するには、http://keepskatinbro.comにアクセスし、任意のボックスをクリックして展開すると、閉じたボックスが開いたボックスの周りに浮くようにレイアウトが調整されていることがわかります。問題は、開いたボックスの下のボックスが、開いたボックスの下部と重なっていることです。

ブラウザのサイズを変更すると(復元してから最大化)、ブラウザのサイズが変更されるとMasonryが起動するため、正しいレイアウトが表示されます。ブラウザのサイズを変更した後、大きく開いたボックスの下にマージンがあることに注意してください。

このマージンは、コンテンツを動的に開いてボックスに挿入した後に存在する必要があります。

ただし、他のブラウザでも完全に機能します。

これはすべてを実現するコードです。いくつかの関数、そして最後に最後のブロックがmasonize()を含むすべてを呼び出します。Masonize()はそれ自体でうまく機能しますが、コールバックでは、次のような問題が発生しているようです。

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. $target 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);
        }
    }
});

何が問題になるのか考えてみませんか?前もって感謝します!

4

2 に答える 2

1

私はあなたに影響を及ぼしているかもしれないこのバグについて読みました(それはIEの問題です):

"jQuery $(anchor).offset()。topは、スクロールが行われた後、オフセット位置の計算を変更するようです。たとえば、コンテナをスクロールしない場合、位置は上から300になります。ただし、スクロールを開始すると、少し下がると、位置が変わります!

この問題を修正するには、document.getElementById(anchor).offsetTop"を使用します。

したがって、置き換えてみてください:

$target.offset().top

document.getElementById($target.attr('id')).offsetTop

それがあなたのためにトリックをするかどうか見てください。

于 2011-03-11T04:23:01.870 に答える
0

答えは、IEでは、jQuery ajax呼び出しを使用した後、DOMのコンテンツが完全に読み込まれる前に石積みが完了していたため、ボックスの最終的なサイズがまだ決まっていないということです。

于 2011-03-24T18:59:09.290 に答える