我正在尝试检测处理自定义协议(protocol)的应用程序是否已安装并使用不同的浏览器运行。我查看了该网站上的其他问题,例如: How to detect browser's protocol handlers? , 并研究了类似的资源,使其可以在大多数浏览器的大多数平台上运行。
在将其标记为重复之前,请听我说完......
我能够让我的函数在除 Windows 8+ 上的 Chrome 之外的所有平台上运行。我无法像在 Windows 7 上那样在 Chrome 上使用窗口焦点方法,因为它会弹出消息,要求我在商店中查找应用程序。
是否有任何方法(无需扩展)可以在 Chrome 上的 Windows 8+ 中检测自定义协议(protocol)处理程序?
更新:
使用 onBlur 来检测它仅适用于 Windows 7,因为在 8+ 中,如果它找不到打开协议(protocol)的内容,它会打开“从应用程序商店查找内容”对话框,从而使浏览器失去焦点。
最佳答案
嘿,我认为你走在正确的道路上。这绝对不是那么容易,但到目前为止 chrome 不是我的问题,更像是 Edge + IE,但我的解决方案是假设如果出现任何故障,它们不支持该协议(protocol),或者它们不能正确响应(有时它们会这样做)。
模糊/焦点是需要检查的内容,但您需要结合可见性变化来检查它。 HTML5 Visblity API 和这篇文章 about it帮助我找到了一个非常可靠的解决方案,除了上面提到的浏览器之外,因为它们在 navigator.msLaunchUri 函数方面存在一些问题,并且实现了自己的方法,不依赖于模糊/焦点。但该功能存在 bug,始终无法正确响应。
你可以找到我的codepen here 。希望这对您有所帮助,尽管现在回答有点晚了。这也适用于移动浏览器,但我没有测试多个,但适用于我的 Android 6.0.2。从长远来看可能需要一些调整,但我认为它非常可靠。
(function() {
var noProtocolHash = '#protocolXYnotsupported',
checkDelay = 800, // apps might start slowly
isBlurred = false,
inCheck = false,
inLauncherCheck = false,
tabVisible = (function(){
var stateKey,
eventKey,
keys = {
hidden: "visibilitychange",
webkitHidden: "webkitvisibilitychange",
mozHidden: "mozvisibilitychange",
msHidden: "msvisibilitychange"
};
for (stateKey in keys) {
if (stateKey in document) {
eventKey = keys[stateKey];
break;
}
}
return function(c) {
if (c) document.addEventListener(eventKey, c);
return !document[stateKey];
}
})(),
isMSIE = function(){
var rv = -1;
if(navigator.appName == 'Microsoft Internet Explorer'){
var ua = navigator.userAgent;
var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
if(re.exec(ua) != null){
rv = parseFloat(RegExp.$1);
}
}
else if(navigator.appName == 'Netscape'){
var ua = navigator.userAgent;
var re = new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})");
if(re.exec(ua) != null){
rv = parseFloat(RegExp.$1);
}
}
return (rv !== -1)? true: false;
},
isEdge = function(){
return window.navigator.userAgent.indexOf("Edge") > -1;
},
checkIfFocusLost = function($el){
try {
document.location.href = $el.attr("href");
} catch (ex) {
document.location.href = document.location.href + '/' + noProtocolHash;
}
setTimeout(checkVisibility, checkDelay);
},
checkVisibility = function(){
if(tabVisible() && !isBlurred){
handleNoProtocol();
}
else {
handleProtocol();
}
},
handleNoProtocol = function(){
$('.result').text('has no protocol');
inLauncherCheck = false;
},
handleProtocol = function(){
$('.result').text('has the protocol');
inLauncherCheck = false;
},
checkHash = function(){
if(document.location.hash === noProtocolHash){
handleNoProtocol();
}
},
checkLauncherProtocol = function($el){
inLauncherCheck = true;
navigator.msLaunchUri($el.attr("href"), function(){
handleProtocol();
},
function(){
handleNoProtocol();
});
setTimeout(function(){
// fallback when edge is not responding correctly
if(inLauncherCheck === true){
handleNoProtocol();
}
}, 500);
},
checkIfHasProtocol = function($el){
inCheck = true;
if(isEdge() || isMSIE()){
checkLauncherProtocol($el);
}
else {
checkIfFocusLost($el)
}
};
checkHash();
tabVisible(function(){
if(tabVisible() && inCheck){
handleProtocol();
inCheck = false;
}
});
window.addEventListener("blur", function(){
isBlurred = true;
});
window.addEventListener("focus", function(){
isBlurred = false;
inCheck = false;
});
window.checkIfHasProtocol = checkIfHasProtocol;
})();
$('.protocol').click(function(e) {
checkIfHasProtocol($(this));
e.preventDefault();
});
我的代码已在 Win10:Chrome、Firefox、IE11、Edge + Android:Chrome (6.0.1) 上进行了测试
还有这个github项目https://github.com/ismailhabib/custom-protocol-detection哪个有类似的方法,可能需要更多维护,但由于某些原因我无法让他们的解决方案工作,但也许这正是您所需要的。
关于javascript - 使用 Chrome 检测 Windows 8+ 中的自定义协议(protocol)处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29108347/