2017-08-29 52 views
11

我有一個HTML頁面,粗略地將30%-70%劃分爲兩個垂直列。左欄包含一個聊天源(通過Node和Socket.io處理),右列包含一個emscripten生成的canvas(ID爲canvas)。畫布包含一個基本的3D世界,用戶可以使用標準的第一人稱控件(WASD移動,鼠標移動到「外觀」)進行導航。Emscripten canvas + jQuery - 切換焦點

默認情況下,畫布吞下所有鍵盤事件。我與畫布初始化過程在下面的代碼解決了這個問題:

Module.preRun.push(function() { 
    ENV.SDL_EMSCRIPTEN_KEYBOARD_ELEMENT = "#canvas"; 
}); 

這讓我手動對焦聊天框中,鍵入消息,並提交。

我遇到的問題是,一旦聊天消息已提交,我試着用下面的代碼焦點返回到畫布(允許玩家使用導航WASD 3D世界):

$('#canvas').focus(); 

名義上將焦點返回到畫布,但鼠標和鍵盤移動不起作用。奇怪的是,單擊標籤頁/瀏覽器窗口,然後進入畫布似乎工作 - 焦點返回到畫布,我可以再次導航。手動撥打$(window).blur().focus()並不能解決問題。

有沒有人知道如何強制回到畫布一旦聊天消息已發送?

- 更新 -

我在畫布背後添加了一個文本輸入框(與hiddenField的ID)和我正在使用預電泳功能分配關鍵事件爲畫布到字段(由於某種原因,畫布不能始終如一地工作)。例如,在聊天字段 - -

直到用戶點擊了畫布工作正常於是畫布停止響應任何鍵盤或鼠標輸入,即使我觸發聚焦放回hiddenField(和可以看到它得到它)。

看起來這個頁面上的任何東西與emscripten的聚焦行爲(我認爲綁定到窗口對象)衝突,並阻止畫布重新獲得焦點。

肯定有一些方法可以讓emscripten畫布與其他HTML元素一起生活嗎?

回答

6

我已經能夠找到這一點的最好辦法 - 實際上,獲取應用程序的獨立方面的唯一途徑(聊天& 3D世界)正常工作 - 已嵌入在iframe的emscripten帆布必要時使用跨幀函數調用來觸發操作。

Page 
    - chat 
    - iframe 
     -- emscripten-generated page 

這不是我的解決方案的第一選擇,但它是我唯一能成功工作的人。

2

您需要通過添加tabindex="0"屬性使canvas對象成爲焦點。

然後,它應該能夠正確地觸發焦點事件:

document.querySelector("#canvas").focus() 
1

編輯:通過CodePen

查看完整的演示(包括鏈接到.js資源)

結構:

Page 
    - emscripten-generated-page 
     - loop 
    - chat 
    - script to handle global key input handlers 

必須設置tabindex canvas元素(如lukedescribed on MDN說明),通過連接全球的事件偵聽器的JavaScript的內置Document接口,然後調用.triggerHandler()確保畫布返回到它的默認狀態,管轄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鍵的行爲。