2016-02-05 26 views
12

Tôi đang xây dựng một ứng dụng đơn giản trong Elm chỉ hiển thị danh sách các div trong danh sách khác và tôi muốn thêm chức năng cuộn vô hạn, để thêm nội dung mới mỗi khi div cuối cùng của trang xuất hiện trong chế độ xem.Cuộn vô hạn trong Elm

Có cách nào trong Elm để biết khi nào một div xuất hiện trong chế độ xem không? Thay vào đó, trong đó có một cách để theo dõi, như một tín hiệu, sự kiện di chuyển chuột?

Trả lời

14

Hiện tại không có hỗ trợ Elm cho các sự kiện cuộn, do đó bạn sẽ phải sử dụng cổng. Đây là một ví dụ đơn giản.

Chúng tôi cần một hàm javascript để cho chúng tôi biết liệu phần tử cuối cùng trong danh sách có nằm trong cổng xem hay không. Chúng ta có thể lấy mã isElementInViewport từ this StackOverflow answer (sao chép vào đây để tham khảo sau này):

function isElementInViewport (el) { 
    //special bonus for those using jQuery 
    if (typeof jQuery === "function" && el instanceof jQuery) { 
     el = el[0]; 
    } 

    var rect = el.getBoundingClientRect(); 

    return (
     rect.top >= 0 && 
     rect.left >= 0 && 
     rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */ 
     rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */ 
    ); 
} 

Hãy nói rằng HTML của bạn trông giống như sau:

<div class="wrapper"> 
    <div class="item">...</div> 
    <div class="item">...</div> 
</div> 

đang Elm của bạn có thể có một cổng hoạt động như một tín hiệu để cho chúng tôi biết mục cuối cùng có hiển thị hay không.

port lastItemVisible : Signal Bool 

Bây giờ, bạn cần kết nối mã cổng ở phía bên thứ Javascript. Mã này sẽ nghe sự kiện window.onscroll, sau đó kiểm tra xem mục cuối cùng bên trong div .wrapper có hiển thị hay không và gửi tín hiệu thích hợp.

var app = Elm.fullscreen(Elm.Main, { 
    lastItemVisible: false 
}); 

window.onscroll = function() { 
    var wrapper = document.getElementsByClassName("wrapper")[0]; 
    var lastItem = wrapper.childNodes[wrapper.childNodes.length - 1]; 

    if (isElementInViewport(lastItem)) { 
    app.ports.lastItemVisible.send(true); 
    } else { 
    app.ports.lastItemVisible.send(false); 
    } 
}; 

Nếu bạn thay vì chỉ muốn có tín hiệu để theo dõi sự kiện cuộn, there is a related StackOverflow answer here.

Các vấn đề liên quan