9

画像のホバー効果を作成していますが、問題があります。特定の画像にカーソルを合わせると、回避したいスクロールバーが表示されますが、その方法がわかりません。ビューポートと計算に関係していると思いますが、それがどのように行われるかはわかりません。

例はこちら

JSBin コード

コードは次のとおりです。

$('.simplehover').each(function(){
    var $this = $(this);        
    var isrc = $this[0].src, dv = null;
                        
    $this.mouseenter(function(e){
        dv = $('<div />')
            .attr('class', '__shidivbox__')
            .css({
                display: 'none',
                zIndex : 9999,
                position: 'absolute',
                top: e.pageY + 20,
                left: e.pageX + 20
            })
            .html('<img alt="" src="' + isrc + '" />')
            .appendTo(document.body);           
        dv.fadeIn('fast');
    })
    .mouseleave(function(){
        dv.fadeOut('fast');
    });         

});

スクロールバーが表示されないような場所にホバーした画像が表示されるようにする方法を教えてください。(もちろん、画像サイズが非常に大きい場合、スクロールバーを避けることはできません)

スクロールバーをできるだけ避けながら、元の画像をズームで表示したいだけです。

これをjQueryプラグインに変換する予定であるため、プラグインのユーザーに強制的overflowhidden. 解決策は、後でプラグインに組み込むことができるviewportlefttopscroll widthheightウィンドウの幅/高さのプロパティに関係しています。


アップデート:

私はこれを思いついた:

http://jsbin.com/upuref/14

ただし、これは非常にハックであり、100% 完璧ではありません。より良いアルゴリズム/ソリューションを探しています。これを非常にうまく行う多くのホバープラグインを見てきましたが、私はこれが得意ではないので、完全にうまく行うことはできません. たとえば、Hover Zoom Chrome プラグインは、ホバーした画像をサイズに基づいて適切な場所に表示するという素晴らしい仕事をします。

4

4 に答える 4

3

このような:

html{overflow-x:hidden;}
html{overflow-y:hidden;}

これらの定義を CSS に追加するだけで、完了です。

サイズ変更による更新:これは、画像のサイズを変更し、水平方向と垂直方向の両方で位置を変更するための mouseenter コードです。これで、HOVER 画像が表示される場所に関係なく、サイズが変更され、常に完全かつカットされていない状態で表示されるように配置されます。スクロールバーに関する限り、ページに収まりきらないほど多くのサムネイルを表示すると、HOVER 画像が表示される前でもスクロールバーが表示されます。

最終更新と作業更新:スクロールバーが非表示になっていることに注目していたため、ビューポートに含めることができるよりも多くのサムネイルを配置するとスクロールバーが表示されるという事実を見落としていたと思います。したがって、ユーザーはスクロールダウンできるため、ホバー画像の位置を計算するときは、サイズ変更だけでなく、scrollTop の位置も考慮する必要があります。FINAL JSBIN HERE、スクロールトップがどこにあるか、ビューポートのサイズに関係なく、すべての写真がサイズ変更され、完全に表示されます。

$this.mouseenter(function () {

    dv = $('<div />')
          .attr('class', '__shidivbox__')
          .css({
            'display': 'none',
            'z-index': 9999,
            'position': 'absolute',
            'box-shadow': '0 0 1em #000',
            'border-radius': '5px'
          })
          .html('<img alt="" src="' + isrc + '" />')
          .appendTo(document.body);

    var DocuWidth = window.innerWidth;
    var DocuHeight = window.innerHeight;

    var DvImg = dv.find('img');

    var TheImage = new Image();
    TheImage.src = DvImg.attr("src");

    var DivWidth = TheImage.width;
    var DivHeight = TheImage.height;

    if (DivWidth > DocuWidth) {

        var WidthFactor = (DivWidth / DocuWidth) + 0.05;
        DivHeight = parseInt((DivHeight / WidthFactor), 10);
        DivWidth = parseInt((DivWidth / WidthFactor), 10);
    }

    var ThumbHeight = $this.height();
    var ThumbWidth = $this.width();
    var ThumbTop = $this.position().top;
    var ThumbLeft = $this.position().left;

    var SpaceAboveThumb = ThumbTop - $(document).scrollTop();
    var SpaceBelowThumb = DocuHeight - ThumbTop - ThumbHeight + $(document).scrollTop();

    var MaxHeight = Math.max(SpaceAboveThumb, SpaceBelowThumb);

    if (DivHeight > MaxHeight) {

        var HeightFactor = (DivHeight / MaxHeight) + 0.05;
        DivHeight = parseInt((DivHeight / HeightFactor), 10);
        DivWidth = parseInt((DivWidth / HeightFactor), 10);
    }

    var HoverImgLeft = 0;
    var HoverImgTop = 0;

    if (SpaceBelowThumb > SpaceAboveThumb) {
        HoverImgTop = ThumbTop + ThumbHeight;
    } else {
        HoverImgTop = ThumbTop - DivHeight;
    }

    HoverImgTop = (HoverImgTop < 0) ? 0 : HoverImgTop;

    HoverImgLeft = (DocuWidth - DivWidth) / 2;

    dv.find('img').css({
        'width': DivWidth,
        'height': DivHeight,
        'border-radius': '5px'
    });

    dv.css({
        'left': HoverImgLeft,
        'top': HoverImgTop
    });

    dv.fadeIn('fast');
});
于 2012-09-25T15:45:15.893 に答える
1

利用可能な幅に基づいて画像を配置できます: http://jsbin.com/upuref/19/

このデモでは、画像の配置に使用できるスペースを考慮しています (つまり、ウィンドウの幅から画像の幅を差し引いたもの)。また、画像がロードされたdivにのみポップアップがフェードインを開始するように、イベントの順序を改善しました。

于 2012-09-25T16:29:21.770 に答える
1

うーん、これは楽しそうですね。とにかく、これが私の答えです。私はこれを数日間見てきましたが、私も参加したいと思います. 以下は、ホバリング画像がビューポートから出ないようにし、画像の幅が表示に使用可能なスペースよりも大きい場合、画像の表示のサイズが変更されます (コードをコメントアウトできます)。コード内の「サイズ変更」という単語を探してください)。

var $document = $(document);
$('.simplehover').each(function(){
    var $this = $(this);
    // make sure that element is really an image
    if (! $this.is('img')) return false;

    var isrc = $this[0].src, ibox = null;

    if (! isrc) return false;
    ibox = $('<img />')
            .attr('class', 'simpleimagehover__shidivbox__')
            .css({
                display: 'none',
                zIndex : 99,
                MozBoxShadow: '0 0 1em #000', 
                WebkitBoxShadow: '0 0 1em #000',
                boxShadow: '0 0 1em #000',
                position: 'absolute',
                MozBorderRadius : '10px',
                WebkitBorderRadius : '10px',
                borderRadius : '10px'
            })
            .attr('src', isrc)
            .appendTo(document.body);          

    $this.bind('mouseenter mousemove', function(e) {
        $('.simpleimagehover__shidivbox__').hide();

        var left = e.pageX + 5, 
            top = e.pageY + 5,
            ww = window.innerWidth,
            wh = window.innerHeight,
            w = ibox.width(),
            h = ibox.height(),
            overflowedW = 0,
            overflowedH = 0;

        // calucation to show element avoiding scrollbars as much as possible - not a great method though
        if ((left + w + $document.scrollLeft()) > ww)
        {
            overflowedW = ww - (left + w + $document.scrollLeft());
            if (overflowedW < 0)
            {
               left -= Math.abs(overflowedW);
            }
        }

        // 25 is just a constant I picked arbitrarily to compensate pre-existing scrollbar if the page itself is too long
        left -= 25;
        left = left < $document.scrollLeft() ? $document.scrollLeft() : left;

        // if it's still overflowing because of the size, resize it
        if (left + w > ww)
        {
            overflowedW = left + w - ww;
            ibox.width(w - overflowedW - 25);
        }


        if (top + h > wh + $document.scrollTop())
        {
            overflowedH = top + h - wh - $document.scrollTop();
            if (overflowedH > 0)
            {
                top -= overflowedH;
            }
        }

        top = top < $document.scrollTop() ? $document.scrollTop() : top;
        ibox.css({
            top: top,
            left: left
        });

        ibox.show();
    }); 


    $('.simpleimagehover__shidivbox__').mouseleave(function(){
        $('.simpleimagehover__shidivbox__').hide();
    });

    $document.click(function(e){
        $('.simpleimagehover__shidivbox__').hide();
    });

    $document.mousemove(function(e){
        if (e.target.nodeName.toLowerCase() === 'img') {
            return false;
        }

        $('.simpleimagehover__shidivbox__').hide();
    });
});

私のソリューション自体は完璧ではありませんが、ビューポートを決定するのに役立つ何かが見つかるかもしれません。また、コードのパフォーマンスについて考える必要があるかもしれません。これは作成中のプラグインであるため、公開する前にいくつかの最適化を行う必要があります。基本的に、遅くないことを確認してください。

于 2012-09-26T14:28:47.473 に答える