如何在 Chrome 的信息亭模式下禁用右侧 click/long 触摸的上下文菜单?

How to disable context menu on right click/long touch in a kiosk mode of Chrome?

我们正在为博物馆开发软件。 Windows 8.1 上有几个带有触摸屏 运行 的交互式信息亭,它们已连接到本地网络。没有键盘,没有鼠标。装有 Apache 的服务器包含几个本地网站。每个信息亭都以信息亭模式运行 Google Chrome 的副本。因此,我们有某种本地 Web 应用程序可以为博物馆参观者提供信息。

现在,问题来了。如果访问者在屏幕上长按,它的工作方式类似于右键单击。出现上下文菜单。我们根本不想要它。我已将 "oncontextmenu = return false" 添加到 body 标签中,这很有帮助。但。我们在 iframe 中有几个外部网站 运行(博物馆可以连接到互联网)。上下文菜单 确实 出现在 iframe 上。 AFAIK,无法使用 javascript.

禁用它

我们的系统工程师在 Windows 中得到了一个完全禁用右键单击的软件。任何地方,包括 Chrome。但。它适用于鼠标。至于触摸……好吧,它会在 除了 Chrome 之外的任何地方禁用触摸事件。也许 Chrome 有自己的触摸事件处理程序,我不知道。

所以,毕竟。我们需要在 Chrome 的 kiosk 模式下摆脱右侧 click/long 触摸的 iframe 上的上下文菜单。请给我一些建议。

我假设您在信息亭上显示一个普通的 http://...(或者可能 https://...file://...)网页。如果您实际展示的是应用程序(即 chrome-extension://...),那么此策略将不起作用。

window.addEventListener("contextmenu", function(e) { e.preventDefault(); }) 注入每个浏览上下文的 Chrome 扩展可能会阻止 iframe 上的上下文菜单。

manifest.json:

{
    "manifest_version": 2,
    "name": "Context Menu Blocker",
    "version": "1.0",
    "content_scripts": [
      {
        "matches": ["<all_urls>"],
        "js": ["contextblocker.js"],
        "all_frames": true,
        "match_about_blank": true
      }
    ]
}

contextblocker.js:

window.addEventListener("contextmenu", function(e) { e.preventDefault(); })

简单的新建一个文件夹,把两个文件放在里面。然后,转到 chrome://extensions/,选中 Developer Mode 框。最后,单击 Load unpacked extension... 和 select 您刚刚创建的文件夹。

这应该可以防止上下文菜单出现在允许扩展内容脚本 运行 的任何地方,包括在 iframe 中加载的任何页面。它有几个值得注意的地方失败了:

  • 运行 不允许在 chrome://chrome-extension:// 页面或 Google 的网上应用店上扩展。如果您的信息亭正在显示一个应用程序,则整个策略将不起作用,因为此扩展程序将无法访问另一个应用程序或扩展程序内的 iframe(即使 iframe 的来源是它通常具有权限的来源访问)。
  • 如果您直接导航到 about:blank,内容脚本将不会 运行,并且可以显示上下文菜单。 (但是,如果 about:blank 加载到 iframe 中,该块将正常工作。)
  • 如果 iframe 的 sandbox 属性不包含 allow-scripts 权限,则扩展无法阻止来自该 iframe 的上下文菜单。

只要 none 这些限制适用(并且只要页面上的脚本本身不清除 window 上的所有事件侦听器),它就应该可以工作。

我已经使用上面的代码创建了 a simple extension in the Chrome Web Store。 (开发人员模式扩展现在会在启动时产生警告,而网上商店扩展则不会。)

如果您使用的是 jQuery,下面的代码将禁用上下文菜单(又名 'right click')。

$(document).on("contextmenu",function(){
       return false;
    }); 
});