2013-08-29 14 views
7

Tôi có một dự án trong đó yêu cầu là di chuyển chân trang (#footer) lên trên trong khi cuộn xuống trang theo hiệu ứng giống như thị sai. Khi bạn bắt đầu cuộn xuống trang, chân trang sẽ chỉ bắt đầu di chuyển lên trên cho đến khi nó hiển thị trong khung nhìn (phần dưới cùng của).làm thế nào để dính chân trang vào cuối trang trong khi di chuyển nó lên trong một hiệu ứng giống như thị sai?

Chân trang nên đã bao phủ hầu hết <div> trước một nửa và đầy đủ khi nó đã đạt đến đỉnh của chế độ xem.

Trang này có thể có một cấu trúc html tương tự như thế này:

<body> 
    <div id="sectionA" class="div">First section</div> 
    <div id="sectionB" class="div">Second section</div> 
    <div id="sectionC" class="div">Third section 
     <div class="box"></div> 
     <div class="box"></div> 
     <div class="box"></div> 
    </div> 
    <div id="footer" class="div cf">Footer</div> 
</body> 

Các hiệu ứng thị sai giống như đạt được thông qua javascript/jQuery thêm một động giá trị âm đến tài sản top CSS của (tương đối vị trí tốt) chân trang. Đây là mã cho những gì nó quan trọng:

var $window = jQuery(window), 
    $footer = jQuery("#footer"), 
    $viewport = window.innerHeight, 
    $startEffect = $footer.offset().top - $viewport; 

function footerParallax() { 
    var $scrollPos = $window.scrollTop() - $startEffect, 
     $ratio = 0.6; 
    $footer.css({ 
     top: -($scrollPos * $ratio) 
    }); 
} 

$window.scroll(function() { 
    footerParallax(); 
}); 

The (rõ ràng) Vấn đề là ngay sau khi top bất động sản bắt đầu nhận được một giá trị tiêu cực, chân bắt đầu di chuyển ra khỏi đáy của trang.

Tôi đã chuẩn bị một JSFIDDLE và gán màu cho từng phần và body để làm rõ hơn. body (màu đỏ đậm) hiển thị dưới chân trang sau khi cuộn xuống dưới cùng.

Tôi đã thử gì?

  • sửa đổi margin-top thay vì top tài sản: này hiện các trick, tuy nhiên trước đó <div> mà đã được bao phủ bởi các chân trang (#sectionC trong ví dụ trên) trùng lặp nội dung của chân và phá vỡ bố cục của nó bất kể rằng nó không thể nhìn thấy do tài sản z-index của nó (thêm một số hộp nổi trong fiddle để làm cho nó hiển nhiên .... một hack clearfix đã không giúp đỡ.)
  • thiết lập một static vị trí để chân: không top hoặc margin-top có hiệu lực trênYếu tố.
  • Thay đổi/giảm động các height của #sectionC thay vì top của chân để tạo ra hiệu ứng di chuyển lên thứ hai: chân dừng di chuyển càng sớm càng height bằng 0 (không phải kích thước tiêu cực hoặc miếng đệm không tiêu cực được phép)
  • Đã thay đổi height động của các thẻ html và/hoặc body vô ích.

Tôi cũng đã thử một số plugin thị sai như skrollrskrollr-stylesheets và một số loại khác.

Vấn đề với giải pháp này (cùng với những người khác) là nó chuyển tiếp ở vị trí cụ thể (bù) của chân trang được đo bằng px và đặt trong thuộc tính data, nhưng nếu nội dung thay đổi động, ví dụ như sử dụng khối xây plugin để sắp xếp các phần tử trong phần khác của tài liệu, các biện pháp trở nên không chính xác và chân trang có thể bắt đầu di chuyển quá sớm hoặc quá muộn.

Nhân tiện, các kỹ thuật chú thích chân trang CSS khác sẽ không hoạt động bởi vì, tốt, chúng thực sự đẩy chân trang vào cuối trang và ở đây chúng tôi đang làm ngược lại.

Tôi đoán câu hỏi là một trong hai:

  • làm thế nào để giữ cho dính chân để dưới cùng của trang trong khi nó đang di chuyển trở lên? - hoặc -
  • cách giảm khoảng cách thành 0 giữa phần cuối của tài liệu và cạnh dưới của chân trang?

Tôi bắt đầu nghĩ rằng vấn đề này không thực sự là giải pháp, hoặc có thể tôi đã quá mệt mỏi để thấy rõ ràng. Tôi quan tâm đến việc học các giải pháp thay thế hoặc hack thông qua CSS/javascript/jQuery hoặc tất cả những điều trên.

Hãy nhớ rằng tôi không hỏi làm thế nào để tạo hiệu ứng thị sai KHÔNG THAM GIA một cách tiếp cận hoàn toàn khác (hoặc chỉnh sửa mã js hiện có) giải quyết vấn đề vị trí.

QUAN TRỌNG: Xin vui lòng xem xét rằng đây là một trang web WP với một XHTML 1.0 Transitional DOCTYPE, và đã lắp đặt nhiều plugin jQuery khác như xây dựng, scrollTo, jQuery UI, vv Tôi có thể không kiểm soát thay đổi nhiều thứ từ cấu trúc ban đầu (và tôi không muốn) vì vậy ý ​​tưởng là để thực hiện điều này mà không phá vỡ quá nhiều thứ và từ một kịch bản mô-đun.

EDIT # 1: Thêm đồ họa để làm rõ câu hỏi.

  • Hình A. hiển thị một trang web thông thường được cuộn xuống cuối. Hình vuông màu đỏ đại diện cho khung nhìn và chân trang (màu xám) được di chuyển sang bên phải cho mục đích minh họa. Các body có một màu nền màu đỏ (không nhìn thấy trong điều kiện bình thường) chỉ cho mục đích minh họa quá. CHÚ Ý: height của mỗi phần cũng như height của chân trang được xác định bởi nội dung của chúng (biểu mẫu, hình ảnh, văn bản, v.v.), vì vậy KHÔNG được sửa.

  • Hình B. hiển thị vấn đề hiện tại: Nếu chân trang trượt lên theo hiệu ứng thị sai (xem JSFIDDLE để tham khảo) trong khi cuộn xuống dưới trang, nó bắt đầu bao gồm bất kỳ phần nào phía trên nó (KHÔNG sửa đổi riêng height hoặc height của trước đó phần) VÀ nó cũng bắt đầu tách chính nó từ dưới cùng của trang, do đó nền màu của body sẽ hiển thị. LƯU Ý: càng lớn viewport là (chế độ toàn màn hình ví dụ) cao hơn chân được di chuyển lên phía trên (và nhiều nội dung được bao phủ bởi nó)

  • Hình C.là kết quả mong đợi: chân trang sẽ bị kẹt ở cuối trang, nói cách khác, nó phải là phần tử hiển thị cuối cùng sau khi trang đã được cuộn xuống hoàn toàn (chứ không phải nền cơ thể như trong Hình B.) rằng nội dung và kích thước của mỗi phần (bao gồm cả chân trang) nên (lý tưởng) vẫn bị ảnh hưởng. Có nói rằng, thêm đệm dưới cùng cho chân trang hoặc tăng chiều cao của nó không phải là kết quả mong đợi vì nó sẽ phá vỡ bố cục hình ảnh ban đầu của nó.

enter image description here

+0

Rất nhiều văn bản và tôi vẫn không hiểu bạn muốn gì. Tôi có một cái gì đó để nói mặc dù: skrollr không yêu cầu bù đắp trong các giá trị tuyệt đối. Ví dụ, bạn có thể sử dụng 'data-bottom' có nghĩa là" khi phần tử của phần tử ở dưới cùng của khung nhìn " – Prinzhorn

+0

@Prinzhorn: sẽ kiểm tra với skrollr, cảm ơn. PS. nếu bạn không hiểu văn bản, hãy kiểm tra jsfiddle. Những gì tôi muốn không phải là để có nền cơ thể có thể nhìn thấy (khoảng cách màu đỏ giữa cạnh dưới cùng của chân trang và dưới cùng của khung nhìn) nó có ý nghĩa? – JFK

+0

Xin lỗi, tôi vẫn không hiểu. Có thể bạn tìm thấy một trang đã thực hiện những gì bạn đang yêu cầu. – Prinzhorn

Trả lời

2

Làm thế nào được nó giải quyết?

Như tôi đã đề cập trong câu hỏi của tôi, tôi đã quá mệt mỏi để xem câu trả lời rõ ràng nhưng @ DC5 của đưa tôi đi đúng hướng:

To help keep the footer's layout from being affected, 
wrapping the content of the footer in an absolutely 
positioned div does the trick 

Dựa trên nhận xét rằng, câu trả lời trở nên đơn giản hơn so với toàn bộ mã ông đề nghị chỉ cần:

  • (tự động) gói nội dung của các chân trong một vị trí tuyệt đối div sử dụng .wrapInner() phương pháp jQuery
  • hiệu ứng động chân bởi thiết lập các margin-top tài sản thay vì top tài sản

Vì vậy, CSS thêm này:

#footerInnerWrapper { 
    position: absolute; 
    top:0; 
    left:0; 
    width: 100%; 
    background-color: #666 /* same as footer */ 
} 

và mã gốc chỉnh

var $window = jQuery(window), 
    $footer = jQuery("#footer"), 
    $viewport = window.innerHeight, 
    $startEffect = $footer.offset().top - $viewport; 

// add inner wrapper 
$footer.wrapInner('<div id="footerInnerWrapper" />'); 

function footerParallax() { 
    var $scrollPos = $window.scrollTop() - $startEffect, 
     $ratio = 0.6; 
    $footer.css({ 
     // top: -($scrollPos * $ratio) 
     marginTop: -($scrollPos * $ratio) 
    }); 
} 

$window.scroll(function() { 
    footerParallax(); 
}); 

đã làm các trick. Xem JSFIDDLE

+0

Nice! Tôi vui vì tôi đã có thể giúp đỡ. Tôi đã bị mắc kẹt trong toán học rõ ràng cố gắng để làm việc thông qua một giải pháp mà không có margin-top và didn' Tôi nghĩ hãy quay lại và thử thuật toán gốc, đơn giản hơn nhiều. – dc5

4

Phiên bản cập nhật

Dưới đây là một phiên bản cập nhật phù hợp nên tốt hơn yêu cầu của bạn.

Phiên bản này quay lại relative định vị cho phần tử chân trang và sử dụng margin-top để định vị nó.

margin-top được tính toán khỏi vị trí cuộn, chiều cao và vị trí cuộn hiện tại của phần tử trước đó. Sau đó sử dụng một trong hai

  1. chiều cao khung nhìn nếu chân bắt đầu offscreen
  2. giá trị đầu ban đầu của phần tử footer ($startEffect) nếu chân bắt đầu trên màn hình

để xác định giá trị thực tế cho lề -hàng đầu.

Để giúp giữ bố cục của chân không bị ảnh hưởng bởi điều này, việc gói nội dung của chân trang trong div vị trí tuyệt đối đã thực hiện thủ thuật cho mã mẫu được cung cấp.

Example Fiddle

CSS:

#footer > div { 
    position: absolute; 
    top: 0; 
    left: 0; 
    ... 
} 

HTML:

<div id="footer" class="div cf"><div>Footer</div></div> 

Code:

var $window = jQuery(window), 
    $footer = jQuery("#footer"), 
    $viewport = window.innerHeight, 
    $startEffect = $footer.offset().top; 
    $prev = $footer.prev(), 
    $useStartEffect = $startEffect < $viewport; 


function footerParallax() { 
    var $scrollPos = $window.scrollTop() - $startEffect, 
     $ratio = 0.6; 

    var prevOffset = $prev.offset().top + $prev.height() - $window.scrollTop(); 
    var marginTop = 0; 

    if(prevOffset < $viewport && prevOffset < $startEffect) { 
     if($useStartEffect) { 
      marginTop = (prevOffset - $startEffect)*$ratio; 
     } else { 
      marginTop = (prevOffset - $viewport)*$ratio;  
     } 
    } 

    $footer.css({ 
     "margin-top": marginTop + 'px' 
    }); 
} 

$window.scroll(function() { 
    footerParallax(); 
}); 

footerParallax(); 
+0

hầu như, hoạt động tốt trong khu vực kết quả nhỏ nhưng lỗi trong chế độ toàn màn hình http://jsfiddle.net/cnRsr/8/show/ – JFK

+0

Đối với tôi, mã này cho thấy nền tối màu đỏ mà tôi tin rằng không được hiển thị ở bất kỳ điểm. – funkwurm

+0

@funkwurm: Có - Tôi đã đề cập ở trên như là một break từ các yêu cầu. – dc5

0

này làm những gì tôi nghĩ rằng bạn cần, gậy chân khi nó h như cuộn theo quan điểm hoàn toàn:

jsFiddle

Mã nói thêm:

function footerParallax() { 
    var $scrollPos = $window.scrollTop() - $startEffect, 
     $ratio = 0.6, 
     $newTop = -($scrollPos * $ratio), 
     $oldTop = parseInt($footer.css('top')), 
     $nonRelTop = $footer.offset().top - $oldTop, 
     $wanted = ($window.scrollTop()+$viewport-$footer.height()); 
    if ($nonRelTop + $newTop < $wanted) { 
     $('#sectionC').css('display', 'none'); 
     $wanted = ($window.scrollTop()+$viewport-$footer.height()); 
     $nonRelTop = $footer.offset().top - $oldTop; 
     $newTop = $wanted - $nonRelTop; 
    } else { 
     $('#sectionC').css('display', 'block'); 
    }  
    $footer.css('top', $newTop); 
} 

$window.scroll(footerParallax); 

Và trong CSS tôi thêm này để $footer.css('top') sẽ không sản xuất NaN:

#footer { 
    top:0; 
    /* ... */ 
} 

EDIT: Hoàn toàn cách tiếp cận mới sau khi làm rõ hơn về OP. Bây giờ tôi có chân trang vị trí cố định bắt đầu tăng chiều cao để chiếm toàn bộ màn hình khi người dùng đã cuộn qua một nửa tài liệu.HTML, CSS và Javascript đều được cập nhật để đạt được điều này:

jsFiddle

+0

gần như, hoạt động tốt trong khu vực kết quả nhỏ nhưng lỗi trong chế độ toàn màn hình http://jsfiddle.net/funkwurm/cnRsr/10/show/ – JFK

+0

Làm việc toàn màn hình cho tôi trong Chrome trên Mac. Điều gì khiến bạn khó chịu? – funkwurm

+0

Trong chế độ toàn màn hình, khi bạn đến cuối trang, chân trang thực sự dừng di chuyển nhưng phần còn lại của trang không như vậy trước 'div' (#sectionC) hiển thị nếu chiều cao của chân nhỏ hơn khung nhìn toàn màn hình (Firefox) và Chrome trong Windows) – JFK