Detecting Custom Protocol Handler in Windows 8+ with Chrome
Hey I think you were on the right track. It is definitly not that easy but chrome so far was not my problem, more like Edge + IE but my solution is assuming they don't support the protocol if anything fails or they don't respond correctly which they do sometimes.
The blur/focus is something to check but you need to check it in combination with a visibility change. The HTML5 Visiblity API and this post about it helped me figure out a solution that is pretty solid except the mentioned browsers above because they have some issues with the navigator.msLaunchUri function and have their own approach implemented which doesn't rely on blur/focus. But the function is bugged and doesn't respond correctly all the time.
You can find my codepen here. Hopefully that helps you even though it is a bit late for an answer. This works for mobile browsers as well but I didn't test multiple yet worked for my Android 6.0.2. Might need some tweaks in the long run but I think it is pretty solid.
(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();});
My code is tested with Win10: Chrome, Firefox, IE11, Edge + Android: Chrome (6.0.1)
there is also this github project https://github.com/ismailhabib/custom-protocol-detection which sorta has a similar approach maybe a little bit more maintained but i couldn't get their solution working for some reasons but maybe this is exactly what you need.
I think this might help you here with different browsers, but please define you question better or add at least some kinda example to make it clear.