English 中文(简体)
如何实施垂直新闻馈赠或时间表,如果能达到尾声,支持跳跃到某个具体位置,则能够动态地装载新的物品?
原标题:How to implement a vertical news feed or timeline which dynamically loads new items if the end is reached and supports jumping to a specific position?

我的数据包括我想要显示的数千件物品。 然而,同时显示所有物品将大大降低性能。 而且,我确实需要看到几个项目。

因此,我所希望的基本上是像Facebook新闻馈赠、Twitter时限或任何即时送信人历史观这样的行为。 在所有这些例子中,首先,我只看到几个项目,而且到名单结束,我可以更有活力地负荷工作。

I can also jump to a specific position of the feed, like a certain date and time of a chat history. The feed usually doesn t load and show every single message from now until the specified history position, but it jumps to the position and shows a few surrounding messages. Again, by reaching (either) end of the list, more items are dynamically added.

What is this feature called? Which library can I use to implement it?

问题回答

这里是一小条概念,不需要任何三党图书馆。

In this example, the database consist of 501 items from 0 to 500. FeedEngine is taking care of the mechanics that add/remove items from the list. The actual site/item content is managed by an itemCallback function. Here, it is called customItemBuilder and is kept very simple: it only displays the item index and alternates the background color. This is where you would actually pull the contents for that specific itemIndex from your database and dynamically adjust the itemElement accordingly.

在流动方面,你可以通过这些物品进行清洗。 在桌面上,它最能利用 mo轮通过饲料进行滚动。

<!DOCTYPE html>
<html lang="en">

<head>
<script>
/**
 * FeedEngine
 *
 * FeedEngine is a vertical news feed or timeline implementation. Initially,
 * only a certain, small amount of items are displayed. If the user reaches
 * either end of the container, for example by scrolling, more and more items
 * are dynamically added to the feed as required. It s also possible to jump
 * to a specific item, i.e. feed position.
 *
 * For each item, an empty, blank DIV element will be added to the container
 * element. Afterwards, a function is called which receives two parameters:
 * `itemElement`, the new element, and `itemIndex`, the index of the new
 * item. This callback function allows you to customize the presentation of
 * the feed items.
 *
 * Options:
 *     containerElement - The element which will contain all DIV elements for
 *         the items. For best results, you should probably choose a DIV
 *         element for the container as well. Furthermore, its CSS should
 *         contain something like `overflow: scroll`. Note: Its attributes
 *         `innerHTML` and `onscroll` will be overwritten.
 *     itemCallback - This function will be called after a new item has been
 *         added to the container. If the callback doesn t return `true`, the
 *         item will immediately be removed again.
 *     moreItemsCount -  The number of new items that will be added above and
 *         below the first item, the target item of a jump or the outermost
 *         item in the feed, respectively.
 *     moreItemsTrigger - The threshold distance to the outermost item which
 *         triggers more items to be added to the feed. For example, if this
 *         option is set to `0`, new items will only be added once the
 *         outermost item is fully in view. Furthermore, a value greater than
 *         or equal to `moreItemsCount` doesn t make sense.
 *     inverseOrder - Use bottom-to-top instead of top-to-bottom order.
 *
 * @constructor
 * @param {Object} options - Options object.
 */
function FeedEngine(options) {
     use strict ;
    this.itemCallback = (itemElement, itemIndex) => {};
    this.moreItemsCount = 20;
    this.moreItemsTrigger = 5;
    this.inverseOrder = false;
    Object.assign(this, options);
    if (this.containerElement === undefined) {
        throw new Error( container element must be specified );
    }
    this.jumpToItem = (itemIndex) => {
        this.containerElement.innerHTML =   ;
        this.topItemIndex = itemIndex;
        this.bottomItemIndex = itemIndex;
        var initialItem = this.insertItemBelow(true);
        for (var i = 0; i < this.moreItemsCount; i++) {
            this.insertItemAbove();
            this.insertItemBelow();
        }
        this.containerElement.scrollTop = initialItem.offsetTop - this.containerElement.offsetTop + (this.inverseOrder ? initialItem.clientHeight - this.containerElement.clientHeight : 0);
    };
    this.insertItemAbove = () => {
        this.topItemIndex += this.inverseOrder ? 1 : -1;
        var itemElement = document.createElement( div );
        this.containerElement.insertBefore(itemElement, this.containerElement.children[0]);
        if (!this.itemCallback(itemElement, this.topItemIndex)) {
            itemElement.remove();
        }
        return itemElement;
    };
    this.insertItemBelow = (isInitialItem) => {
        if (isInitialItem === undefined || !isInitialItem) {
            this.bottomItemIndex += this.inverseOrder ? -1 : 1;
        }
        var itemElement = document.createElement( div );
        this.containerElement.appendChild(itemElement);
        if (!this.itemCallback(itemElement, this.bottomItemIndex)) {
            itemElement.remove();
        }
        return itemElement;
    };
    this.itemVisible = (itemElement) => {
        var containerTop = this.containerElement.scrollTop;
        var containerBottom = containerTop + this.containerElement.clientHeight;
        var elementTop = itemElement.offsetTop - this.containerElement.offsetTop;
        var elementBottom = elementTop + itemElement.clientHeight;
        return elementTop >= containerTop && elementBottom <= containerBottom
    };
    this.containerElement.onscroll = (event) => {
        var topTriggerIndex = this.moreItemsTrigger;
        var bottomTriggerIndex = event.target.children.length - this.moreItemsTrigger - 1;
        var topTriggerElement = event.target.children[topTriggerIndex];
        var bottomTriggerElement = event.target.children[bottomTriggerIndex];
        var topTriggerVisible = this.itemVisible(topTriggerElement);
        var bottomTriggerVisible = this.itemVisible(bottomTriggerElement);
        for (var i = 0; i < this.moreItemsCount; i++) {
            if (topTriggerVisible) {
                this.insertItemAbove();
            }
            if (bottomTriggerVisible) {
                this.insertItemBelow();
            }
        }
    };
    this.jumpToItem(0);
}
</script>
</head>

<body>
Feed:
<button onclick="feed = new FeedEngine({containerElement: document.getElementById( container ), itemCallback: customItemBuilder})">top-to-bottom</button>
<button onclick="feed = new FeedEngine({containerElement: document.getElementById( container ), itemCallback: customItemBuilder, inverseOrder: true})">bottom-to-top</button>
<input type="text" id="jump" value="250">
<button onclick="feed.jumpToItem(parseInt(document.getElementById( jump ).value))">jump</button>
<div id="container" style="overflow: scroll; width: 300px; height: 100px; resize: both;"></div>
<script>
function customItemBuilder(itemElement, itemIndex) {
    if (0 <= itemIndex && itemIndex <= 500) {
        /* customize the item DIV element here */
        itemElement.innerHTML =  Content for item index   + itemIndex;
        itemElement.style.backgroundColor = itemIndex % 2 ?  LightCyan  :  LightGray ;
        return true;
    }
}
window.onload = () => {
    document.getElementsByTagName( button )[0].click();
}
</script>
</body>

</html>

The feature is called Infinite Scrolling





相关问题
CSS working only in Firefox

I am trying to create a search text-field like on the Apple website. The HTML looks like this: <div class="frm-search"> <div> <input class="btn" type="image" src="http://www....

image changed but appears the same in browser

I m writing a php script to crop an image. The script overwrites the old image with the new one, but when I reload the page (which is supposed to pickup the new image) I still see the old one. ...

Firefox background image horizontal centering oddity

I am building some basic HTML code for a CMS. One of the page-related options in the CMS is "background image" and "stretch page width / height to background image width / height." so that with large ...

Separator line in ASP.NET

I d like to add a simple separator line in an aspx web form. Does anyone know how? It sounds easy enough, but still I can t manage to find how to do it.. 10x!

热门标签