在离开未保存更改的网页之前警告用户

2023-12-11

我的申请中有一些带有表格的页面。

如何保护表单,以便在有人离开或关闭浏览器选项卡时,系统应提示他们确认是否确实要保留未保存数据的表单?


简短、错误的答案:

你可以通过以下方式做到这一点处理beforeunload事件并返回一个非空字符串:

window.addEventListener("beforeunload", function (e) {
    var confirmationMessage = 'It looks like you have been editing something. '
                            + 'If you leave before saving, your changes will be lost.';

    (e || window.event).returnValue = confirmationMessage; //Gecko + IE
    return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
});

这种方法的问题在于提交表单也会触发卸载事件。通过添加您正在提交表单的标志可以轻松解决此问题:

var formSubmitting = false;
var setFormSubmitting = function() { formSubmitting = true; };

window.onload = function() {
    window.addEventListener("beforeunload", function (e) {
        if (formSubmitting) {
            return undefined;
        }

        var confirmationMessage = 'It looks like you have been editing something. '
                                + 'If you leave before saving, your changes will be lost.';
        
        (e || window.event).returnValue = confirmationMessage; //Gecko + IE
        return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
    });
};

然后在提交时调用setter:

<form method="post" onsubmit="setFormSubmitting()">     
    <input type="submit" />
</form>

但请继续阅读...

长而正确的答案:

您也不想显示此消息当用户没有更改表单上的任何内容时。一种解决方案是使用beforeunload事件与“脏”标志相结合,只有在确实相关时才会触发提示。

var isDirty = function() { return false; }

window.onload = function() {
    window.addEventListener("beforeunload", function (e) {
        if (formSubmitting || !isDirty()) {
            return undefined;
        }
        
        var confirmationMessage = 'It looks like you have been editing something. '
                                + 'If you leave before saving, your changes will be lost.';

        (e || window.event).returnValue = confirmationMessage; //Gecko + IE
        return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
    });
};
    

现在要实施的是isDirty方法,有多种方法。

您可以使用jQuery 和表单序列化,但这种方法有一些缺陷。首先,您必须更改代码以适用于任何形式($("form").each()就可以了),但最大的问题是 jQuery 的serialize()只适用于命名的、非禁用的元素,因此更改任何禁用的或未命名的元素不会触发脏标志。有解决方法,例如将控件设置为只读而不是启用、序列化然后再次禁用控件。

因此,事件似乎是一条出路。你可以试试监听按键。本次活动有几个问题:

  • 不会在复选框、单选按钮或通过鼠标输入更改的其他元素上触发。
  • Will trigger for irrelevant keypresses like the Ctrl key.
  • 不会触发通过 JavaScript 代码设置的值。
  • 通过上下文菜单剪切或粘贴文本时不会触发。
  • 不适用于日期选择器或复选框/单选按钮美化器等虚拟输入,它们通过 JavaScript 将其值保存在隐藏输入中。

The change event also 不会触发 JavaScript 代码设置的值,因此也不适用于虚拟输入。

绑定input给所有人的活动inputs (and textareas and selects)在您的页面上不适用于旧版浏览器并且,像上面提到的所有事件处理解决方案一样,不支持撤消。当用户更改文本框然后撤消该操作,或者选中并取消选中复选框时,表单仍然被视为脏表单。

当您想要实现更多行为(例如忽略某些元素)时,您将需要做更多工作。

不要重新发明轮子:

因此,在考虑实施这些解决方案和所有必需的解决方法之前,请意识到您正在重新发明轮子,并且很容易遇到其他人已经为您解决的问题。

如果您的应用程序已经使用 jQuery,您也可以使用经过测试、维护的代码,而不是自己编写代码,并使用第三方库来完成所有这些操作。

jquery.dirty(由 @troseman 在评论中建议)提供了正确检测表单是否已更改的功能,并防止用户在显示提示时离开页面。它还具有其他有用的功能,例如重置表单以及将表单的当前状态设置为“干净”状态。用法示例:

$("#myForm").dirty({preventLeaving: true});

一个较旧的、目前已废弃的项目是jQuery 的你确定吗?插入,效果也很好;看到他们的演示页面。用法示例:

<script src="jquery.are-you-sure.js"></script>

<script>
  $(function() {
    $('#myForm').areYouSure(
      {
        message: 'It looks like you have been editing something. '
               + 'If you leave before saving, your changes will be lost.'
      }
    );
  });
  
</script>

并非所有地方都支持自定义消息

请注意自 2011 年以来,Firefox 4不支持此对话框中的自定义消息。截至 2016 年 4 月,Chrome 51 正在推出其中自定义消息也被删除.

本网站其他地方存在一些替代方案,但我认为这样的对话框已经足​​够清晰了:

您想离开这个网站吗?

您所做的更改可能不会保存。

Leave Stay

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在离开未保存更改的网页之前警告用户 的相关文章

  • zone.js:140未捕获类型错误:无法读取属性“删除”

    我是 kendo ui 的新手 我在小提琴中开发了原型 删除确认窗口在那里工作正常 但是当我集成到我的代码库中时 我收到错误 Cannot read property remove at the line pai to delete rem
  • 有没有办法在javascript中代理(拦截)一个类的所有方法?

    我希望能够在类本身的构造函数内代理类的所有方法 class Boy constructor proxy logic do something before each call of all methods inside class like
  • Mozilla WebExtension API 存储 - 使用和不使用断点进行调试会导致不同的输出

    大家好 我正在尝试为 Mozilla Firefox 浏览器实现一个附加组件 以下脚本显示了我已经成功集成的一个后台脚本 它使用 Mozilla WebExtension API 存储 它被执行了 但浏览器控制台上的日志让我感到惊讶 我交替
  • Typescript:匿名函数内可能未定义的变量

    太长了 在匿名函数中使用变量之前检查变量仍然 TS 警告变量可能未定义 在下面的代码示例中变量baseDirId检查是否未定义 然后传递给 array map 函数 但 TS 发出警告baseDirId可以是未定义的 Typescript
  • 在 ajax 请求上启用 jQuery contextMenu 项

    我正在尝试更新上下文菜单 http medialize github com jQuery contextMenu docs htmlitem 如果 ajax 请求改变了我的 div 内容 这就是我的意思 我有一个这样的 div div c
  • Pug 从模板内的另一个文件调用 js 函数

    我花了将近四个小时都无法解决这个问题 而且我找不到任何针对此类问题的有用文档 这就是问题 我正在使用 pug jade 模板 我想调用 pug 模板内的函数来转换一些数据 这是主要模板 main template section each
  • 图表.js.如何更改“标签”数组的字体样式?

    我从 Chart JS 库中获取了一个图表 截屏 https i stack imgur com DnuRq png var ctx document getElementById myChart var data labels HTML
  • 网络上的等角柱状图

    我计划为游戏的标记 图钉 构建在线地图 但我无法设置标记的正确纬度 原始地图是一个2048 2048px 的正方形 然后我得到了标记 数千个 地图坐标使用 0 到 100 之间的 x y 表示法设置 0 0 是top left角和100 1
  • 用更好的模式替换开关(Javascript)

    我必须升级我的应用程序以根据用户类型和角色属性显示页面 目前 我使用一个简单的 switch 语句来根据用户类型来执行此操作 例如 switch type case a return CONSTANT ONE case b return C
  • 解释一下这个令人困惑的 dojo 教程声明语法

    我正在阅读使用的语法道场的声明 http dojotoolkit org documentation tutorials 1 8 declare 用于班级创建 描述很混乱 The declare function is defined in
  • 为什么我可以使用 Date 对象进行数学运算? [复制]

    这个问题在这里已经有答案了 当我像这样减去两个日期对象时 const startTime new Date await someAsyncStuff const endTime new Date const elapsedTime endT
  • 如何使用 Nextjs/React 将 JSON 对象导出到 Excel?

    我有一个检索 json 对象的端点 如下所示 data id 1 temaIndicador Indian codigo 001 observaciones Interactions Specialist tertiary Regional
  • 为什么这个递归函数返回未定义?

    我正在尝试编写一个使用递归组合两个字符串的函数 我的代码如下 但我不知道为什么该函数返回未定义 特别是当我在基本情况下使用 console log 时 它不会打印未定义而是打印正确的值 var str3 function merge str
  • 文件缓存:查询字符串与上次修改时间?

    我正在研究缓存网站资源的方法 并注意到大多数与我类似的网站都使用查询字符串来覆盖缓存 例如 css style css v 124942823 后来 我注意到每当我保存 style css 文件时 最后修改的标头都会 更新 使得查询字符串变
  • 将默认搜索文本添加到搜索框 html

    我正在努力将 搜索 文本添加到搜索框 我正在努力实现 onfocus 消失文本 And onblur 重新出现文本 到目前为止 我已经实现了这一点 但我必须将其硬编码为 html eg
  • 如何禁用网页中的萤火虫?

    如何使用 Javascript 禁用 firebug 我想这样做是为了向访问者隐藏我的网页的运作方式 有什么选择可以做到这一点吗 你不能 你能做的最好的事情就是混淆你的 JavaScript 实际上刮掉了 您能做的最好的事情就是将所有安全关
  • 如何计算一行中Flexbox项目的数量?

    网格是使用 CSS flexbox 实现的 Example http jsbin com jumosicasi edit html css js output 本示例中的行数为 4 因为我出于演示目的固定了容器宽度 但是 实际上 它可以根据
  • eventSources 到事件 Json,完整日历

    我正在尝试从 eventSources 获取 json 调用到我的事件 我在 eventSources 中返回的 json 是 title Title Test start 1305841052 当我将此字符串传递到事件中时 它会正确显示日
  • 如何得知客户端从服务器的下载速度?

    根据客户的下载速度 我想以低质量或高质量显示视频 任何 Javascript 或 C 解决方案都是可以接受的 Thanks 没有任何办法可以确定 您只能测量向客户端发送数据的速度 如果没有来自客户端的任何类型的输入来表明其获取信息的速度 您
  • 如何强制下载图片?

    我的页面上有一个动态生成的图像 如下所示 img src 我不想告诉我的用户右键单击图像并点击保存 而是想公开一个下载链接 单击该链接将提示下载图像 如何实现这一目标 最初我在 js 中尝试这样做 var path my image att

随机推荐

  • 使用 MVC 和实体框架实施审核日志/更改历史记录

    我正在使用实体框架在我的 MVC 应用程序中构建更改历史记录 审核日志 所以具体在编辑方法中public ActionResult Edit ViewModel vm 我们找到我们正在尝试更新的对象 然后使用TryUpdateModel o
  • 如何让 Homebrew 恢复到之前的状态?

    我删除了一些 rb 文件 cassandra rb 电子邮件受保护 and 电子邮件受保护 从文件夹 usr local Homebrew Library Taps homebrew homebrew core Formula 来自 mac
  • Win32 中的 Sleep() 使程序无响应

    基本上就是标题所说的 我想当用户按下特定按钮时每 1 秒更新一次按钮包含的文本 我注意到 当程序没有焦点时 它可以正常工作并且文本刷新正确 但是当我将鼠标悬停在程序上或尝试单击它的菜单时 Windows 通知我该程序没有响应 并询问我是否我
  • 关于传统解释器、编译器和 JIT 编译器/解释器的澄清

    我正在学习 Java 以下事情对我来说有点困惑 我的理解是 Java编译器 Java 编译器只是转换 java程序进入 class文件 这意味着将我们的源代码转换为字节码 它是虚拟机 JVM 的操作码列表 这使得 Java 平台无关 Jav
  • 这是一个错误的 REST URL 吗?

    我刚刚阅读了有关 REST URL 的内容并看到了以下示例 API 用户 获取用户 现在 如果使用动词 GET 通过 HTTP 进行访问 这不是一个错误的 URL 因为它描述了 URL 中的操作 GET 这更像是一个惯例 而不是硬性规则 但
  • 现在有人可以下载 Eclipse 吗?

    我无法下载 Eclipse 这是Eclipse的问题吗 这是链接https www eclipse org downloads packages 是的 在计划内的维护中断之后 eclipse org 网站是很遗憾无法到达的到目前为止 202
  • 调用未定义的方法 Illuminate\Pagination\Paginator::make()?

    这是我的代码 use Illuminate Support Collection use Illuminate Support Facades Input use Illuminate Pagination Paginator collec
  • CakePHP - 分页和排序二级关联

    我知道这个问题已经被问了 100 000 次 但我几乎阅读了所有 100 000 条回复 但似乎没有一个符合我的要求 我已经尝试了所有可能的组合 显然没有 但我担心我会在如此相对简单的事情上失败 这是我的第二个蛋糕项目 所以我绝不是专家 简
  • 如何绘制混合箱线图:一半箱线图,另一半有抖动点?

    我正在尝试制作与图 2d f 类似的图文章发表在 自然 杂志上今年 它基本上是一半箱线图 另一半是点 有人能给我一些提示吗 非常感谢 这些是我的数据和代码 它们生成了带有点的完整框 require magrittr require tidy
  • android 媒体播放器显示音频但不显示视频

    我正在使用媒体播放器来播放视频 它只播放音频而不播放视频 有人可以帮忙吗 我的代码如下 public class VideoViewApplication extends Application Override public void o
  • WHERE-CASE 子句子查询性能

    该问题可能特定于 SQL Server 当我编写如下查询时 SELECT FROM IndustryData WHERE Date 20131231 AND ReportTypeID CASE WHEN fnQuarterDate 2013
  • XSLT :将命名空间声明添加到根元素

    我有这个 XML 文档
  • 更新 SQL Server 2012 中的 varbinary(MAX) 字段丢失最后 4 位

    最近想做一些数据修补 尝试更新一列 typevarbinary 最大 更新值是这样的 0xFFD8F 6DC0676 但是 更新查询成功运行后 该值变为 0x0FFD8 6DC067 看起来最后 4 位丢失了 或者整个值右移了一个字节 我尝
  • 如何通过脚本设置Azure DevOps版本的描述?

    在 Azure DevOps 中 我尝试通过 PowerShell CMD 设置版本描述 以便根据构建步骤中工件的输入获得版本的动态描述 我尝试通过 powershell 设置发布变量 例如 Write Host vso task setv
  • 如何让循环中的多个ajax请求按顺序返回值?

    我必须循环发出一系列 Ajax 请求 大约有100个 每个请求都会返回一个 JSONP 变量 我从 JSON 中提取数据并将值附加到 div 中 问题是我希望 div 按函数调用的顺序附加数据 即依次 现在 每次刷新页面时 我都会根据请求完
  • Dask Dataframe 将列表的列拆分为多列

    在 Pandas 中可以轻松完成相同的任务 import pandas as pd df pd DataFrame lists i i 1 for i in range 10 df left right pd DataFrame x for
  • 这个“标签”在 C++ 中意味着什么?

    我正在阅读一些 C 代码 我看到了一些有趣的东西 代码是这样的 repeat code here fallback code here start another code 这是我第一次在 C 代码中看到这种 标签 我称之为标签是因为我在汇
  • 没有显式锁定的 postgres 死锁

    我使用 PostgreSQL 9 2 并且我没有在任何地方使用显式锁定 也没有LOCK声明也不SELECT FOR UPDATE 然而 最近我得到了ERROR 40P01 deadlock detected 不过 检测到死锁的查询被包装在事
  • 如何通过ajax将表单数据发送到python脚本?

    我正在努力处理 python 程序和 ajax 请求 我正在尝试将一些数据从 Javascript 获取到 python 程序中 我一直在使用 getfirst field name 的正常方法不起作用 我认为这是因为请求是通过 ajax
  • 在离开未保存更改的网页之前警告用户

    我的申请中有一些带有表格的页面 如何保护表单 以便在有人离开或关闭浏览器选项卡时 系统应提示他们确认是否确实要保留未保存数据的表单 简短 错误的答案 你可以通过以下方式做到这一点处理beforeunload事件并返回一个非空字符串 wind