Emscripten canvas + jQuery - 切换焦点
Emscripten canvas + jQuery - toggle focus
我有一个 HTML 页面,大致将 30% - 70% 分为两个垂直栏。左列包含聊天提要(通过 Node 和 Socket.io 处理),右列包含 emscripten 生成的 canvas
(ID 为 canvas
)。 canvas 包含一个基本的 3D 世界,用户可以使用标准的第一人称控件(WASD 用于移动,鼠标指向 'look')进行导航。
默认情况下,canvas 吞没所有键盘事件。我在 canvas 初始化过程中使用以下代码解决了这个问题:
Module.preRun.push(function () {
ENV.SDL_EMSCRIPTEN_KEYBOARD_ELEMENT = "#canvas";
});
这让我可以手动关注聊天框,输入消息,然后提交。
我 运行 遇到的问题是,一旦提交了聊天消息,我就会尝试 return 使用以下代码将注意力集中到 canvas (以允许玩家使用 WASD 导航 3d 世界):
$('#canvas').focus();
这名义上 return 将焦点转移到 canvas,但鼠标和键盘移动不起作用。奇怪的是,点击 tab/browser window 然后进入 canvas 似乎可行 - 焦点 returned 到 canvas,我可以再次导航.手动调用 $(window).blur().focus()
不起作用。
有人知道如何在发送聊天消息后将焦点强制返回到 canvas 吗?
--更新--
我在 canvas 后面添加了一个文本输入字段(ID 为 hiddenField
),我正在使用 preRun 函数为 canvas 分配按键事件到该字段(canvas 由于某种原因不能始终如一地工作)。
这很好用 直到 用户点击 canvas - 例如,进入聊天区域 - 于是 canvas 停止响应任何键盘或鼠标输入,即使我触发焦点回到 hiddenField
(并且可以看到它正在获取)。
似乎在页面上做 任何事情 与 emscripten 的聚焦行为(我相信与 window 对象相关联)冲突并阻止 canvas从重新获得焦点。
肯定有一些方法可以让 emscripten canvas 与其他 HTML 元素共存?
我找到的最好的方法——事实上,让应用程序的各个方面(聊天和 3D 世界)正常工作的唯一方法——是嵌入 emscripten canvas 在 iframe
中,并在必要时使用跨框架函数调用来触发操作。
Page
- chat
- iframe
-- emscripten-generated page
这不是我的首选解决方案,但它是我设法开始工作的唯一解决方案。
您需要通过添加 tabindex="0"
属性使 canvas
对象可聚焦。
那么应该可以正常触发focus事件了:
document.querySelector("#canvas").focus()
编辑:
通过 CodePen 查看完整演示(包括指向 .js
资源的链接)
结构:
Page
- emscripten-generated-page
- loop
- chat
- script to handle global key input handlers
您必须在canvas元素上设置tabindex
(如luke and described on MDN所述),通过[=47附加全局事件监听器=] 的内置 Document
接口,然后调用 .triggerHandler()
以确保 canvas returns 到它的默认状态,由 click
:
var chatInputField = $("#message-input");
var canvas = $("#canvas");
canvas.on("click", function(e){
return document.addEventListener("keyup", game.toggleKeys);
});
chatInputField.on("focusin", function(e) {
$('#canvas').attr('tabindex', 0);
return document.removeEventListener("keyup", game.toggleKeys, false);
});
chatInputField.on("focusout", function(e) {
$("#canvas").triggerHandler('click');
chatInputField.attr('tabindex', 0);
});
我已经测试过了,它有效。这是我的 app.js 文件,用于管理键输入(参见第 297 行)。
https://gist.github.com/shagamemnon/585df8dd215a949b839f8b02199af31b
注意:您必须明确定义游戏中tab
键的行为canvas。
我有一个 HTML 页面,大致将 30% - 70% 分为两个垂直栏。左列包含聊天提要(通过 Node 和 Socket.io 处理),右列包含 emscripten 生成的 canvas
(ID 为 canvas
)。 canvas 包含一个基本的 3D 世界,用户可以使用标准的第一人称控件(WASD 用于移动,鼠标指向 'look')进行导航。
默认情况下,canvas 吞没所有键盘事件。我在 canvas 初始化过程中使用以下代码解决了这个问题:
Module.preRun.push(function () {
ENV.SDL_EMSCRIPTEN_KEYBOARD_ELEMENT = "#canvas";
});
这让我可以手动关注聊天框,输入消息,然后提交。
我 运行 遇到的问题是,一旦提交了聊天消息,我就会尝试 return 使用以下代码将注意力集中到 canvas (以允许玩家使用 WASD 导航 3d 世界):
$('#canvas').focus();
这名义上 return 将焦点转移到 canvas,但鼠标和键盘移动不起作用。奇怪的是,点击 tab/browser window 然后进入 canvas 似乎可行 - 焦点 returned 到 canvas,我可以再次导航.手动调用 $(window).blur().focus()
不起作用。
有人知道如何在发送聊天消息后将焦点强制返回到 canvas 吗?
--更新--
我在 canvas 后面添加了一个文本输入字段(ID 为 hiddenField
),我正在使用 preRun 函数为 canvas 分配按键事件到该字段(canvas 由于某种原因不能始终如一地工作)。
这很好用 直到 用户点击 canvas - 例如,进入聊天区域 - 于是 canvas 停止响应任何键盘或鼠标输入,即使我触发焦点回到 hiddenField
(并且可以看到它正在获取)。
似乎在页面上做 任何事情 与 emscripten 的聚焦行为(我相信与 window 对象相关联)冲突并阻止 canvas从重新获得焦点。
肯定有一些方法可以让 emscripten canvas 与其他 HTML 元素共存?
我找到的最好的方法——事实上,让应用程序的各个方面(聊天和 3D 世界)正常工作的唯一方法——是嵌入 emscripten canvas 在 iframe
中,并在必要时使用跨框架函数调用来触发操作。
Page
- chat
- iframe
-- emscripten-generated page
这不是我的首选解决方案,但它是我设法开始工作的唯一解决方案。
您需要通过添加 tabindex="0"
属性使 canvas
对象可聚焦。
那么应该可以正常触发focus事件了:
document.querySelector("#canvas").focus()
编辑:
通过 CodePen 查看完整演示(包括指向 .js
资源的链接)
结构:
Page
- emscripten-generated-page
- loop
- chat
- script to handle global key input handlers
您必须在canvas元素上设置tabindex
(如luke and described on MDN所述),通过[=47附加全局事件监听器=] 的内置 Document
接口,然后调用 .triggerHandler()
以确保 canvas returns 到它的默认状态,由 click
:
var chatInputField = $("#message-input");
var canvas = $("#canvas");
canvas.on("click", function(e){
return document.addEventListener("keyup", game.toggleKeys);
});
chatInputField.on("focusin", function(e) {
$('#canvas').attr('tabindex', 0);
return document.removeEventListener("keyup", game.toggleKeys, false);
});
chatInputField.on("focusout", function(e) {
$("#canvas").triggerHandler('click');
chatInputField.attr('tabindex', 0);
});
我已经测试过了,它有效。这是我的 app.js 文件,用于管理键输入(参见第 297 行)。
https://gist.github.com/shagamemnon/585df8dd215a949b839f8b02199af31b
注意:您必须明确定义游戏中tab
键的行为canvas。