2010-06-04 29 views
19

Tôi có một bản trình diễn rất đơn giản sử dụng các phép biến đổi và chuyển đổi Webkit để cuộn ngang mượt mà giữa các 'bảng' (divs).Cách sửa lỗi nhấp nháy khi sử dụng chuyển đổi và chuyển đổi Webkit

Lý do tôi muốn đi tuyến đường này trái ngược với hệ thống điều khiển Javascript là vì hiệu suất của iPad và Javascript khá kém, nhưng biến đổi css và chuyển tiếp trơn tru như lụa. Đáng buồn thay, mặc dù tôi nhận được rất nhiều nhấp nháy trên iPad với Demo của tôi.

Bạn có thể thấy the demo here

Bạn sẽ cần săn hay và iPad để xem nó trong hành động. Tôi chưa bao giờ thấy điều này xảy ra trong bất kỳ trình diễn nào cho các biến đổi và chuyển tiếp, vì vậy tôi hy vọng rằng điều này có thể khắc phục được.

Dù sao, đây là mã hỗ trợ điều ....

HTML trông như thế này.

<html> 
    <head> 
     <title>Swipe Demo</title> 
     <link href="test.css" rel="stylesheet" /> 
     <link href="styles.css" rel="stylesheet" /> 
     <script type="text/javascript" src="jquery.js"></script> 
     <script type="text/javascript" src="functions.js"></script> 
     <script type="text/javascript" src="swiping.js"></script> 
    </head> 
    <body> 


    <div id="wrapper"> 
     <div class='panel one'> 
      <h1>This is panel 1</h1> 
     </div> 

     <div class='panel two'> 
      <h1>This is panel 2</h1> 
     </div> 

     <div class='panel three'> 
      <h1>This is panel 3</h1> 
     </div> 

     <div class='panel four'> 
      <h1>This is panel 4</h1> 
     </div> 
    </div> 

    </body> 
</html> 

CSS trông như thế này

body, 
    html 
     { 
      padding: 0; 
      margin: 0; 
      background: #000; 
     } 

    #wrapper 
     { 
      width: 10000px; 
      -webkit-transform: translateX(0px); 
     } 

    .panel 
     { 
      width: 1024px; 
      height: 300px; 
      background: #fff; 
      display: block; 
      float: left; 
      position: relative; 
     } 

và javascript trông như thế này

// Mouse/iPad Touch 
var touchSupport = (typeof Touch == "object"), 
touchstart = touchSupport ? 'touchstart' : 'mousedown', 
touchmove = touchSupport ? 'touchmove' : 'mousemove', 
touchend  = touchSupport ? 'touchend' : 'mouseup'; 

$(document).ready(function(){ 

    // set top and left to zero 
    $("#wrapper").css("top", 0); 
    $("#wrapper").css("left", 0); 

    // get total number of panels 
    var panelTotal; 
    $(".panel").each(function(){ panelTotal += 1 }); 

    // Touch Start 
    // ------------------------------------------------------------------------------------------ 

    var touchStartX; 
    var touchStartY; 
    var currentX; 
    var currentY; 
    var shouldMove = false; 
    document.addEventListener(touchstart, swipeStart, false); 
    function swipeStart(event){ 

     touch = realEventType(event); 

     touchStartX = touch.pageX; 
     touchStartY = touch.pageY; 
     var pos = $("#wrapper").position(); 
     currentX = parseInt(pos.left); 
     currentY = parseInt(pos.top); 

     shouldMove = true; 

    } 

    // Touch Move 
    // ------------------------------------------------------------------------------------------ 

    var touchMoveX; 
    var touchMoveY; 
    var distanceX; 
    var distanceY; 
    document.addEventListener(touchmove, swipeMove, false); 
    function swipeMove(event){ 
     if(shouldMove){ 
      touch = realEventType(event); 
      event.preventDefault(); 

      touchMoveX = touch.pageX; 
      touchMoveY = touch.pageY; 

      distanceX = touchMoveX - touchStartX; 
      distanceY = touchMoveY - touchStartY;  
      movePanels(distanceX); 

     } 
    } 

    function movePanels(distance){ 
     newX = currentX + (distance/4);  
     $("#wrapper").css("left", newX); 
    } 


    // Touch End 
    // ------------------------------------------------------------------------------------------ 

    var cutOff = 100; 
    var panelIndex = 0; 
    document.addEventListener(touchend, swipeEnd, false); 
    function swipeEnd(event){ 

     touch = (touchSupport) ? event.changedTouches[0] : event; 

     var touchEndX = touch.pageX; 
     var touchEndY = touch.pageY; 

     updatePanelIndex(distanceX); 

     gotToPanel(); 

     shouldMove = false; 

    } 

    // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 

    function updatePanelIndex(distance){ 

     if(distanceX > cutOff) 
      panelIndex -= 1; 

     if(distanceX < (cutOff * -1)){ 
      panelIndex += 1; 
     } 

     if(panelIndex < 0){ 
      panelIndex = 0; 
     } 

     if(panelIndex >= panelTotal) 
      panelIndex = panelTotal -1; 

      console.log(panelIndex); 

    } 

    // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 

    function gotToPanel(){ 

     var panelPos = getTotalWidthOfElement($(".panel")) * panelIndex * -1; 

     $("#wrapper").css("-webkit-transition-property", "translateX"); 
     $("#wrapper").css("-webkit-transition-duration", "1s"); 
     $("#wrapper").css("-webkit-transform", "translateX("+panelPos+"px)"); 

    } 

}); 

function realEventType(event){ 
    e = (touchSupport) ? event.targetTouches[0] : event; 
    return e; 
} 

Trả lời

8

Hãy thử sử dụng translate3d thay vì translateX. Nó xuất hiện chỉ dịch3d là phần cứng tăng tốc trên iPad 3.2.

5

Như đã đề cập ở trên, tốt hơn nên sử dụng Translate3d do tăng tốc phần cứng giúp chuyển tiếp mượt mà hơn.

Tuy nhiên, nhấp nháy được gây ra khi div đang hoạt ảnh lớn hơn màn hình. Vì vậy, nếu bạn có một khu vực có thêm tối đa 3,5 độ rộng màn hình mà bạn muốn chuyển đổi theo chiều ngang, nó sẽ được chia thành 4 divs như thế này

[1] [2] [3] [. 5]

Không có div nào vượt quá chiều cao hoặc chiều rộng màn hình.

Xin lỗi vì độ trễ trong việc đăng câu trả lời này. Tôi đã hoàn toàn quên mất nó cho đến khi tôi nhận được thông báo "câu hỏi phổ biến".

+0

khổng lồ - Tôi đang chạy vào cùng một vấn đề, nhưng tôi không chắc là tôi hiểu câu trả lời này. Tôi có bố cục tương tự - một khu vực xem rộng 300% rộng như khung nhìn/màn hình và tôi đang tạo hoạt ảnh cho khu vực đó sang trái và phải. Nếu tôi chia nó thành 3 div, mỗi màn hình rộng như màn hình - thì bạn có gợi ý rằng tôi làm sinh động từng cá nhân không? – mattstuehler

1

Tôi bị nhấp nháy để biến mất trước tiên bằng cách để chế độ xem ở trạng thái "3D". Đầu tiên tôi có tất cả các quan điểm của tôi có bảo toàn 3D. Sau đó, tôi có mã này,

MyNamespace.flickerFixer = function(children) { 
children.css({ 
    "-webkitTransform": "translate3D(0px, 0px, 0px)", 
    "-webkit-transition": "1s ease-in-out" 
}); 
} 

Và sau đó tôi khởi tạo nó trước khi thực hiện hình ảnh động webkit:

MyNamespace.flickerFixer($this.parent(".ui-content")); 
45

@gargantaun là đúng, Webkit nhấp nháy nếu các yếu tố bạn muốn động lớn hơn màn hình. Nhưng có một sửa chữa dễ dàng. Chỉ cần thêm:

-webkit-backface-visibility: hidden; 

cho phần tử này và bạn tốt!

+0

Tôi tò mò, làm cách nào bạn tìm ra điều này? – gargantuan

+0

Tìm thấy nó [ở đây] (http://stackoverflow.com/questions/3461441/prevent-flicker-on-webkit-transition-of-webkit-transform), cần nó cho [trang web công ty của chúng tôi] (http: // www .beenetwork.eu) (chờ một vài giây cho hoạt ảnh). –

+9

Tự chịu rủi ro! Khi IOS7 xuất hiện, ứng dụng của chúng tôi đã bắt đầu gặp sự cố do lỗi bộ nhớ. Nó thường sử dụng 10-15 MB, nhưng bản ghi sự cố IOS báo cáo sử dụng ~ 600 MB. Sau khi một số đào, nó bật ra rằng hack này khả năng hiển thị backface (mà chúng tôi theo nghĩa đen có một liên kết đến chủ đề SO này từ mã nguồn của chúng tôi) là nguyên nhân, hoặc ít nhất, loại bỏ nó làm cho crashing đi. Không chắc chắn tại sao, và nó chỉ là IOS7. Tôi nghĩ rằng phải có một số lỗi rò rỉ bộ nhớ hoặc một cái gì đó trong ngã ba của Apple Webkit. Rất nhiều nhà phát triển đang phàn nàn về trình duyệt Safari của IOS7 hiện nay. – greim

1

Ngày nay, với iOS8, một giải pháp tốt khác là áp dụng overflow: hidden cho các yếu tố bị buộc tội (hoặc vùng chứa của chúng).

0

Dựa trên @tobiasahlin nói chuyện tại WebExpo.

Safari nhấp nháy vấn đề sửa chữa giải pháp tốt nhất là

transform: translateZ(0); 
Các vấn đề liên quan