There are countless questions about this but the answers to all of them are out of date with IE no longer supporting conditional statements, jQuery no longer supporting detection without a migrate plugin etc. This question has been asked before but there are no answers that remain supported in 2020.
The tag is a perfect example of how simple this should be. Surely there must be a way to detect the browser (IE) and then set a DIV with a warning message to visible.
There have been answers in the past but even they aren't supported now. Of course any JS used to detect the browser would need to be compatible with IE.
My first thought was to do something that would detect MSIE and then display a DIV. It seems up for debate as to if you should use feature or browser detection based on everything I've looked through for the last few hours.
The reason I need this message in IE is because the site isn't compatible due to new JS and CSS features. I wouldn't know where to start with this so apologies for not posting any code. All it needs is something like this.
// Detect if Internet Explorer
// If no do nothing
// If Internet Explorer
// Set iewarning to visible
.iewarning {
display: none;
}
<div class="iewarning">Update your browser</div>
I don't know how to go about detecting features, the browser or user agent but this question has to be asked again now that there's no conditional statements or jQuery support. Pure JS is the most ideal solution. Any approaches using that would be appreciated. Thanks in advance.
EDIT
If feature detection could be used to make a DIV visible.
if (typeof Promise == "undefined") {
document.getElementByClass("iewarning").style.display = "block";
}
.iewarning {
display: none;
}
<div class="iewarning">Please upgrade your browser</div>
That doesn't work though but seems like it could be a more minimal solution.
EDIT
Using a query selector instead should work? I'm entirely lost but willing to use feature detection if someone can help me get it working.
if (typeof Promise == "undefined") {
document.querySelector("div.iewarning").style.display = "block";
}
.iewarning {
display: none;
}
<div class="iewarning">Please upgrade your browser</div>
OK based on your comments so far here is the most simplfied browser detection approach I could devise using a div in the HTML as you requested.
function isUnsupported (browser) {
return (browser.name === "MSIE" || browser.name === "IE")
}
var isUnsupported = this.isUnsupported(this.get_browser());
// Uncomment to simulate being in an IE browser.
//var isUnsupported = true;
this.listen("load", window, function() {
if (isUnsupported) {
var warning = document.querySelector(".iewarning");
warning.style.display = 'block';
}
});
function listen(evnt, elem, func) {
if (elem.addEventListener) // W3C DOM
elem.addEventListener(evnt,func,false);
else if (elem.attachEvent) { // IE DOM
var r = elem.attachEvent("on"+evnt, func);
return r;
}
else window.alert('Error: unsupported browser!');
}
function get_browser() {
var ua = navigator.userAgent, tem, M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
if (/trident/i.test(M[1])) {
tem = /\brv[ :]+(\d+)/g.exec(ua) || [];
return { name: 'IE', version: (tem[1] || '') };
}
if (M[1] === 'Chrome') {
tem = ua.match(/\bOPR\/(\d+)/)
if (tem != null) { return { name: 'Opera', version: tem[1] }; }
}
if (window.navigator.userAgent.indexOf("Edge") > -1) {
tem = ua.match(/\Edge\/(\d+)/)
if (tem != null) { return { name: 'Edge', version: tem[1] }; }
}
M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, '-?'];
if ((tem = ua.match(/version\/(\d+)/i)) != null) { M.splice(1, 1, tem[1]); }
return {
name: M[0],
version: +M[1]
};
}
.iewarning {
display: none;
}
<div>Welcome to the Website👋</div>
<div class="iewarning">IE not supported. Please upgrade your browser.</div>
There are countless questions about this but the answers to all of them are out of date with IE no longer supporting conditional statements, jQuery no longer supporting detection without a migrate plugin etc.
They're not out of date, since those features are still no longer supported, and nothing new has arrived to replace them.
This question has been asked before but there are no answers that remain supported in 2020.
There's a reason for that.
The tag is a perfect example of how simple this should be. Surely there must be a way to detect the browser (IE) and then set a DIV with a warning message to visible.
There are ways, but they have varying degree of reliability, and none match what conditional comments provided.
There have been answers in the past but even they aren't supported now.
That's basically your answer right there.
Of course any JS used to detect the browser would need to be compatible with IE.
Would it? If it's not compatible, wouldn't that give you an indicator that the browser doesn't support the features you want to provide?
My first thought was to do something that would detect MSIE and then display a DIV. It seems up for debate as to if you should use feature or browser detection based on everything I've looked through for the last few hours.
Yes, read those debates. If you want to detect features, then detect features. If you actually want to detect browsers, then do so with the user agent.
The reason I need this message in IE is because the site isn't compatible due to new JS and CSS features.
What about other legacy browsers that don't support the features you want? Why do you only want to deal with one specific browser in this situation.
I wouldn't know where to start with this so apologies for not posting any code.
You already had a good start when you read the myriad of other discussions on this topic.
You seem unwilling to listen to any previous discussion and are hoping there's some magic that hasn't yet found its way to the internet.
There isn't.
Here's a summary of some options.
IE's legacy features - If the specific versions of IE that you want to detect have conditional comments enabled, then use that feature.
User agent sniffing - gives detailed information about the user agent. It can technically be spoofed by the user, but that's very rare, and who cares. If the user wants you to believe they're using a different browser, then let them.
Feature detection - If missing features are your concern, then this would seem to be the obvious choice. However, if you load libraries that provide compatibility for some of the missing features, it could get a little complicated. As long as you're aware of the 3rd party code you load, it shouldn't be an issue.
Let it break - Why not? Do you think your site is the only one they'll encounter that uses modern features? Most sites take this approach, and it works incredibly well.
Ask the user - Kindly request upon entry that the user tell you their browser and version. Say things like "pretty please" and convince them that it's of the utmost importance (lie to them), and you may have some success.
Write a virtual psychic library - This would harness the unseen powers of the universe to detect the exact browser and version of the visitor to your site. Seems like a winning solution to me.
You're not the first to want this, but you're sort of acting like this topic hasn't really been explored in full until today. It has. There's nothing new at the moment. When there is, it will be big news, and you'll see it discussed in those old posts.
I just wrote a codepen a couple of days ago that uses the approach codepen.io utilizes in production to notify a user when they come to their site with an IE browser. The notification is modal. It's pretty solid.
CSS:
* {
margin: 0;
padding: 0;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
#unsupported-message :last-child {
margin-bottom: 0px;
}
html, body {
height: 100%;
-webkit-overflow-scrolling: touch;
}
body {
background: #131417;
}
/* #media all and (min-width:831px) */
body {
position: relative;
height: auto;
min-height: 100vh;
}
body {
color: white;
}
body {
position: relative;
overflow-x: hidden;
overflow-y: auto;
height: 100vh;
background: #131417;
}
/* #media all and (min-width:831px) */
body:not(.sidebar-false) {
padding-left: 188px;
}
html {
font-family: "Lato", "Lucida Grande", "Lucida Sans Unicode", Tahoma, Sans-Serif;
line-height: 1.5;
font-size: 15px;
font-weight: 400;
}
html {
overflow-x: hidden;
}
#unsupported-overlay,
#unsupported-modal {
display: block;
position: absolute;
position: fixed;
left: 0;
right: 0;
z-index: 9999;
background: #000;
color: #D5D7DE;
}
#unsupported-overlay {
top: 0;
bottom: 0;
opacity: 0.7;
}
#unsupported-modal {
top: 80px;
margin: auto;
width: 90%;
max-width: 520px;
max-height: 90%;
padding: 40px 20px;
box-shadow: 0 10px 30px #000;
text-align: center;
overflow: hidden;
overflow-y: auto;
border: solid 7px #ffdd40;
}
#unsupported-message :last-child { margin-bottom: 0; }
#unsupported-message h2 {
font-family: 'Telefon', Sans-Serif;
font-size: 34px;
color: #FFF;
}
#unsupported-message h3 {
font-size: 20px;
color: #FFF;
}
body.hide-unsupport { padding-top: 24px; }
body.hide-unsupport #unsupported-message { visibility: hidden; }
#unsupported-banner {
display: block;
position: absolute;
top: 0;
left: 0;
right: 0;
background: #ffdd40;
color: #000;
font-size: 14px;
padding: 2px 5px;
line-height: 1.5;
text-align: center;
visibility: visible;
z-index: 199;
}
#unsupported-banner a {
color: #000;
text-decoration: underline;
}
#media (max-width: 800px), (max-height: 500px) {
#unsupported-message .modal p {
/* font-size: 12px; */
line-height: 1.2;
margin-bottom: 1em;
}
#unsupported-modal {
position: absolute;
top: 20px;
}
#unsupported-message h1 { font-size: 22px; }
body.hide-unsupport { padding-top: 0px; }
#unsupported-banner { position: static; }
#unsupported-banner strong,
#unsupported-banner u { display: block; }
}
JS:
// dirty vanilla listen method
function listen(evnt, elem, func) {
if (elem.addEventListener) // W3C DOM
elem.addEventListener(evnt,func,false);
else if (elem.attachEvent) { // IE DOM
var r = elem.attachEvent("on"+evnt, func);
return r;
}
else window.alert('Error: unsupported browser!');
}
// dirty browser detection but production worthy
function get_browser() {
var ua = navigator.userAgent, tem, M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
if (/trident/i.test(M[1])) {
tem = /\brv[ :]+(\d+)/g.exec(ua) || [];
return { name: 'IE', version: (tem[1] || '') };
}
if (M[1] === 'Chrome') {
tem = ua.match(/\bOPR\/(\d+)/)
if (tem != null) { return { name: 'Opera', version: tem[1] }; }
}
if (window.navigator.userAgent.indexOf("Edge") > -1) {
tem = ua.match(/\Edge\/(\d+)/)
if (tem != null) { return { name: 'Edge', version: tem[1] }; }
}
M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, '-?'];
if ((tem = ua.match(/version\/(\d+)/i)) != null) { M.splice(1, 1, tem[1]); }
return {
name: M[0],
version: +M[1]
};
}
function isUnsupported (browser) {
return (browser.name === "MSIE" || browser.name === "IE")
}
var isUnsupported = this.isUnsupported(this.get_browser());
/*
Uncomment the below line of code to simulate
being in an IE browser.
*/
//var isUnsupported = true;
if (isUnsupported) {
this.listen("load", window, function() {
var d1 = document.createElement('div');
var a1 = document.createElement('a');
var d2 = document.createElement('div');
var title = document.createElement('h2');
var p1 = document.createElement('p');
d1.id = 'unsupported-message';
a1.id = 'unsupported-overlay';
a1.href = '#unsupported-modal';
d2.id = 'unsupported-modal';
d2.role = 'alertdialog';
d2['aria-labelledby'] = 'unsupported-title';
title.id = 'unsupported-title';
title.innerHTML = 'âš Unsupported Browser âš ';
d2.appendChild(title);
d2.innerHTML += "This site does not support Internet Explorer. We generally only support the recent versions of major browsers like Chrome, Firefox, Safari, and Edge."
d2.appendChild(p1)
d1.appendChild(a1);
d1.appendChild(d2)
document.body.appendChild(d1);
});
} else {
var instructions = document.createElement('div')
instructions.innerHTML = "Uncomment line 45 (//var isUnsupported = true;) in the javascript to simulate being in an unsupported browser."
document.body.append(instructions)
}
Related
I decided to make a Pac-Man game and after I did it and everything was working somewhat fine on local document I pushed my website on Github pages and decrease in fps was enormous. It turned out page was making recalculation for hundreds elements which caused 20ms+ delay.
Here's a small part of the code that still has performance difference between local and github-pages hosted website.
const gameBoard = document.getElementById("game-board");
const root = document.documentElement.style;
let elements;
let characterNode;
let position = 658;
makeLevel();
function makeLevel() {
for (let i = 0; i < 868; i++) {
const element = document.createElement("DIV");
element.style.backgroundPosition = `0 0`;
let character = document.createElement("DIV");
character.className = "yellow";
element.append(character);
gameBoard.append(element);
}
elements = Array.from(gameBoard.children);
characterNode = elements[658].children[0];
changePosition();
}
function changePosition() {
root.setProperty(`--yellow-sprite-y`, `-32px`);
characterNode.style.transform = `translateX(-20px)`;
setTimeout(() => {
characterNode.style.transform = "";
characterNode.classList.remove(`yellow-visible`);
position = position - 1;
characterNode = elements[position].children[0];
characterNode.classList.add(`yellow-visible`);
changePosition()
}, 200)
}
:root {
--yellow-sprite-y: -32px;
}
#game-board {
width: 560px;
height: 620px;
display: grid;
grid-template-columns: repeat(28, 20px);
background-color: #000000;
}
#game-board > * {
position: relative;
width: 20px;
height: 20px;
}
.yellow {
position: absolute;
top: -4px;
left: -5.5px;
width: 30px;
height: 28px;
z-index: 10;
}
.yellow-visible {
background-image: url("https://i.imgur.com/SphNpH6.png");
background-position: -32px var(--yellow-sprite-y);
transition: transform 200ms linear;
}
<div id="game-board">
</div>
The exact problem in this code is line 29 which on local document performs like this:
while after hosting it on Github performs this way:
Why is it working this way and what can I do to lessen the performance decrease on hosted page?
Amazingly everything works well and bug doesn't exist on CodePen, yet on Github it still persists.
After getting some feedback that my site works well for other users I shared it on CodePen and it also worked fine, day later somebody said there could be an extension that could do something like that and indeed Adblocker Ultimate caused the slow performance.
I been trying to create a script that lets the user know if the #x element is in complete view or not so I have an if else conditional statement, which determines that.
The if condition is triggered in this situation
If the #x element can be seen completely in the web page.
The else condition is triggered in the following situations.
The #x element can not be seen at all or portions of the #x element can be seen.
Situation 1:
The window is small enough that the #x element is not seen any more or
the #x element is in incomplete view.
Situation 2:
CSS positioning is used to have the #x element not see able or incompletely in view in the web page.
Situation 3:
The #x element is so big for the web page to see completely that a portion of it is shown regardless if there is a scroll bar or not.
So even if the #x element is a pixel off in view then the else condition is still triggered as well.
Situation 4:
Other elements push the #x element out of sight or the #x element is pushed just enough where only a portion of the #x element can be seen in the web page.
Heads up
So how can I do this? I made many attempts to try to figure this out on my own but no luck yet so please provide a code example with my code in pure JavaScript only and please no jQuery examples or links to articles or other posts. I asked similar questions like this before in the past and no luck still. I just been
frustrated on the responses that I had been getting and now I question if this is even possible to do. I’m not asking any of you guys to do the code for me, all I’m asking if any of you guys can provide a code example with my code on how this can be done because I learned best that way just a heads up.
My current code now
/*
????
if(???){
var status='You can see #x completely in the web page.';
}
else{
var status='You can not see #x completely in the web page.';
}
document.querySelector('#status-output').innerHTML= status;
*/
html{
background-color: dodgerblue;
}
#x{
position: absolute;
top: -5px; /*<-- This should trigger the else condition because this makes the element not completely in view on the web page.*/
left: 15px;
background-color: lime;
height: 150px;
width: 150px;
border: 3px solid black;
}
#status-output{
position: absolute;
top: 150px;
}
<div id='x'></div>
<p id='status-output'></p>
I have made this exmaple base on your code. The checkSeen function is what you need for checking if element can be seen base on its position. I have also add an interval to move the <div> around so that you can see the status update base on the <div> position. Hope this help.
function checkSeen(id){
var x = document.getElementById(id);
if(x.offsetTop < 0 ) return false;
if(x.offsetLeft < 0 ) return false;
if(x.offsetTop + x.offsetHeight > window.innerHeight) return false;
if(x.offsetLeft + x.offsetWidth > window.innerWidth) return false;
return true;
}
function updateStatus(seen){
if(seen){
var status='You can see #x completely in the web page.';
}else{
var status='You can not see #x completely in the web page.';
}
document.querySelector('#status-output').innerHTML= status;
}
updateStatus(checkSeen("x"));
var testMovingInterval = setInterval(function(){
var x = document.getElementById("x");
if(x.offsetTop - window.innerHeight > 100){
x.style.top = "-100px";
}else{
x.style.top = (x.offsetTop + 1) + "px";
}
updateStatus(checkSeen("x"));
}, 10);
html{
background-color: dodgerblue;
}
#x{
position: absolute;
top: -5px; /*<-- This should trigger the else condition because this makes the element not completely in view on the web page.*/
left: 15px;
background-color: lime;
height: 150px;
width: 150px;
border: 3px solid black;
}
#status-output{
position: absolute;
top: 150px;
}
<div id='x'></div>
<p id='status-output'></p>
Something like:
const winTop = window.pageYOffset || document.documentElement.scrollTop;
const winLeft = window.pageXOffset || document.documentElement.scrollLeft;
const winWidth = window.innerWidth || document.documentElement.clientWidth;
const winHeight = window.innerHeight || document.documentElement.clientHeight;
const xElem = document.getElementById('x').getBoundingClientRect();
const doesFit = xElem.top >= winTop &&
xElem.left >= winLeft &&
xElem.top + xElem.height <= winHeight &&
xElem.left + xElem.width <= winWidth;
const status = `You ${doesFit ? 'can' : 'can not'} see #x completely in the web page.`;
I'm working through the Single Page Web Applications book and the first example in it isn't working properly in Chrome, but does work in Firefox. The essential code is the following:
.spa-slider {
position: absolute;
bottom: 0;
right: 2px;
width: 300px;
height: 16px;
cursor: pointer;
border-radius: 8px 0 0 0;
background-color: #f00;
}
The JavaScript code is the following:
var spa = (function($) {
var configMap = {
extended_height: 434,
extended_title: 'Click to retract',
retracted_height: 16,
retracted_title: 'Click to extend',
template_html: '<div class="spa-slider"></div>'
},
$chatSlider, toggleSlider, onClickSlider, initModule;
toggleSlider = function() {
var slider_height = $chatSlider.height();
console.log("slide_height: " + slider_height);
if (slider_height == configMap.retracted_height) {
$chatSlider.animate({height: configMap.extended_height})
.attr('title', configMap.extended_title);
return true;
}
if (slider_height == configMap.extended_height) {
$chatSlider.animate({height: configMap.retracted_height})
.attr('title', configMap.retracted_title);
return true;
}
return false;
};
onClickSlider = function(event) {
toggleSlider();
return false;
};
initModule = function($container) {
$container.html(configMap.template_html);
$chatSlider = $container.find('.spa-slider');
$chatSlider.attr('title', configMap.retracted_title)
.click(onClickSlider);
return true;
};
return {initModule: initModule};
}(jQuery));
jQuery(document).ready(function() {
spa.initModule(jQuery('#spa'));
});
My question is essentially the following. The slider doesn't seem to work on Chrome, because console.log("slide_height: " + slider_height); prints 17, so it matches neither of the if guards. On Firefox it prints 16, so the height() property gets the correct value. Can anyone explain why this happens and what is a portable way to write the code?
UPDATE: I use 90% zoom on Chrome and changing it to 100% seems to make the code work correctly. However, the code should clearly work on all zoom levels, so how can this be accomplished? I'm surprised that the book uses code that is so brittle.
I used this JavaScript code to full screen the page:
<script>
function requestFullScreen(element) {
// Supports most browsers and their versions.
var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullscreen;
if (requestMethod) { // Native full screen.
requestMethod.call(element);
} else if (typeof window.ActiveXObject !== "undefined") { // Older IE.
var wscript = new ActiveXObject("WScript.Shell");
if (wscript !== null) {
wscript.SendKeys("{F11}");
}
}
}
</script>
And then changed the full screen page background color:
html:-moz-full-screen {
background: red;
}
html:-webkit-full-screen {
background: red;
}
html:-ms-fullscreen {
background: red;
width: 100%; /* needed to center contents in IE */
}
html:fullscreen {
background: red;
}
but it doesn't work in safari.
How can I change full screen background color in safari?
why not just use this in your css:
html{
background-color: #ff0000;
}
if it's not working you may have other issues and it would be good too see your full html and css.
otherwise you may try this:
http://johndyer.name/native-fullscreen-javascript-api-plus-jquery-plugin/
<script language="JavaScript" type="text/javascript">
var theBar = createProgressBar(document.getElementById('progress-bar'));
var value;
function resetValue() {
value = 0;
}
function showProgress() {
value += 1;
theBar.setValue(value);
if (value < 100) {
window.setTimeout(showProgress, 100);
}
}
window.onload=resetValue();showProgress();
</script>
--
<script language="JavaScript" type="text/javascript">
function createProgressBar(elem) {
var div1 = document.createElement('DIV');
div1.className = 'progress-bar-background';
div1.style.height = elem.offsetHeight + 'px';
elem.appendChild(div1);
var div2 = document.createElement('DIV');
div2.className = 'progress-bar-complete';
div2.style.height = elem.offsetHeight + 'px';
div2.style.top = '-' + elem.offsetHeight + 'px';
elem.appendChild(div2);
return {
div1 : div1,
div2 : div2,
setValue : function(v) {
this.div2.style.width = v + '%';
}
}
}
</script>
--
div.field input{
height: 45px;
width: 270px;
font-size: 24px;
}
.progress-bar-background {
background-color: #D0D0D0;
width: 100%;
position: relative;
overflow:hidden;
top: 0;
left: 0;
}
.progress-bar-complete {
background-color: green;
width: 50%;
position: relative;
overflow:hidden;
top: -12px;
left: 0;
}
#progress-bar {
width: auto;
height: 10px;;
overflow:hidden;
border: 0px black solid;
}
--
This snippet works perfectly under Chromer, Safari and FireFox.
The only issue is with Internet Explorer.
It seems to render as "half-full" and doesn`t execute anything.
Since I`m not that familiar with JS I have no clue what to start looking for.
Would appreciate some noob friendly advice.
change this...
window.onload=resetValue();showProgress();
to this...
window.onload = function() {
createProgressBar();
resetValue();
showProgress();
};
and you should be fine.
Remember...
"window.onload" is a property of the Window object ... and the value of this property should be a function that will execute automatically once the browser has loaded the entire DOM AND all the content (images, css, js, etc.)
This a NOT a good place to execute your stuff however -- you should use the event "onContentLoaded" but since it is not uniformly supported across browsers -- you should use a JavaScript library such as jQuery or Prototype or MooTools instead.
BUT -- of course if you're new to JS -- do NOT skim over it in order to get the pleasure of using these libs -- first get the real taste of what JavaScript is and what it is like to juggle with the browser incompatibilities -- only then you'll be able to appreciate the full potential of these libraries.
The first thing I see is that you shouldn't create the progress bar (or reference anything in the DOM) until the page has been loaded. IE is particularly sensitive to this. It looks to me like you're calling createProgressBar right when the javascript is loaded rather than after the page is loaded.
When I put your stuff into a jsFiddle and make sure that the code doesn't run until the page is loaded, it works for me in IE8.
See it here: http://jsfiddle.net/jfriend00/CQqat/