appendChild() 复选框:记住带有浏览器后退按钮的选择

Posted

技术标签:

【中文标题】appendChild() 复选框:记住带有浏览器后退按钮的选择【英文标题】:appendChild() checkboxes: remember selections with browser back button 【发布时间】:2012-11-12 02:34:35 【问题描述】:

提前感谢任何试图帮助我的人。

我有一个表单,我正在通过 appendChild() 添加复选框 - 作为供用户选择的选项 - 基于一系列标准。

当用户选中任何这些框,然后单击“继续”按钮将选择发布到另一个页面 - 然后单击 后退按钮 - 用户选中的复选框 -现在已被浏览器忘记(不再检查)。

如果我使用 php 编写复选框或仅使用 static 复选框 - 当用户选中这些框中的任何一个然后单击“继续”按钮将选择发布到另一个页面时 - 然后点击后退按钮 - 选中的复选框被记住(仍然选中)

我的问题是:

为什么当我使用 appendChild() 创建复选框时,浏览器会忘记用户所做的选择

但同一浏览器会记住用户在使用静态复选框时所做的选择

appendChild() 不允许同一个浏览器记住选中的选择是什么原因?

[div id="mydiv"] here is where the checkboxes are going[div]


[script type="text/javascript"]

var newInput = document.createElement("INPUT");
newInput.id = "mycheckboxid";
newInput.name = "mycheckboxname";
newInput.type = "checkbox";

document.getElementById('mydiv').appendChild(newInput);

[/script]

【问题讨论】:

需要支持哪些浏览器? 全部 - 这是浏览器特有的问题吗? 想知道这是否有帮助:***.com/questions/7956563/… 有些浏览器会将页面缓存在内存中,当你按下返回时,它会再次显示;有些会重新加载它并重新运行您的 JavaScript 代码(丢失用户选择)。我想在页面重新加载之间保留状态的最便携方法是创建一个包含复选框状态的 cookie,并在用户选择或取消选择一个时通过 JS 更新它。我会看看我是否能找到一些示例代码;同时,您可以阅读document.cookie 每个复选框都有自己的ID吗?如果是这样,这可能就是您所追求的:jsfiddle.net/bae5b。它存储客户端机器上每个复选框的当前选中状态,并在附加复选框时将其加载回来。 【参考方案1】:

浏览器可能会“忘记”对 DOM 的动态更改,因为不同的浏览器使用不同的策略来缓存网页。当您点击后退按钮时,其想法是浏览器可以显示其缓存副本,而不是从原始 Web 服务器重新请求页面。

它可以通过(至少)两种方式实现这一点:

    浏览器在离开页面时缓存页面的 DOM 本身。重新访问(向前或向后)时,动态变化将持续存在。 浏览器在加载时仅缓存页面的原始 html(在任何动态更改之前)。这会导致丢失这些动态更改 - 使用 appendChild()innerHTML 对 DOM 进行的进一步修改不会被记录。

请注意,有些浏览器会额外保留修改后的表单数据,而其他浏览器则不会。如果您的目标是在所有浏览器中实现 99% 以上的兼容性,那么您还有一些工作要做。

要解决这个问题,您需要以某种方式保持状态。您有几个选择:

    将有关页面修改的数据保存到localstorage。使用在第一次加载页面时随机生成然后保留在页面中的密钥,以便状态更改仅适用于页面的 那个 实例。在页面加载时,如果此键已存在,请读出更改数据并重新应用更改。旧版浏览器不支持本地存储。

    用 cookie 做前面的事情。我不推荐这个,因为它的缺点是会增加 cookie。 Cookie 在每个 请求(包括 ajax 请求)中发送和接收,因此您将在每个请求上传输数据。旧浏览器可以正常使用。

    放弃您的动态更改模型并通过发布到服务器来进行更改。然后,当从浏览器的缓存中拉出页面时,该页面将包含修改后的 html。你可能不想要这个,但为了完整起见,我想我会指出它。

    通过后台的 ajax 将有关页面修改的数据保存到服务器。这与实际往返每个更改(如前一项)不同。您仍然动态地进行更改,但您将“通知”文件发布到服务器。然后,在每次页面加载时,向服务器请求任何调整数据。这类似于第一个建议,但您使用远程服务器作为存储。这会在每个页面加载时产生额外的净流量,但流量可能很小,因为它只是关于 this 页面。它还会产生通常不会发送的额外网络流量(通知数据)。然而,一个聪明的系统架构可以使用这些信息以一种非常方便的方式在计算机和一段时间内保存用户未提交的表单数据(假设您的用户在 200 个问题的调查中完成了 199 个,然后他的权力消失了结束——有了这个计划,他有机会在他离开的地方轻松地继续!)。

    让您的继续按钮打开一个新的浏览器窗口,保持原始页面不变。

    让您的“继续”按钮在不离开页面的情况下发布数据,使其保持原样。你可以做一个简单的灯箱式叠加。

    如果灯箱样式的覆盖不起作用,但您确实必须显示一个新页面并且不希望它出现在新窗口中,那么重新设计您的网站以类似于 gmail:页面更改的地方只能通过 javascript,并且只能通过在 URL 末尾使用 #hash 标签来控制行为。这可能很困难,但有一些图书馆可以完成它。 (对于某些浏览器,必须诉诸轮询来查看主题标签是否已更改。)基本思想是,当您单击指向同一页面但上面有标签(例如<a href="#about">About</a>)的链接时,浏览器将启动页面加载事件,并将新上下文推送到历史向前/向后堆栈中,但 实际上不会加载新页面。然后解析更新的 URL 以获取哈希码(映射到某种命令)并执行它。通过为每个链接仔细选择适当的哈希码,您可以通过 Javascript 动态隐藏和显示适当的页面,它看起来就像这个人正在浏览一个真实的网站。你这样做的原因是,因为页面从不加载,你不仅可以在 Javascript 中维护状态,还可以维护 DOM 状态——你只需隐藏用户修改过的页面,当返回事件发生意味着再次访问该页面,您显示它,这正是用户离开它的方式。优点:如果您的网站需要 Javascript 来运行,那么您不会冒险使用更多的 Javascript 来完成它。缺点:完全改变您网站的架构需要大量工作,并且很难在旧浏览器上工作。要开始使用此功能,请参阅Unique URLs。你可以试试jQuery hashchange plugin。如果您的网站分布广泛,您需要确保地址为search engine optimization and web usability issues。你可能想看看this SO page on detecting back button hash changes。

    使用与前一点相同的策略,但不要使用主题标签,而是使用新的 HTML5 history.pushState()history.replaceState() 方法——请参阅 Mozilla browser history。

如果您的目标不是在使用的 99% 的浏览器中实现 99% 的兼容性,那么请告诉我们您的目标,因为可能有一条捷径。

更新:添加了选项 #8

【讨论】:

谢谢大家——如果我能得到一个有针对性的回答,那就太好了:为什么特定浏览器在使用静态复选框时会“记住”复选框,而在使用 appendChild 时会“忘记”复选框() ? 我相信我确实为您提供了针对您的问题的重点回应。请参阅上面第二段中以“当浏览器改为使用原始 HTML 时...”开头的句子 所以你说浏览器保存/缓存原始 HTML - 在任何动态更改之前。那是对的吗?您认为这实际上与使用 innerHTML += 相同吗?浏览器已经缓存了静态 HTML,当您使用 innerHTML 或 appendchild() 进行任何更改时 - 浏览器已完成缓存? 这是我的假设,它符合已知事实,但我无法证明。【参考方案2】:

脚本页面不会停留在状态管理上。它包括状态管理。

这意味着脚本状态更改,例如脚本页面转换(内部导航的页面)、内容窗格、弹出菜单、样式更改,当然还有表单输入和选择,都是脚本编写者的责任。

所以,回答为什么......这是因为您没有管理您编写脚本的页面状态。

如果您希望您的页面按预期工作,您可以管理您自己编写脚本的页面状态更改,使用管理页面的 js 库,或者在您的情况下表单、状态或使用 http(s)客户端/服务器状态管理并在服务器上加载会话状态,或者在您的情况下只是表单状态。

【讨论】:

以上是关于appendChild() 复选框:记住带有浏览器后退按钮的选择的主要内容,如果未能解决你的问题,请参考以下文章

即使没有检查,请记住我在 laravel auth 中的工作

PHP登录系统:记住我(持久cookie)[重复]

记住我功能如何运作?

本地存储-记住用户名

Cookie实现记住密码自动登录功能

带有 Codeigniter 会话到期时间的帮助