2010-04-22 37 views
8

Tôi gặp phải sự cố thanh cuộn lạ. Tôi đang xây dựng một trang sử dụng jQuery và PHP để tự động tải hình ảnh vào một DIV tuần tự. DIV này là một chiều cao cố định nhưng sử dụng một thanh cuộn cho chiều rộng biến của nó. Vấn đề là thanh cuộn không đặt lại sau khi làm mới động của DIV. Vì vậy, khi người dùng cuộn và sau đó làm mới với nội dung mới, vị trí thanh cuộn vẫn liên tục thay vì đặt lại về bên trái.Làm thế nào để đặt lại vị trí thanh cuộn liên tục sau khi làm mới div trong FF3?

Điều này dường như chỉ xảy ra trong FF3. Thanh cuộn đặt lại hoàn toàn tốt trong Chrome, Safari và IE8.

Đối với mỗi refresh, DIV ẩn, làm trống, có kích thước bằng CSS, sau đó tuần tự nối với hình ảnh.

Tôi đã thử đặt lại white-space: normal trước nowrap, chơi đùa với overflow, và cũng jQuery scrollLeft vô ích. Nó vẫn hoạt động lạ lùng trong FF3, và chỉ FF3.

Nhấp vào hình thu nhỏ, di chuyển thanh cuộn rồi nhấp vào một ngón tay cái khác.

Cảm ơn bạn đã trợ giúp!

+1

Chà, điều đó rất lạ. Đoán tốt nhất của tôi là chỉ đơn giản là lấy phần tử và đặt scrollTop và scrollLeft về 0, theo cách này không nên phiền toái. btw, trang web đẹp! Tôi thích điều khiển băm. – Tom

+0

Vâng, tôi đã thử thực hiện ScrollLeft trước đây. Tôi có thể xem lại một lần nữa. Plugin hashchange là tuyệt vời, eh ?. Tôi nên tặng một số tiền bia cho Ben Alman vì nó đã cứu tôi khỏi phải viết tất cả những thứ bỏ phiếu đó! – rcon

Trả lời

5

OK, sau khi xem xét các đề xuất của David M, tôi đã tìm ra. Vì #interiors là con của #content, nó cũng bị ẩn. Vì vậy, tôi đã phải show trước tiên, đặt scrollLeft rồi hide lại một lần nữa. Một chút kludgy, nhưng bất cứ điều gì hoạt động ...

$('#landing, #interiors, #caption').empty(); 
$('#content').show() 
$('#interiors').scrollLeft(0); 
$('#interiors, #caption').hide(); 

Về dữ liệu đã lưu trong FF3, tôi vẫn chưa rõ về điều đó. Lưu rằng một cho một ngày mưa ...

Cảm ơn

0

Khi tôi gõ này vào bảng điều khiển firebug tương tác:

var e = $('#interiors')[0] 
e.scrollLeft = 0 
e.scrollTop = 0 

có vẻ như để thiết lập lại các thanh cuộn một cách chính xác. Yếu tố này cũng có thể cần phải được hiển thị với một display của block trước khi thiết scrollLeft nhưng tôi không chắc chắn - Tôi nghĩ rằng khi tôi đã cố gắng để làm điều này mà Firefox khôi phục lại các giá trị cuối cùng khi các yếu tố với overflow: auto thay đổi từ ẩn để hiển thị.

EDIT: Có một vài điều bạn có thể cố gắng buộc Firefox đặt lại giá trị. Trước hết, bạn có thể loại bỏ và sau đó lại thêm yếu tố "nội dung" khi thay đổi băm:

var e = $('#interiors')[0] 
var p = e.parentNode 
p.removeChild(e) 
p.insertBefore(e, p.firstChild) // insert again before the caption 

Thứ hai, bạn có thể thiết lập lại các giá trị scrollLeft/scrollTop-0 trước khi sử dụng $('#interiors').empty() hoặc $('#interiors').hide() nên nó doesn' t lưu các giá trị.

+0

Tôi đã phân tích nhiều hơn trong Firebug. Điều xảy ra là khi DIV làm mới, giá trị scrollLeft đặt lại về 0 cho đến khi cần thanh cuộn. Nếu cần thanh cuộn, thanh cuộn sẽ khôi phục giá trị trước đó (bạn sẽ thấy nó chuyển đổi). Nếu thanh cuộn không cần thiết, giá trị nằm ở mức 0 và các lần làm mới tiếp theo sẽ sử dụng giá trị được lưu trữ mới này bằng không cho dù thanh cuộn có cần thiết hay không. Bây giờ tôi muốn tìm ra cách để không hoặc chặn giá trị cũ. – rcon

+0

@rcon: Tôi đã thêm một số đề xuất khác để đặt lại thanh cuộn, vui lòng trả lời nếu bạn vẫn gặp sự cố – cryo

+0

M: Tôi nghĩ rằng việc thực hiện 'remove()' cũng sẽ hoạt động, nhưng tiếc là không. Người ta sẽ nghĩ rằng việc loại bỏ một phần tử từ DOM sẽ xóa dữ liệu liên tục. Đó là một ý tưởng hay, vì vậy tôi sẽ thử chơi với 'clone()' tiếp theo. Về đề nghị khác, xem trả lời của tôi cho câu trả lời của Már Örlygsson. Cảm ơn những ý tưởng! – rcon

0

Tôi đã chỉnh sửa javascript để đặt lại giá trị scrollLeft/scrollTop trước khi ẩn/xóa/đặt HTML. Tôi đặt tất cả các hoạt động đó vào một hàm duy nhất để cố gắng tìm ra những gì đang xảy ra.

Tôi đã thử nghiệm điều này trong Firefox và có vẻ như để sửa chữa những vấn đề di chuyển, nhưng tôi đã không kiểm tra bất kỳ trình duyệt khác. Nó sẽ làm việc mặc dù.

Có vẻ như tôi đã đúng trong câu trả lời khác của tôi mà bạn cần phải thiết lập lại scrollLeftscrollTop giá trị trong Firefox trong khi các phần tử với một tràn của auto được hiển thị với một màn hình của block mặc dù, vì nó dường như để khôi phục lại cái cũ các giá trị khi được hiển thị bất kể giá trị cuộn có thay đổi khi bị ẩn:

function setInteriors(html, hide) { 
    var i = $('#interiors'); 

    // Reset the scrollbar positions BEFORE clearing/setting the HTML 
    i.scrollLeft(0); 
    i.scrollTop(0); 

    // Set the HTML if provided, otherwise empty 
    if (html) i.html(html); 
    else i.empty(); 

    // Hide the element if hide is `true` 
    if (hide) i.hide(); 
} 

function showContent(nav) { 
    if($.browser.safari) // webkit browsers 
    { 
     bodyelement = $("body") 
    } 
    else 
    { 
     bodyelement = $("html, body") 
    } 
    bodyelement.animate({ scrollTop: 0 }, 300); 

    setInteriors(null, true); 
    $('#caption').hide(); 
    $('#caption').empty(); 
    $('#landing').empty(); 

    // Detect document window size and use appropriate image heigh images 

    if ($(window).height() < 832) // size of the document window, not browser window 
    {        // threshold for 600px images + 5 caption lines 
     var imageHeight = 500; 
    } 
    else 
    { 
     var imageHeight = 600; 
    } 

    // Show #content so we can show/hide #interiors and #caption individually 

    $('#content').show(); 
    if ((nav == "about") || (nav == "contact")) 
    { 
     setInteriors(null); // for fast back/forward button mashing 

     switch(nav) 
     { 
      case "about": 
       setInteriors($('#hidden-about').html()); // Load from hidden div 
       break; 
      case "contact": 
       setInteriors($('#hidden-contact').html()); 
       break; 
     } 
     $('#interiors').css('height', '100%'); // Dimensions for "about" and "contact" 
     $('#interiors').css('width', '645px'); 
     $('#interiors').css('white-space', 'normal'); 
     $('#interiors').fadeIn(200); 
    } 
    // TO DO: Maybe separate #interiors to two classes for dynamic changes? 
    else 
    { 
     switch(imageHeight) 
     { 
      case 500: 
       $('#interiors').css('height', '520px'); // Dimensions for gallery 
                 // Extra 20px for scrollbar 
       break; 
      case 600: 
       $('#interiors').css('height', '620px'); 
       break; 
     } 
     $('#interiors').css('width', '100%'); 
     setInteriors(null); // for fast back/forward button mashing 
     $('#interiors').show(); 
     nav = (location.hash).substring(1); // for fast back/forward button mashing 
     $('#caption').html('<P class="caption">' + $('#hidden-' + nav).html() + '</P>'); // load hidden captions 
     $('#caption').fadeIn(300); // show caption before images 

     getImages = "http://www.shadowshapes.com/uttwerk/getImages.php?id=" + nav + "&height=" + imageHeight; 
     $.getJSON(getImages, function(json) { 
      var max = json.length; 
      if(max > 0) 
      { 
       loadImage(0, max, nav); 
      } 

      function loadImage(index, max, nav) { 
       if ((location.hash).substring(1) == nav) // until hash changes, load current nav 
       { 
        if(index < max) 
        { 
         var newimg = new Image(); 
         $(newimg).load(function() { 
          if ((location.hash).substring(1) == nav) // after current image loads 
          {          // continue if no hashchange 
           $('#interiors').append(this); 
           $('#interiors').css('white-space', 'nowrap'); 
           $(this).hide(); 
           if (max - index > 1) // add space after each image except last one 
           { 
            $(this).css('margin-right', '20px'); 
           } 
           $(this).css('vertical-align', 'top'); 
           $(this).fadeIn(200, function() { 
             loadImage(index + 1, max, nav); 
           }); 
          } 
         }).attr('src', json[index]); 
        } 
       } 
      } 
     }); 
    } 
} 

function arrangeStars() { 
    $('img.star').each(function() { 
     thumbposition = $(this).siblings('a.nav').children('img').position(); 
     $(this).css("top", (thumbposition.top - 9)); 
     $(this).css("left", (thumbposition.left - 9)); 
    }); 
} 

function placeStar(nav) { 
    // clear all stars on hash change 

    if ($('div.thumb').children('img').hasClass("visiblestar")) { 
     $('div.thumb').children('img').removeClass("visiblestar").addClass("hiddenstar"); 
    } 
    // attach star to selected thumbnail 

    var test = $('div#_' + nav); 
    if ($(test).children('img').hasClass("hiddenstar")) { 
     $(test).children('img').removeClass("hiddenstar").addClass("visiblestar"); 
    } 
} 

$(document).ready(function() { 

    //$.imgpreload(['', ''], {each: null, all:null}); 

    // bind hover event for empty/contact/about hash only 

    $(arrangeStars()); // positions stars in the corner of each thumbnail 

    $('img.thumb, img.thumbwithborder').hover(
     function() { 
      var nav = (location.hash).substring(1); 
      if ((nav == '') || (nav == "about") || (nav =="contact")) { 
       nav = $(this).parent().parent().attr("id"); 
       $('div.thumb#' + nav).children('img').removeClass('hiddenstar').addClass('visiblestar'); 
      } 
     }, 
     function() { 
      var nav = (location.hash).substring(1); 
      if ((nav == '') || (nav == "about") || (nav =="contact")) { 
       nav = $(this).parent().parent().attr("id"); 
       $('div.thumb#' + nav).children('img').removeClass('visiblestar').addClass('hiddenstar'); 
      } 
     } 
    ); 

    // hash change event triggers all the navigation and content switching 

    jQuery.hashchangeDelay = 50; 

    $(function() { 
     $(window).bind('hashchange', function() { 
      var nav = (location.hash).substring(1); 
      if (nav != '') 
      { 
       placeStar(nav); 
       $('#content').fadeOut(200, function() { 
        showContent(nav); 
       }); 
      } 
     }); 
    }) 

    if (location.hash != '') 
    { 
     $(window).trigger('hashchange'); 
    } 

    // load landing content 

    $(function() { 
     $('#content').hide(function() { 
      var landingdiv = $(document.createElement('div')).attr({id: 'landing'}); 
      landingdiv.html($('#hidden-landing').html()); 
      landingdiv.clone().appendTo('#interiors'); 
      $(this).fadeIn(200); 
      }); 
    }); 
}); 
+0

@Davin M: Vâng, bạn hoàn toàn chính xác. Phần tử phải là 'display: block'. Chức năng của bạn hoạt động, nhưng chỉ miễn là '# content' không bị ẩn. Xem câu trả lời của tôi. Cảm ơn bạn đã giúp đỡ! – rcon

0

Chỉ cần gặp phải cùng một vấn đề và giải quyết nó bằng cách thiết lập một timeout SAU#interiors đã hiển thị trên trang.

$("#interiors").show(function(){ 
    setTimeout(function(){$(this).scrollLeft(0);},10);}); 
}); 
Các vấn đề liên quan