0

レイアウトを崩さずに、画像をさまざまな画面サイズにうまく合わせようとしています。次の CSS が役に立ちます。

.viewer .main img {
    max-width: 100%;
    height: auto;
}

しかし問題は、このイメージが変わることです。既存のものを再利用する代わりに、画像が変更されるたびに新しい img 要素を作成するために Javascript を少し使用します。(これは、私がやっていることに対してもう少し信頼できるようです)。ブラウザーは画像が読み込まれるまで画像のサイズを認識しないため、その間に明らかなちらつきが発生します。HTML で画像の幅と高さの属性を設定することで、これに対処します。上記の CSS ルールがなくても、問題なく動作します。

その CSS では、ちらつきがまだ残っています。何らかの理由で、新しい img 要素を作成すると、CSS によってブラウザーが幅と高さの属性を無視するように見えるので、. 以前と同じように、縦横比を無視してしまいます。

状況を説明する jsfiddle を次に示します: http://jsfiddle.net/7sDtN/ そこにある画像の 1 つは非常に大きい (138 MB) ため、従量制接続を使用している場合は注意してください :)

私が気に入っているのは、HTML で設定した寸法に従って画像を拡大縮小することです。できればいい意味で。Javascript ソリューションは世界の終わりではありません (もちろん、私はすでにそれを使用しています) が、非常に優れたエレガントな CSS ソリューションがあれば.

4

2 に答える 2

1

画像を専用のコンテナーにラップすることで、これを回避する方法で解決することになりました。そのコンテナーの寸法は Sven の回答のように計算されますが、最終的にはブラウザーが引き継ぐことができます。このようにして、レイアウトの変更は最小限に抑えられ、最終的には画像間のわずかな時間だけ、このクレイジーなことを行うだけになります。

完全を期すために、コードの大きな塊を次に示します。

function Viewer(container) {
    var viewer = this;

    container = $(container);

    var pictureBox = $('.picture', container);
    var img = $('<img>').appendTo(pictureBox);

    var hide = function() {
        /* [snip] */
    }

    var getPictureDisplayHeight = function(picture) {
        var ratio = picture.data.h / picture.data.w;
        var displayWidth = Math.min(pictureBox.width(), picture.data.w);
        var displayHeight = Math.min(displayWidth * ratio, picture.data.h);
        return displayHeight;
    }

    var stopLoadingTimeoutId = undefined;
    var stopLoadingTimeout = function() {
        container.removeClass('loading');
    }

    var showPicture = function(picture) {
        var imgIsChanging = img.data('picture') != picture;

        container.show();

        /* This code expects to be cleaned up by stopLoadingTimeout or onImgLoaded, which will not fire if img src doesn't change */
        if (imgIsChanging) {
            container.addClass('loading');
            window.clearTimeout(stopLoadingTimeoutId);
            stopLoadingTimeoutId = window.setTimeout(stopLoadingTimeout, 3000);
        }

        pictureBox.css({
            'min-height' : pictureBox.height()
        });

        var displayHeight = getPictureDisplayHeight(picture);
        if (displayHeight > pictureBox.height()) {
            /* Grow pictureBox if necessary */
            pictureBox.stop(true, false);
            pictureBox.animate({
                'height' : displayHeight
            }, 150);
        }

        /* I wish I could set width and height here, but it causes the current image to stretch */
        img.attr({
            'src' : picture.fullPath
        }).data('picture', picture);
    }

    var onImgLoaded = function(event) {
        /* The load event might not be fired, so nothing here should be essential */

        var picture = img.data('picture');

        container.removeClass('loading');

        var displayHeight = getPictureDisplayHeight(picture);
        pictureBox.stop(true, false);
        pictureBox.animate({
            'min-height' : 0,
            'height' : displayHeight
        }, 150, function() {
            pictureBox.css('height', 'auto');
        });

        window.clearTimeout(stopLoadingTimeoutId);
    }

    var onImgClicked = function(event) {
        selectNextPicture();
    }

    var onPictureSelectedCb = function(picture) {
        if (picture) {
            showPicture(picture);
        } else {
            hide();
        }
    }

    var init = function() {
        img.on('click', onImgClicked);
        img.on('load', onImgLoaded);
    }
    init();
}

関連する HTML:

<div class="viewer" style="display: none;">
    <div class="picture"></div>
    <div class="caption"><div class="caption-text"></div></div>
</div>

そしてCSS:

.viewer .picture img {
    display: block;
    margin: 0 auto;
    max-width: 100%;
    height: auto;
}

このようにして、次の画像のサイズまたは現在の画像のサイズのいずれかである画像の周りにスペースを残し、新しい画像が読み込まれる前に発生するように見える小さなサイズは決して残しません (何らかの理由で発生し続けました)。これにはおそらく何百万もの解決策があり、私のものは特に簡単ではないように感じます。

于 2012-07-18T19:29:49.420 に答える
0

私があなたを正しく理解していれば、次のコードを使用して目標を達成できます

HTML

<div id="Wrapper">
    <img id="MyPic" src="http://www.davidstorey.tv/wp-content/uploads/2012/05/image.php_.jpeg" alt="" width="300" height="200" />
</div>

CSS

body{
    width:100%;
}

#Wrapper{
    width:98%;
    border:1px solid red;
}

jQuery

$("document").ready(function(){
    var ratio=$("#MyPic").width() / $("#MyPic").height();
    $("#MyPic").css("width","100%");
    $("#MyPic").css("height", $("#MyPic").width()/ratio+"px");
});

ここにjsfiddleへのリンクがあります

于 2012-07-16T19:11:29.720 に答える