My website - https://wilfredopersonal.herokuapp.com/# - shows some specific content for mobile view. The problem is that this content is also shown in Desktop while the Desktop content is loading. How can I prevent it from doing so?
<script>
function isMobile() {
if (navigator.userAgent.match(/Mobi/)) {
return true;
}
if ("screen" in window && window.screen.width < 1366) {
return true;
}
var connection =
navigator.connection ||
navigator.mozConnection ||
navigator.webkitConnection;
if (connection && connection.type === "cellular") {
return true;
}
return false;
}
</script>
<script>
if (!isMobile()) {
document.getElementById("not-desktop").style.display = "none";
document.getElementById("container").style.display = "unset";
} else {
document.getElementById("not-desktop").style.display = "unset";
document.getElementById("container").style.display = "none";
}
</script>
Because your script is executed after HTML loaded. So before the browser read to your script, the mobile keep visible.
I recommend you to use CSS media query to solve this rather then using script. Here is a good answer demonstrate how to use media query to target desktop and mobile. This answer could solve your problem.
Another way is set #not-desktop's display to none in your CSS. Then when the script executed, if it is shows on mobile, your code will show it. But this method is not flexible.
This is an issue where you are displaying both your mobile view and your desktop view at the same time, then disabling which ever "view" is incorrect. Since your javascript is loaded after the page is created, it will display both views until the javascript loads and disables one.
You can fix this by making both of them "disabled" from the start - add the style attribute like this: style="display:none" to "not-desktop" and "container". That way both of them will be disabled until the javascript can enable one.
EDIT: after looking at Li Jinyao's answer, I see that there is a much faster way to do this - use a CSS media tag to check the width of the element, and only display it if it matches the requirements. Afterwards, use java script to check the userAgent and anything else, and change the displayed element accordingly.
To see information about CSS media tags, look at Li Jinyao's answer.
A couple of days i found an issue that my jquery wasn't responding on ios devices. Now i found what the problem was. It was a perfect working code. Now i thought i will not include this on mobile so i used this code
This is the code:
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) === false ) {
var muziek = getCookie("Muziek");
// Save progression when leaving window
window.onbeforeunload = () => {
var prog = $('#muziek audio')[0].currentTime;
console.log("current time = ", prog);
sessionStorage.setItem('audioProgression', prog);
};
}
I test this on the google element inspector on the different sizes and it worked. But on my ipad it still doesn't, is there a way i can use this code to run and not block the jquery on my ios device? I do not need the music in the ios devices or other mobile/tablet devices. But i still need it on my computer browser. Does anybody know a way i can solve this?
Kind regards
Dylan
I am using the following javascript to detect whether the site is viewed on a mobile device it works perfectly as a redirect (see example 1);
However, is it possible to amend it to so it amends the font size of an element or class (the original font-size is contained within an external style sheet) when the same condition is satisfied, that being a iDevice is detected.
//original code: (Javascript)
// iDevice
var iDevice = {
// Android
Android: function() {
return navigator.userAgent.match(/Android/i);
},
// Blackberry
BlackBerry: function() {
return navigator.userAgent.match(/BlackBerry/i);
},
// Apple
iOS: function() {
return navigator.userAgent.match(/iPhone|iPad|iPod/i);
},
// Opera Browser
Opera: function() {
return navigator.userAgent.match(/Opera Mini/i);
},
// Windows Mobile
Windows: function() {
return navigator.userAgent.match(/IEMobile/i);
},
// Function: (iDevice)
any: function(){
return (iDevice.Android() || iDevice.BlackBerry() || iDevice.iOS() || iDevice.Opera() || iDevice.Windows());
}
};
<!-- Working HTML -->
{
if( iDevice.any() )
window.location = "http://www.stackoverflow.com";
}
One possible solution would be to modify the JavaScript so that it adds one or more custom classes to the 'body' element in your HTML based on the device agent. Then, in your CSS, you could do something like this:
.header {
/* default font size */
}
.android .header,
.iphone .header
.mobile .header {
/* custom font size */
}
However, a better solution might be to forgo user agent detection and instead use media queries to make your website responsive based on the actual width of the device the user is using to view your website.
Your code will not work on any device that you haven't explicitly enumerated. For example, why don't you support Firefox OS?
Of course you can try to enumerate every single mobile device ever produced (and keep doing that to keep your code working for new devices) and change the font size for the detected mobile devices (that you know about) but it would be much better to use responsive web design for things like that.
You can use a framework like:
Bootstrap
Foundation
or many others, or to use CSS media queries yourself if you don't want to use those frameworks.
See: Media Queries for Standard Devices on CSS-Tricks.
I have a web site containing millions of photos from thousands of events over the last 26 years, and the directory structure is \root\events\(year)\(eventdate) so that all the photos and files for any given event date are kept together. Each directory has its own index.shtml file which sorts out the organisation of the content.
I want to add a mobile version of the site. My current thinking is to add a mobile.shtml page to each directory, and switch based on a simple screen width test. All the pages throughout the site use a common header include, so I need to add code to a common header, but which will only switch if the current page is the index.shtml file. I´ve used the following, and it fails to switch.
This is what I´ve added to the include file
......
<body>
<script>
var url = location.href;
var filename = url.substring(url.lastIndexOf('/')+1);
var a = "index.shtml";
if((screen.width < 600) && (filename.equals(a))) {
location.href = 'mobile.shtml';
}
</script>
.........
I´m not a JS programmer and am trying to implement code seen hereabouts, so would appreciate learning why this fails! Thanks in advance to anyone that replies.
I have not used this for a while but I am pretty sure it still works. Place this in the Head of your HTML e.g. desktop website - index.html
<!-- Detect and redirect for mobile -->
<script type="text/javascript">
if(navigator.userAgent.match(/iP(od|hone)/i) || navigator.userAgent.match(/Android/i)){
if(document.cookie.indexOf("iphone_redirect=false")==-1) {
window.location.href="http://myWebsite.com/index_mobile.html";
}
}
</script>
Be sure to add your correct redirect here in this line from above:
window.location.href="http://myWebsite.com/index_mobile.html";
As a second solution to support your original intentions, I managed to get a variation of your JS code working live here DEMO. My DEMO will take you to GitHub if you view it from a screen with a width < or = to 600px. To test it properly you must view it from monitor sizes above and below 600px widths. Below is my variation of your JS code:
<body>
<script>
var url = window.location.href;
var filename = url.substring(url.lastIndexOf('/')+1);
var a = 'index.shtml';
if((screen.width <= 600) && (filename == a)) {
window.location.href = 'https://github.com/';
}
</script>
* NOTE the difference that my code will redirect you to GitHub as opposed to 'mobile.shtml'
What you are trying to accomplish should be done with responsive design techniques. In a perfect world, you could just use media queries
to adjust the css applied to format the content differently.
But I have also had the need sometimes to do server side detection of the client, because I would render an entirely different widget based on the form factor. You seem to be using .shtml, which is a poor choice IMHO. Your webserver at a min must support php, and that is a way more powerful server side choice for your app. PhpMobileDetect is a great script that will give you a way to detect if it is mobile, tablet, or desk. Problem now is that we have enormous phones, or phablets. But it might just be the right fit for your task.
In Javascript/jQuery, how can I detect if the client device has a mouse?
I've got a site that slides up a little info panel when the user hovers their mouse over an item. I'm using jQuery.hoverIntent to detect the hover, but this obviously doesn't work on touchscreen devices like iPhone/iPad/Android. So on those devices I'd like to revert to tap to show the info panel.
var isTouchDevice = 'ontouchstart' in document.documentElement;
Note: Just because a device supports touch events doesn't necessarily mean that it is exclusively a touch screen device. Many devices (such as my Asus Zenbook) support both click and touch events, even when they doen't have any actual touch input mechanisms. When designing for touch support, always include click event support and never assume any device is exclusively one or the other.
Found testing for window.Touch didn't work on android but this does:
function is_touch_device() {
return !!('ontouchstart' in window);
}
See article: What's the best way to detect a 'touch screen' device using JavaScript?
+1 for doing hover and click both. One other way could be using CSS media queries and using some styles only for smaller screens / mobile devices, which are the ones most likely to have touch / tap functionality. So if you have some specific styles via CSS, and from jQuery you check those elements for the mobile device style properties you could hook into them to write you mobile specific code.
See here: http://www.forabeautifulweb.com/blog/about/hardboiled_css3_media_queries/
if ("ontouchstart" in window || navigator.msMaxTouchPoints) {
isTouch = true;
} else {
isTouch = false;
}
Works every where !!
return (('ontouchstart' in window)
|| (navigator.maxTouchPoints > 0)
|| (navigator.msMaxTouchPoints > 0));
Reason for using maxTouchPoints alongwith msMaxTouchPoints:
Microsoft has stated that starting with Internet Explorer 11,
Microsoft vendor prefixed version of this property (msMaxTouchPoints)
may be removed and recommends using maxTouchPoints instead.
Source : http://ctrlq.org/code/19616-detect-touch-screen-javascript
I use:
if(jQuery.support.touch){
alert('Touch enabled');
}
in jQuery mobile 1.0.1
Google Chrome seems to return false positives on this one:
var isTouch = 'ontouchstart' in document.documentElement;
I suppose it has something to do with its ability to "emulate touch events" (F12 -> settings at lower right corner -> "overrides" tab -> last checkbox). I know it's turned off by default but that's what I connect the change in results with (the "in" method used to work in Chrome).
However, this seems to be working, as far as I have tested:
var isTouch = !!("undefined" != typeof document.documentElement.ontouchstart);
All browsers I've run that code on state the typeof is "object" but I feel more certain knowing that it's whatever but undefined :-)
Tested on IE7, IE8, IE9, IE10, Chrome 23.0.1271.64, Chrome for iPad 21.0.1180.80 and iPad Safari. It would be cool if someone made some more tests and shared the results.
Wrote this for one of my sites and probably is the most foolproof solution. Especially since even Modernizr can get false positives on touch detection.
If you're using jQuery
$(window).one({
mouseover : function(){
Modernizr.touch = false; // Add this line if you have Modernizr
$('html').removeClass('touch').addClass('mouse');
}
});
or just pure JS...
window.onmouseover = function(){
window.onmouseover = null;
document.getElementsByTagName("html")[0].className += " mouse";
}
For my first post/comment:
We all know that 'touchstart' is triggered before click.
We also know that when user open your page he or she will:
1) move the mouse
2) click
3) touch the screen (for scrolling, or ... :) )
Let's try something :
//--> Start: jQuery
var hasTouchCapabilities = 'ontouchstart' in window && (navigator.maxTouchPoints || navigator.msMaxTouchPoints);
var isTouchDevice = hasTouchCapabilities ? 'maybe':'nope';
//attach a once called event handler to window
$(window).one('touchstart mousemove click',function(e){
if ( isTouchDevice === 'maybe' && e.type === 'touchstart' )
isTouchDevice = 'yes';
});
//<-- End: jQuery
Have a nice day!
I have tested following code mentioned above in the discussion
function is_touch_device() {
return !!('ontouchstart' in window);
}
works on android Mozilla, chrome, Opera, android default browser and safari on iphone...
all positive ...
seems solid for me :)
A helpful blog post on the subject, linked to from within the Modernizr source for detecting touch events. Conclusion: it's not possible to reliably detect touchscreen devices from Javascript.
http://www.stucox.com/blog/you-cant-detect-a-touchscreen/
This works for me:
function isTouchDevice(){
return true == ("ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch);
}
If you use Modernizr, it is very easy to use Modernizr.touch as mentioned earlier.
However, I prefer using a combination of Modernizr.touch and user agent testing, just to be safe.
var deviceAgent = navigator.userAgent.toLowerCase();
var isTouchDevice = Modernizr.touch ||
(deviceAgent.match(/(iphone|ipod|ipad)/) ||
deviceAgent.match(/(android)/) ||
deviceAgent.match(/(iemobile)/) ||
deviceAgent.match(/iphone/i) ||
deviceAgent.match(/ipad/i) ||
deviceAgent.match(/ipod/i) ||
deviceAgent.match(/blackberry/i) ||
deviceAgent.match(/bada/i));
if (isTouchDevice) {
//Do something touchy
} else {
//Can't touch this
}
If you don't use Modernizr, you can simply replace the Modernizr.touch function above with ('ontouchstart' in document.documentElement)
Also note that testing the user agent iemobile will give you broader range of detected Microsoft mobile devices than Windows Phone.
Also see this SO question
In jQuery Mobile you can simply do:
$.support.touch
Don't know why this is so undocumented.. but it is crossbrowser safe (latest 2 versions of current browsers).
As already mentioned, a device may support both mouse and touch input. Very often, the question is not "what is supported" but "what is currently used".
For this case, you can simply register mouse events (including the hover listener) and touch events alike.
element.addEventListener('touchstart',onTouchStartCallback,false);
element.addEventListener('onmousedown',onMouseDownCallback,false);
...
JavaScript should automatically call the correct listener based on user input. So, in case of a touch event, onTouchStartCallback will be fired, emulating your hover code.
Note that a touch may fire both kinds of listeners, touch and mouse. However, the touch listener goes first and can prevent subsequent mouse listeners from firing by calling event.preventDefault().
function onTouchStartCallback(ev) {
// Call preventDefault() to prevent any further handling
ev.preventDefault();
your code...
}
Further reading here.
For iPad development I am using:
if (window.Touch)
{
alert("touchy touchy");
}
else
{
alert("no touchy touchy");
}
I can then selectively bind to the touch based events (eg ontouchstart) or mouse based events (eg onmousedown). I haven't yet tested on android.