为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

PHP
素胚勾勒不出你 2023-03-04 16:24:20
我知道我可以存储页面上的最后一个元素,当用户返回时我可以使用偏移量从该用户离开的地方获取内容,我的问题是,有没有办法让页面加载所有动态内容?例如,在 LinkedIn 或 Twitter 上,当您从推文/帖子返回时,页面似乎不会再次发出请求,这是一个即时转换。这是否意味着您可以以某种方式使用 JS 保留整个页面并立即恢复它而无需再次向服务器发出请求?或者它是某种恶作剧,页面实际上没有改变,所以它只是一个页面应用程序,所有内容都是动态加载的?编辑:我认为 Twitter/LinkedIn 以某种方式替换了同一页面上的内容并且不会重定向到另一个页面(我猜),但我有 2 个单独的页面。我会重新措辞,并尝试更好地解释。我有一个无限滚动页面,它以块的形式加载内容,比如我一次加载 10 张垂直放置的图像。用户滚动并加载 30 张图片,当你点击一张图片时,你会被重定向到另一个页面,在那里你可以全屏查看图片。现在用户点击后退按钮,回到主页,我怎样才能让用户看到他离开的地方的内容。我尝试过的解决方案。1 -- 我可以存储图像的当前偏移量并在用户返回时从那里加载,但我一次只加载 10 张图像,如果用户单击第 11 张图片,我仍然可以从那里拉,但它弄乱了滚动位置,因为该图片现在位于页面上的第一位,并且页面向下滚动到第 11 张图片所在的位置。2 -- 我可以存储已经加载了多少张图片,所以如果用户在滚动时加载了 50 张图片,他返回时我只加载页面更改之前的图片数量,但我认为这不是一个好主意,因为加载大量这样的内容会影响性能。当返回主页并保持滚动位置在无限滚动页面上时,如何向用户显示他离开的内容?(我将再次以推特为例)
查看完整描述

2 回答

?
芜湖不芜

TA贡献1796条经验 获得超7个赞

我会建议你使用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% 的人启用了本地存储,所以我绝对会使用它,因为降级只是“最新的”,这仍然是一个不错的体验。


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


查看完整回答
反对 回复 2023-03-04
?
当年话下

TA贡献1890条经验 获得超9个赞

这个问题太宽泛了,但由于它不能在有赏金的情况下关闭,所以我不妨用同样宽泛的答案来回答。

  1. 你真的需要这个吗?为什么不在新标签页中打开全尺寸图片?或者为什么不离开页面就打开它们?如果您想要后退/前进功能,您可以使用History API 。您将尽可能节省所有流量。此外,在显示全尺寸图像时,您可以允许用户使用箭头键和其他一些很酷的员工在全尺寸图像之间移动。

  2. 关于

    但我认为这不是一个好主意,因为加载大量这样的内容会影响性能

    正确的缓存 - 不是真的。图像不会被重新加载...当然,如果您通过 url 加载它们而不是以其他一些奇怪的方式加载它们。

  3. 关于问题的标题:我们真的应该谈论重建状态而不是恢复状态。因为对于这个:

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

    答案是:“不,你不能”。不是因为它完全不可能,而是因为你肯定会失败。要存档此目标,您需要

    1. 在每次更改时将应用程序的每个变量序列化。包括有关 DOM 动态更改的信息。

    2. 并非所有东西都易于序列化:Promises、WeakMaps、Symbols、具有循环引用的数据等。

    3. 接下来,您需要将它们反序列化回来。这也可能是一个挑战。特别是,如果在序列化和反序列化之间服务器端发生了一些变化。(可能扔掉所有东西重新开始更容易)

    4. 此外,您还需要决定是否应该这样做。例如,如果用户在一个月后访问您的页面——您真的要显示一个月前的状态吗?

  4. 但如果我们谈论存储一些重要变量并从中重新创建状态,那么答案是:“是的,它一直在发生”。

    在客户端存储数据有不同的方法(甚至是数据库!),在服务器端存储数据更是如此。

    他们都适合自己的场景。在不知道这些情况的情况下很难说什么是最好的方法。

    但在这种特殊情况下,您只需要存储 1 或 2 个变量。而使用 cookie 可能是最好的选择。虽然现在如果您使用 cookie,您需要显示一些烦人的消息。由于欧盟 cookie 指令。但它们易于使用,例如,如果您决定在一个月后向用户呈现一个全新的状态,您只需要为 cookie 设置到期日期,而如果您使用localStorage.

    在这个显然不是商业站点的地方,可能不需要服务器端存储。


查看完整回答
反对 回复 2023-03-04
  • 2 回答
  • 0 关注
  • 75 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信