Ответ 1
Эй, я думаю, ты был на правильном пути. Это определенно не так просто, но хром пока не был моей проблемой, больше похожей на Edge + IE, но мое решение предполагает, что они не поддерживают протокол, если что-то не работает или они не отвечают правильно, что они иногда делают.
Размытие/фокус - это что-то проверить, но вам нужно проверить его в сочетании с изменением видимости. API HTML Visiblity и этот пост об этом помогли мне найти решение, которое довольно твердое, за исключением упомянутых выше браузеров, потому что у них есть некоторые проблемы с функцию navigator.msLaunchUri и реализовать свой собственный подход, который не полагается на размытие/фокус. Но функция прослушивается и не реагирует правильно все время.
Здесь вы можете найти мой код здесь. Надеюсь, это поможет вам, хотя немного опоздал на ответ. Это работает и для мобильных браузеров, но я не тестировал несколько, но работал на моем 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, который имеет аналогичный подход, возможно, немного более поддерживается, но я не мог получить их решение работает по некоторым причинам, но, возможно, это именно то, что вам нужно.