AlloyTouch實戰–60行代碼搞定QQ看點資料卡

kinner 7年前發布 | 8K 次閱讀 JavaScript開發 JavaScript

如你體驗所見,流程的滾動的同時還能支持頭部的動畫?不斷地加載新數據還能做到流暢的滑動!怎么做得的?使用AlloyTouch CSS 0.2.0及以上版本便可!

頭部動畫

加載更多

實現代碼

var infoList = document.getElementById("infoList"),
    mockHTML = infoList.innerHTML,
    scroller = document.getElementById("scroller"),
    header = document.getElementById("header"),
    userLogo = document.getElementById("user-logo-wrapper"),
    loading = false,
    alloyTouch = null;
 
Transform(scroller, true);
Transform(header);
header.originY = -70;
header.translateY = -70;
Transform(userLogo);
 
alloyTouch = new AlloyTouch({
    touch: "#wrapper",
    vertical: true,
    target: scroller,
    property: "translateY",
    maxSpeed: 2,
    outFactor: 0.1,
    min: 160 * -20 + window.innerHeight - 202 - 50,
    max: 0,
    lockDirection: false,
    touchStart: function () {
        reastMin();
    },
    lockDirection: false,
    change: function (v) {
        if (v <= this.min + 5 && !loading) {
            loading = true;
            loadMore();
        }
        if (v < 0) {
            if (v < -140) v = -140;
            var scaleY = (240 + v) / 240;
            header.scaleY = scaleY;
            userLogo.scaleX = userLogo.scaleY = scaleY;
            userLogo.translateY = v / 1.7;
        } else {
            var scaleY = 1 + v / 240;
            header.scaleY = scaleY;
            userLogo.scaleX = userLogo.scaleY = scaleY;
            userLogo.translateY = v / 1.7;
        }
    }
})
 
function loadMore() {
    setTimeout(function () {
        infoList.innerHTML += mockHTML;
        loading = false;
        reastMin();
    }, 500)
}
 
function reastMin() {
    alloyTouch.min = -1 * parseInt(getComputedStyle(scroller).height) + window.innerHeight - 202;
}
 
document.addEventListener("touchmove", function (evt) {
    evt.preventDefault();
}, false);

就這么多代碼。當然你要引用一個transformjs和alloy_touch.css.js。先看這一堆:

Transform(scroller, true);
Transform(header);
header.originY = -70;
header.translateY = -70;
Transform(userLogo);
  • Transform(xxx)是什么意思?

    賦予xxx transformation能力

  • 第一個scroller加上true代表關閉透視投影,為什么要關閉透視投影?

    因為scroller里面是有文本,防止文本在IOS中模糊的情況。

  • header是頂部的那個藍色的區域。為什么要設置originY和translateY?為什么要設置為-70?

    因為header的高度為140px,用戶向上滾動的過程中,需要對其進行scaleY變換。通常我們的做法是設置CSS3 transform-origin為 center top。而使用transformjs之后,可以拋棄transform-origin,使用originY或者originX屬性便可。originY 設置為 -70,相對于高度為140的header來說就是center top。

再看這一堆:

alloyTouch = new AlloyTouch({
    touch: "#wrapper",
    vertical: true,
    target: scroller,
    property: "translateY",
    maxSpeed: 2,
    outFactor: 0.1,
    lockDirection: false,
    min: 160 * -20 + window.innerHeight - 202 - 50,
    max: 0,
    touchStart: function () {
        resetMin();
    },
    lockDirection: false,
    ...
    ...
    ...
})
...
...
function resetMin() {
    alloyTouch.min = -1 * parseInt(getComputedStyle(scroller).height) + window.innerHeight - 202;
}

使用AlloyTouch最關鍵的一點就是計算min和max的值。min和max決定了可以滾到哪里,到了哪里會進行回彈等等。這里max是0毫無疑問。

  • 但是min那一堆加減乘除是什么東西?

    這里首次加載是20行數據,每一行高度大概160,主意是大概, window.innerHeight是視窗的高度,202px是滾動的容器的padding top的值,50px是用來留給顯示 加載更多 的…

如上圖所示,主要是需要求???的高度。

  • 那么怎么解決大概160*20的問題?

    touchStart的時候reastMin。resetMin會去通過getComputedStyle計算整個scroller的高度。

  • maxSpeed是干什么用的?

    用來限制滾動的最大速度,個人感覺調整到2挺舒適,這個可以根據場景和被運動的屬性靈活配置。

  • outFactor是干什么用的?

    用來設置超出min或者max進行拖拽的運動比例系數,系數越小,超出min和max越難拖動,也就是受到的阻力越大。

  • lockDirection是干什么用的?

    lockDirection默認值是true。代表用戶起手時候是橫向的,而你監聽的是豎直方向的touch,這樣的話是不會觸發運動。只有起手和監聽對應上才會有觸摸運動。這里把lockDirection設置成false就沒有這個限制,不管用戶起手的direction,都會有觸摸運動。

再看AlloyTouch注入的change事件!頭部動效核心的一個配置函數:

change: function (v) {
    if (v <= this.min + 5 && !loading) {
        loading = true;
        loadMore();
    }
    if (v < 0) {
        if (v < -140) v = -140;
        var scaleY = (240 + v) / 240;
        header.scaleY = scaleY;
        userLogo.scaleX = userLogo.scaleY = scaleY;
        userLogo.translateY = v / 1.7;
    } else {
        var scaleY = 1 + v / 240;
        header.scaleY = scaleY;
        userLogo.scaleX = userLogo.scaleY = scaleY;
        userLogo.translateY = v / 1.7;
    }
}

v代表當前被運動對象的被運動屬性的當前的值,根據這個v去做一些效果和加載更多。

  • 什么時候加載更多?

    當滾動你能看到加載更多的時候去加載更多

  • 什么時候能看到加載更多?

    v <= this.min + 5。 可以看到change回調里可以拿到this,也就是AlloyTouch對象的實例,當v等于this.min代表滾到了底部,所以這里加上5代表快要滾動底部已經看到了加載更多。就去執行loadMore函數。

  • loading是干什么用的?

    防止重復loadMore用得,因為change執行得很頻繁,所以這里會通過loading的狀態去鎖上。

  • 下面一堆設置scaleX、scaleY、translateY以及一堆數字是怎么來的?

    慢慢調試得出的最佳效果~~反正就是根據v的數值映射到 header和用戶頭像的transform屬性上,這里就不一一講了。

再看loadMore:

function loadMore() {
    setTimeout(function () {
        infoList.innerHTML += mockHTML;
        loading = false;
        reastMin();
    }, 500)
}

這里使用了一段假的HTML去模擬AJAX異步請求以及數據轉HTML的過程,整個耗時500ms,500ms后會去:

  • 插入HTML
  • 重置loading狀態
  • 重置AlloyTouch的min

最后:

document.addEventListener("touchmove", function (evt) {
    evt.preventDefault();
}, false);

阻止掉整個document的默認事件,不會把整個頁面拖下來,在手Q里的話,你就看不到網址和X5內核提供技術支持了。

 

 

來自:https://github.com/AlloyTeam/AlloyTouch/wiki/kandian 

 

 本文由用戶 kinner 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!