Check if viewport meta tag is being used

I have a canvas that needs to be resized when the browser window is resized, so I have the following:

var resizeCanvas = function () {
    var ratio =  Math.max(window.devicePixelRatio || 1, 1);
    canvas.width = (canvas.offsetWidth || canvas.width) * ratio;
    canvas.height = (canvas.offsetHeight || canvas.height) * ratio;
    canvas.getContext('2d').scale(ratio, ratio);
}

window.addEventListener('resize', resizeCanvas);

This works great, except on mobile devices scrolling triggers the resize event.

This is undesired as resizing the canvas clears its contents, which means as a mobile user scrolls, the canvas is always wiped.

Thanks to this answer I came up with a solution based on caching the width and double checking it, but based on my design, I really only need to resolve the issue for devices which are affected by my viewport metatag:

<meta name="viewport" content="width=device-width, initial-scale=1">

Is there someway I can check if that meta tag is being used by the browser? I'm looking for something like:

if(viewportMetaTagIsUsed){
    //For mobile browsers
    window.addEventListener("orientationchange", resizeCanvas);
} else {
    //For desktop browsers
    window.addEventListener('resize', resizeCanvas);
}

Answers:

Answer

AFAIK, it's not possible to detect whether a browser is capable of processing the viewport meta-tag.

Herebelow are some alternatives to consider...


Alternative 1 : browser sniffing

!function(a){var b=/iPhone/i,c=/iPod/i,d=/iPad/i,e=/(?=.*\bAndroid\b)(?=.*\bMobile\b)/i,f=/Android/i,g=/(?=.*\bAndroid\b)(?=.*\bSD4930UR\b)/i,h=/(?=.*\bAndroid\b)(?=.*\b(?:KFOT|KFTT|KFJWI|KFJWA|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|KFARWI|KFASWI|KFSAWI|KFSAWA)\b)/i,i=/IEMobile/i,j=/(?=.*\bWindows\b)(?=.*\bARM\b)/i,k=/BlackBerry/i,l=/BB10/i,m=/Opera Mini/i,n=/(CriOS|Chrome)(?=.*\bMobile\b)/i,o=/(?=.*\bFirefox\b)(?=.*\bMobile\b)/i,p=new RegExp("(?:Nexus 7|BNTV250|Kindle Fire|Silk|GT-P1000)","i"),q=function(a,b){return a.test(b)},r=function(a){var r=a||navigator.userAgent,s=r.split("[FBAN");return"undefined"!=typeof s[1]&&(r=s[0]),s=r.split("Twitter"),"undefined"!=typeof s[1]&&(r=s[0]),this.apple={phone:q(b,r),ipod:q(c,r),tablet:!q(b,r)&&q(d,r),device:q(b,r)||q(c,r)||q(d,r)},this.amazon={phone:q(g,r),tablet:!q(g,r)&&q(h,r),device:q(g,r)||q(h,r)},this.android={phone:q(g,r)||q(e,r),tablet:!q(g,r)&&!q(e,r)&&(q(h,r)||q(f,r)),device:q(g,r)||q(h,r)||q(e,r)||q(f,r)},this.windows={phone:q(i,r),tablet:q(j,r),device:q(i,r)||q(j,r)},this.other={blackberry:q(k,r),blackberry10:q(l,r),opera:q(m,r),firefox:q(o,r),chrome:q(n,r),device:q(k,r)||q(l,r)||q(m,r)||q(o,r)||q(n,r)},this.seven_inch=q(p,r),this.any=this.apple.device||this.android.device||this.windows.device||this.other.device||this.seven_inch,this.phone=this.apple.phone||this.android.phone||this.windows.phone,this.tablet=this.apple.tablet||this.android.tablet||this.windows.tablet,"undefined"==typeof window?this:void 0},s=function(){var a=new r;return a.Class=r,a};"undefined"!=typeof module&&module.exports&&"undefined"==typeof window?module.exports=r:"undefined"!=typeof module&&module.exports&&"undefined"!=typeof window?module.exports=s():"function"==typeof define&&define.amd?define("isMobile",[],a.isMobile=s()):a.isMobile=s()}(this);

alert(isMobile.any ? 'Mobile' : 'Not mobile');

This particular browser sniffing code is that of a library called isMobile.


Alternative 2 : window.orientation

Test is window.orientation is defined :

alert(typeof window.orientation !== 'undefined' ? 'Mobile' : 'Not mobile');

Answer

Ideally, you should treat mobile devices and desktops as the same, because the line is so very blurred. Tablet propped up with a keyboard? Laptop with touchscreen? The only difference is where the cpu is located at that point.

Stick with what you were doing: Cache the width and check if it changes. Don't try to determine if the device is a mobile or a desktop device, because you will at some point fail.

Answer

Have you tried:

var viewportMetaTag = document.querySelector('meta[name="viewport"]');
var viewportMetaTagIsUsed = viewportMetaTag && viewportMetaTag.hasAttribute('content') ? true : false;

Documentation on MDN:

Answer

you can check if orientationchange event exists or not and based on that assign the function. something like below code

if("onorientationchange" in window) {
  //For mobile browsers
  window.addEventListener("orientationchange", resizeCanvas);
} else{
  //For desktop browsers
  window.addEventListener('resize', resizeCanvas);
}

code snippet to detect event support is taken from below thread

Detecting support for a given JavaScript event?

Answer

Try this:

//mobile detection
    var isDevice = false;
    if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
        isDevice = true;
        // your code ...
    }

or:

if ($('meta[name="viewport"]').size() > 0) {
      // your code ...
}

or:

if ($('meta[name="viewport"]').attr('content').indexOf('device-width') - 1) {
      // your code ...
}
Answer

I would argue that what you want is not necessarily to detect the use of the viewport tag, but really whether you are running inside of a mobile browser.

From this answer we can snag a function to detect most mobile browsers:

window.mobilecheck = function() {
    var check = false;
    (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera);
    return check;
}

Then you can use it to do what you want:

if(window.mobilecheck()){
    //For mobile browsers
    window.addEventListener("orientationchange", resizeCanvas);
} else {
    //For desktop browsers
    window.addEventListener('resize', resizeCanvas);
}
Answer

You could change the content of the meta tag via js (for example, set it to width=123). Now, you've got to have such an element in your page which would certainly change its size because of that ([email protected]:100% maybe?). After that, you restore original value of meta, but already knowing if it means anything for the browser.

If you go this way, the result of the proceduce should be saved to localStorage or cookie, so that you mess with the page only once.

Answer

Try this:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=0.1">
<script>
    var width=$(window).width();
    $('meta[name=viewport]').attr('content','width=device-width, initial-scale=1');
    var newWidth=$(window).width();
    var viewportMetaTagIsUsed=width!=newWidth;
    alert(viewportMetaTagIsUsed?'using meta viewport':'not using meta viewport');
</script>

Or more encapsulated:

	function usesViewport() {
		var meta=$('meta[name=viewport]');
		var content=meta.attr('content');
		if (!meta.length) {
			meta=$('<meta name="viewport" content="width=device-width, initial-scale=1" />').appendTo('head');
			console.log(meta.parent());
		}
		$('meta[name=viewport]').attr('content','width=device-width, initial-scale=1');
		var width1=$(window).width();
		$('meta[name=viewport]').attr('content','width=device-width, initial-scale=0.1');
		var width2=$(window).width();
		if (content) {
			$('meta[name=viewport]').attr('content',content);
		} else {
			meta.remove();
		}
		var result=width1!=width2;
		return result;
	}
	$(function() {
		alert(usesViewport()?'Uses viewport':'Doesn\'t use viewport');
	});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

I don't know why it doesn't work here, probably something to do with the sandboxing of the script, but still, I copied and pasted it in the console on Wikipedia and it works, for example.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.