Loading content with ajax while scrolling

后端 未结 4 1800
温柔的废话
温柔的废话 2020-12-10 23:24

I\'m using jQuery Tools Plugin as image slider (image here), but due to large amount of images I need to load them few at a time. Since it\'s javascript coded, I can\'t have

4条回答
  •  一个人的身影
    2020-12-10 23:48

    First, you'll want to use jQuery for this

    Second, put a placeholder on your page to contain your data.

    You'll need to code your own GetData method in a webservice, but this is the general idea (And call Refresh(); from your page load)

    function Refresh() {
        var getData = function(callback, context, startAt, batchSize) {
            MyWebservice.GetData(
                startAt,   //What record to start at (1 to start)
                batchSize, //Results per page
                3,         //Pages of data
                function(result, context, method) {
                    callback(result, context, method);
                },
                null,
                context
            );
        };
    
        $('#dataTable').scrolltable(getData);
    }
    

    The getData function variable is passed into the scrolltable plugin, it will be called as needed when the table is being scrolled. The callback and context are passed in, and used by the plugin to manage the object you are operating on (context) and the asynchronous nature of the web (callback)

    The GetData (note the case) webmethod needs to return a JSON object that contains some critical information, how your server side code does this is up to you, but the object this plugin expects is the following. The Prior and Post data are used to trigger when to load more data, basically, you can scroll through the middle/active page, but when you start seeing data in the prior or post page, we're going to need to fetch more data

        return new {
            // TotalRows in the ENTIRE result set (if it weren't paged/scrolled)
            TotalRows = tableElement.Element("ResultCount").Value,
            // The current position we are viewing at
            Position = startAt,
            // Number of items per "page"
            PageSize = tableElement.Element("PageSize").Value,
            // Number of pages we are working with (3)
            PageCount = tableElement.Element("PageCount").Value,
            // Data page prior to active results
            PriorData = tbodyTop.Html(),
            // Data to display as active results
            CurrentData = tbodyCtr.Html(),
            // Data to display after active results
            PostData = tbodyBot.Html()
        };
    

    Next is the plugin itself

    /// 
    (function($) {
        $.fn.scrolltable = function(getDataFunction) {
            var setData = function(result, context) {
                var timeoutId = context.data('timeoutId');
                if (timeoutId) {
                    clearTimeout(timeoutId);
                    context.data('timeoutId', null);
                }
    
                var $table = context.find("table");
                var $topSpacer = $table.find('#topSpacer');
                var $bottomSpacer = $table.find('#bottomSpacer');
    
                var $newBodyT = $table.children('#bodyT');
                var $newBodyC = $table.children('#bodyC');
                var $newBodyB = $table.children('#bodyB');
    
                var preScrollTop = context[0].scrollTop;
    
                $newBodyT.html(result.PriorData);
                $newBodyC.html(result.CurrentData);
                $newBodyB.html(result.PostData);
    
                var rowHeight = $newBodyC.children('tr').height() || 20;
                var rowCountT = $newBodyT.children('tr').length;
                var rowCountC = $newBodyC.children('tr').length;
                var rowCountB = $newBodyB.children('tr').length;
    
                result.Position = parseInt(result.Position);
                $newBodyC.data('firstRow', result.Position);
                $newBodyC.data('lastRow', (result.Position + rowCountC));
                context.data('batchSize', result.PageSize);
                context.data('totalRows', result.TotalRows);
    
                var displayedRows = rowCountT + rowCountC + rowCountB;
                var rowCountTopSpacer = Math.max(result.Position - rowCountT - 1, 0);
                var rowCountBottomSpacer = result.TotalRows - displayedRows - rowCountTopSpacer;
    
                if (rowCountTopSpacer == 0) {
                    $topSpacer.closest('tbody').hide();
                } else {
                    $topSpacer.closest('tbody').show();
                    $topSpacer.height(Math.max(rowCountTopSpacer * rowHeight, 0));
                }
    
                if (rowCountBottomSpacer == 0) {
                    $bottomSpacer.closest('tbody').hide();
                } else {
                    $bottomSpacer.closest('tbody').show();
                    $bottomSpacer.height(Math.max(rowCountBottomSpacer * rowHeight, 0));
                }
    
                context[0].scrollTop = preScrollTop;  //Maintain Scroll Position as it sometimes was off
            };
    
            var onScroll = function(ev) {
                var $scrollContainer = $(ev.target);
    
                var $dataTable = $scrollContainer.find('#dataTable');
                var $bodyT = $dataTable.children('tbody#bodyT');
                var $bodyC = $dataTable.children('tbody#bodyC');
                var $bodyB = $dataTable.children('tbody#bodyB');
    
                var rowHeight = $bodyC.children('tr').height();
                var currentRow = Math.floor($scrollContainer.scrollTop() / rowHeight);
                var displayedRows = Math.floor($scrollContainer.height() / rowHeight);
    
                var batchSize = $scrollContainer.data('batchSize');
                var totalRows = $scrollContainer.data('totalRows');
    
                var prevRowCount = $bodyT.children('tr').length;
                var currRowCount = $bodyC.children('tr').length;
                var postRowCount = $bodyB.children('tr').length;
    
                var doGetData = (
                                    (
                                        (currentRow + displayedRows) < $bodyC.data('firstRow')                      //Scrolling up
                                        && (($bodyC.data('firstRow') - prevRowCount) > 1)                           // ...and data isn't already there
                                    )
                                ||
                                    (
                                        (currentRow > $bodyC.data('lastRow'))                                       //Scrolling down
                                        && (($bodyC.data('firstRow') + currRowCount + postRowCount) < totalRows)    // ...and data isn't already there
                                    )
                                );
    
                if (doGetData) {
                    var batchSize = $scrollContainer.data('batchSize');
    
                    var timeoutId = $scrollContainer.data('timeoutId');
                    if (timeoutId) {
                        clearTimeout(timeoutId);
                        $scrollContainer.data('timeoutId', null);
                    }
    
                    timeoutId = setTimeout(function() {
                        getDataFunction(setData, $scrollContainer, currentRow, batchSize);
                    }, 50);
    
                    $scrollContainer.data('timeoutId', timeoutId);
                }
            };
    
            return this.each(function() {
                var $dataTable = $(this);
    
                if (!getDataFunction) 
                    alert('GetDataFunction is Required');
    
                var batchSize = batchSize || 25;
                var outerContainerCss = outerContainerCss || {};
    
                var defaultContainerCss = {
                    overflow: 'auto',
                    width: '100%',
                    height: '200px',
                    position: 'relative'
                };
    
                var containerCss = $.extend({}, defaultContainerCss, outerContainerCss);
    
                if (! $dataTable.parent().hasClass('_outerContainer')) {
                    $dataTable
                        .wrap('
    ') .append($('
    ')) .append($('')) .append($('')) .append($('')) .append($('
    ')); } var $scrollContainer = $dataTable.parent(); $scrollContainer .css(containerCss) .scroll(onScroll); getDataFunction(setData, $scrollContainer, 1, batchSize); }); }; })(jQuery);

    You'll likely need to tweak some things. I just converted it to a jQuery plugin and it's probably still a little glitchy.

提交回复
热议问题