首页 > 解决方案 > 您能否保留使用 ajax 的页面的动态内容,以便在用户返回时恢复?

问题描述

我知道我可以存储页面上的最后一个元素,当用户返回时,我可以使用偏移量从用户离开的地方获取内容,我的问题是,有没有办法让页面加载所有动态内容?

例如,在 LinkedIn 或 Twitter 上,当您从推文/帖子返回时,页面似乎没有再次发出请求,这是一个即时转换。

这是否意味着您可以以某种方式使用 JS 保留整个页面并立即恢复它而无需再次向服务器发出请求?还是页面实际上并没有改变的某种恶作剧,所以它只是一个页面应用程序,所有内容都是动态加载的?

编辑:我认为 Twitter/LinkedIn 以某种方式替换了同一页面上的内容并且不会重定向到另一个页面(我猜),但我有 2 个单独的页面。

我会改写,并尝试更好地解释

我有一个无限滚动页面,它以块的形式加载内容,比如我一次加载 10 张垂直放置的图像。

用户滚动并加载 30 张图片,当您单击一张图片时,您将被重定向到另一个页面,您可以在该页面上看到全屏图片。

现在用户点击后退按钮,回到主页,我该怎么做才能让用户从他离开的地方看到内容。

我尝试过的解决方案。

1 - 我可以存储图像的当前偏移量并在用户回来时从那里加载,但我一次只能加载 10 张图像,如果用户单击第 11-n 张图片,我仍然可以从那里拉但是它与滚动位置混淆,因为该图片现在位于页面的第一个位置,并且页面向下滚动到第 11 个图片所在的位置。

2 -- 我可以存储已经加载了多少张图片,所以如果用户在滚动时加载了 50 张图片,他会回来,我只加载页面更改之前有多少张图片,但我认为这不是一个好主意,因为加载大量这样的内容会影响性能。

如何在返回主页时向用户显示他离开的内容并将滚动位置保持在无限滚动页面上?(我再以推特为例)

标签: phpajax

解决方案


我建议您使用localStorage它具有相当不错的存储容量

您仅限于其中的字符串,因此您需要将所有内容与 JSON 进行转换以获得最佳结果。

您存储的内容取决于您。我将创建一个具有各种属性的对象,例如当前滚动高度、上次请求的索引和一个数组,其中包含您迄今为止从 AJAX 中提取的所有内容(以及您在页面加载时创建的所有内容)。如果您要在多个页面上使用此逻辑,或者只是更改每页的键,您可能还想存储这是在哪个页面上。但是,如果您共享一个密钥,您也可以完全跳过对已有数据的 AJAX 调用,并且您认为自己的业务逻辑是“新鲜的”。

下面是一些示例代码。如果您按下开始按钮并让它运行几秒钟,您会看到列表随着时间戳而增长。如果你然后刷新页面,一切都会在那里。

首先,一些 HTML 让我们工作,一个开始和停止的按钮,以及我们将要写入的列表。

<button id="start">Start</button>
<button id="stop">Stop</button>

<ul id="list">

</ul>

然后 JS 是下一个,内联注释应该可以解释一切:

// This is the interval key, used when stopping the interval code
let iv;

const cache_key = 'my-cache-key';

function stop() {
    window.clearInterval( iv );
}

function start() {
    iv = window.setInterval( tick, 1000 );
}

function makeLi( text ) {
    const li = document.createElement( 'li' );
    li.appendChild( document.createTextNode( text ) );
    return li;
}

// Run once a second
function tick() {
    // Create a timestamp
    const ts = new Date().getTime();

    // Store it to local session
    store( ts );

    // Append to our list
    const ul = document.getElementById( 'list' );
    ul.appendChild( makeLi( ts ) );
}

function store( text ) {
    // See if we have our key
    let items = window.localStorage.getItem( cache_key );

    // Parse it as JSON or set it to an empty array to start
    if ( items ) {
        items = JSON.parse( items );
    } else {
        items = [];
    }

    // Append our current key
    items.push( text );

    // Push it back
    window.localStorage.setItem( cache_key, JSON.stringify( items ) );
}

// One page load, recreate all items
function load() {
    const ul = document.getElementById( 'list' );
    let items = window.localStorage.getItem( cache_key );
    if ( !items ) {
        return;
    }
    items = JSON.parse( items );
    items
        .forEach(
            ( item ) => {
                ul.appendChild( makeLi( item ) )
            }
        );
}

// Click handlers for the button
document.getElementById( 'start' ).addEventListener( 'click', start );
document.getElementById( 'stop' ).addEventListener( 'click', stop );

// Reload anything previously stored on page refresh
window.addEventListener( 'load', load );

至于您在本地存储中存储的内容,这取决于。如果你的 DOM 很复杂但很短,你可以存储outerHTML它,但这有点难看。相反,我将存储您从 AJAX 收到的用于创建对象的最少字段数。

此外,无论您要存储什么,我都建议您在对象上设置一个名为“版本”之类的属性,并且每当您向 AJAX 逻辑引入新功能时,手动增加此属性。这样,如果有人带着不再有意义的数据返回您的页面,您的应用程序可以检测到它并将其丢弃。

这个示例应用程序存储了一个非常简单的数组,但就像我说的那样,您可能想要存储一个对象,并且您还想要执行验证和清理,就像您在 AJAX 中所做的那样。

编辑

我还应该补充一点,您需要确保图像等资源的缓存过期,以便从本地缓存中获得额外的站点速度。

根据我的评论,这个网站(已有 4 年历史)说 97.6% 的人启用了本地存储,所以我绝对会使用它,因为降级只是“只是最新的”,这仍然是一个不错的体验。

如果您在参考站点上打开您的开发人员工具,您可以检查应用程序部分的本地存储,您会发现我在此讨论的版本。


推荐阅读