2011-04-08 211 views
2

我的工作具有這些屬性的項目:自定義鼠標光標+ IE愁楚

  1. 的jQuery驅動的頁面嵌入到頁面使用jQuery和unityobject.js
  2. 團結3D播放器(每個指令從Unity )
  3. 統一定製鼠標光標時用戶的光標是統一的畫布區域的內部

問題:統一捕獲謀se光標,但當包含它的網頁變爲非活動狀態時不會釋放它。這意味着如果用戶切換到不同的選項卡(或打開一個新窗口),當用戶將鼠標放置在Unity所在的區域時,鼠標光標消失。這是在Unity3D論壇中描述的統一錯誤: http://forum.unity3d.com/threads/4565-Unity-Web-player-issue-mouse-hidden-for-all-new-windows

而且不,在最新版本的Unity Web客戶端中仍然沒有修復。

爲了緩解這個問題,我們決定讓Unity通過Javascript監聽當前的瀏覽器窗口狀態,並根據收到的狀態捕獲/釋放自定義鼠標光標。但也有其他的問題:

團結如何接收窗口狀態:

// GetUnity returns the Unity object in the DOM<br> 
NAMESPACE.windowStatus = function(statusStr) { 
    GetUnity().SendMessage("_AppShell", "OnRecieveWindowStatusFromWebPage", statusStr); 
} 

我嘗試以下方法...

方法1:將事件綁定到了「window」object

$(window).live('focus', function() { 
    NAMESPACE.windowStatus('active'); 
}); 

$(window).live('blur', function() { 
    NAMESPACE.windowStatus('inactive'); 
}); 

問題:在IE7和IE8中,新的瀏覽器選項卡不被認爲是不同的「窗口」,所以代碼對Unity沒有影響。它只在一個真正的單獨的瀏覽器窗口打開時才起作用。


方法2:將事件綁定到 「文件」 對象
像這樣的:$(document).live(...);

問題:jQuery的$(document)實際上什麼也不做。發現困難的方式。
來源:http://forum.jquery.com/topic/should-document-live-map-to-document-bind-window-too


方法3:結合事件到對象<body>
像這樣:$('body').live(...);

問題:不知何故IE不認識到,統一性對象是部分的DOM(儘管使用了.live()方法)。因此,每當用戶點擊嵌入式Unity播放器時,瀏覽器都會向Unity發送一個blur事件,並且鼠標光標被鎖定(當單擊Unity時,console.log()打印出inactive)。在某些情況下,它甚至不會釋放鼠標光標,導致整個瀏覽器對鼠標事件無響應;釋放光標的唯一方法是在瀏覽器窗口外單擊並再次單擊瀏覽器)。


其他的事情我已經試過:

window.addEventListener('focus', function() {...}); 
document.addEventListener('focus', function() {...}); 
document.body.addEventListener('focus', function() {...}); 
document.getElementsByTagName('body')[0].addEventListener('focus', function() {...}); 

問題:在IE瀏覽器不支持在所有這些因素.addEventListener()方法! GAH!


獎勵:
更細心的你可能在說,「嘿,爲什麼不檢測的統一的鼠標點擊事件對象本身,而忽略了blur事件,.live().bind()事件幫腔「。試過了。 IE也不喜歡它。它完全忽略了事件,並說這些事件不適用於該對象。

所以我的同事的Javascript大師。我不知道如何以最好的方式最好地解決這個問題。任何指針將不勝感激。

回答

1

問題已解決。在Unity3d的論壇上提供了一個解決方案,它埋在某處... http://forum.unity3d.com/threads/27516-Mouse-input-possible-from-different-tab

它的要點是:框架並不總是答案。回到根源。

我忘記了.addEventListener()不是原生的IE,.attachEvent()是。所以我上面的代碼可以工作了,當我檢測到IE時,我用IE特定的事件監聽器替換了所有的事件監聽器。

所以修改後的代碼如下:

if (navigator.appName == 'Microsoft Internet Explorer') { 
    GetUnity().attachEvent('onmouseover', onFocus, false); 
    GetUnity().attachEvent('onfocusin', onFocus, false); 
    GetUnity().attachEvent('onmouseout', onBlur, false); 
} else { 
    // Netscape, Firefox, Mozilla, Chrome and Safari. 
    GetUnity().addEventListener('mouseover', onFocus, false); 
    GetUnity().addEventListener('focus', onFocus, false); 
    GetUnity().addEventListener('mouseout', onBlur, false); 
} 

function onFocus() { 
    NAMESPACE.WindowStatus('active'); 
} 

function onBlur() { 
    NAMESPACE.WindowStatus('inactive'); 
} 

要真正使這項工作,你就必須讓事件附件的unityobject.embedUnity()方法的回調函數。如果您嘗試在Unity加載之前附加事件,瀏覽器將會抱怨GetUnity()nullundefined

希望這可以幫助別人在那裏發現同樣的問題。