has anyone noticed that on the last version of Desktop Firefox, it is recognized as a touch device?
I am using the script below:
function isTouch() {
try{ document.createEvent("TouchEvent"); return true; }
catch(e){ return false;
}
}
if (isTouch()) {
alert('I am touch device!')
}
The script has given me flawless results up until the latest version of Desktop Firefox. Is it a bug? Am I missing something?
Thanks everyone for your time!
edit: False alarm people. I have no idea what went wrong, I tried resetting preferences, disabled all extensions but had no luck.
I finally solved the issue by REFRESHING firefox (lost all my extensions though and had to reinstall).
Thanks for everybody's efforts and sorry for any inconvenience caused.
You are just checking if you can create a specific type of event, not really if you are currently on a touch device.
Here is a more complete isTouchDevice function, which I wrote some time ago based on the core of Modernizr.
/**
* Detect if the current device is a touch device.
* Inspired by Modernizr and hardcore streamlined.
*/
function isTouchDevice() {
var bool;
if( ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch ) {
bool = true;
}
else {
var fakeBody = document.createElement( 'fakebody' );
fakeBody.innerHTML += '<style>#media (touch-enabled),(-webkit-touch-enabled),(-moz-touch-enabled),(-o-touch-enabled){#touchtest{top:42px;position:absolute}}</style>';
document.documentElement.appendChild( fakeBody );
var touchTestNode = document.createElement( 'div' );
touchTestNode.id = 'touchtest';
fakeBody.appendChild( touchTestNode );
bool = touchTestNode.offsetTop === 42;
}
return bool;
}
I've had a similar problem, and maybe some people will benefit from the information.
In my case, the Touch events were always detected as positive by Modernizr in Firefox desktop, even if they weren't fired.
In the end, I realized that 'dom.w3c_touch_events.enabled' had a value of '1' even if I didn't set it myself.
It was actually switched on by the "Touch" button in Responsive Design View, but never switched back to '0' even after disabling the Touch events with the very same button.
So I've reported a bug to Mozilla : https://bugzilla.mozilla.org/show_bug.cgi?id=1188270
You will find a test case there.
Basically, the only solution I had to go back to normal is to change manually the value of 'dom.w3c_touch_events.enabled' to '0' in 'about:config'.
And I'm now aware that by enabling Touch events in the Responsive Design View, I will have to manually switch it back after.
Hope this can help some people !
Related
I am trying to get the absolute device orientation across different mobile devices (android + IOs) and browsers
in a more or less reliable way. I would rather be able to understand if the orientation I am receiving is relative and not show the compass instead of showing wrong values.
I have been googling back and forth for days and I haven't found a definitive answer yet (I am
a javascript and web dev novice).
I see that the Full-Tilt library should be doing exactly
that but it has a non commercial license. I intend to use this result in a potentially commercial project, moreover, I would like to understand what's happening.
Nowadays most deviceorientation events are returning relative values.
deviceorientationabsolute is not supported by firefox and it's an experimental feature, I can fallback on it when other things fail but it cannot be the main solution.
So far I've got to this line of reasoning (pseudocode):
if(mobile)
if(webkitmobilecompassheading)
window.addEventListener("deviceorientation", handleOrientationWebkit, true);
else if(deviceorientationabsolute)
window.addEventListener("deviceorientation", handleOrientationAbsolute, true);
else
"bad luck"
I have no idea where to look to understand how many devices I would miss out on with the following reasoning, and if there is a better way.
For Android it works auto, for iOS it needs to be clicked to start it.
Here's a part of code you can use for that
startBtn.addEventListener("click", startCompass);
function startCompass() {
if (isIOS) {
DeviceOrientationEvent.requestPermission()
.then((response) => {
if (response === "granted") {
window.addEventListener("deviceorientation", handler, true);
} else {
alert("has to be allowed!");
}
})
.catch(() => alert("not supported"));
} else {
window.addEventListener("deviceorientationabsolute", handler, true);
}
}
function handler(e) {
const degree = e.webkitCompassHeading || Math.abs(e.alpha - 360);
}
Full tutorial is here, try demo also
https://dev.to/orkhanjafarovr/real-compass-on-mobile-browsers-with-javascript-3emi
I'm trying to create a script which will run when any browser console is opened or closed. Is there any way to detect if the browser console in all browsers (Firefox/IE/Chrome/Safari/Opera) is open or not via JavaScript, jQuery, or any other client-side script?
If you are willing to accept an interference for the user,
you could use the debugger statement, as it is available in all major browsers.
Side note: If the users of your app are interested in console usage, they're probably familiar with dev tools, and will not be surprised by it showing up.
In short, the statement is acting as a breakpoint, and will affect the UI only if the browser's development tools is on.
Here's an example test:
<body>
<p>Devtools is <span id='test'>off</span></p>
<script>
var minimalUserResponseInMiliseconds = 100;
var before = new Date().getTime();
debugger;
var after = new Date().getTime();
if (after - before > minimalUserResponseInMiliseconds) { // user had to resume the script manually via opened dev tools
document.getElementById('test').innerHTML = 'on';
}
</script>
</body>
devtools-detect should do the job. Try the simple demo page.
devtools-detect → detect whether DevTools is open, and its orientation.
Supported Browsers:
DevTools in Chrome, Safari, Firefox & Opera
Caveats:
Doesn't work if DevTools is undocked (separate window), and may show a false positive if you toggle any kind of sidebar.
I don't think it is directly possible in JS for security reasons.But in here
they are claiming that it is possible and is useful for when you want something special to happen when DevTools is open. Like pausing canvas, adding style debug info, etc.
But As #James Hill tell in this, I also thinks even if a browser chose to make this information accessible to the client, it would not be a standard implementation (supported across multiple browsers).
Also can also try this one also here.
It's not possible in any official cross browser way, but if the occasional false positive is acceptable, you can check for a window.onresize event. Users resizing their windows after loading a page is somewhat uncommon. It's even more effective if you expect users will be frequently opening the console, meaning less false positives as a percentage.
window.onresize = function(){
if ((window.outerHeight - window.innerHeight) > 100) {
// console was opened (or screen was resized)
}
}
Credit to https://stackoverflow.com/a/7809413/3774582. Although that question is chrome specific, the concept applies here.
To expand on this, if you need a very low tolerance on false positives, most window resizes will trigger this event dozens of times because it is usually done as a drag action, while opening the console will only trigger this once. If you can detect this, the approach will become even more accurate.
Note: This will fail to detect if the console is already open when the user visits the page, or if the user opens the console in a new window.
(function() {
'use strict';
const el = new Image();
let consoleIsOpen = false;
let consoleOpened = false;
Object.defineProperty(el, 'id', {
get: () => {
consoleIsOpen = true;
}
});
const verify = () => {
console.dir(el);
if (consoleIsOpen === false && consoleOpened === true) {
// console closed
window.dispatchEvent(new Event('devtools-opened'));
consoleOpened = false;
} else if (consoleIsOpen === true && consoleOpened === false) {
// console opened
window.dispatchEvent(new Event('devtools-closed'));
consoleOpened = true;
}
consoleIsOpen = false;
setTimeout(verify, 1000);
}
verify();
})();
window.addEventListener('devtools-opened', ()=>{console.log('opened')});
window.addEventListener('devtools-closed', ()=>{console.log('closed')});
Here is a code that worked for me.
This solution works like a charm
https://github.com/sindresorhus/devtools-detect
if you are not using modules - disable lines
// if (typeof module !== 'undefined' && module.exports) {
// module.exports = devtools;
// } else {
window.devtools = devtools;
// }
and result is then here
window.devtools.isOpen
I for my project use the blur event.
function yourFunction() {}
window.addEventListener('blur',(e)=>{e.preventDefault(); yourFunction()})
This will execute yourFunction when the window loses focus.
For instance when someone opens the DevTools.
Okay seems like it also fires when you try to access a different window... so maybe not the best solution.
Maybe pair it with looking at the width of the browser.
If it chainged you can be pretty sure about it I think
I am using a "shake" function from github - and it has a detection that is browser-based javascript.
//feature detect
this.hasDeviceMotion = 'ondevicemotion' in window;
This though yields true even on Chrome on OS X.
It feels strange, since I am not willing to shake my monitor on my desktop.
Safari on OS X gives me "false" in return when testing.
I have searched but not been able to find out why Chrome decided to take this path. It bugs me.
Is there a better way to make this detection? Not all "mobile devices" has shake as well.. or does not let the browser have that capability, as it does not seem to work in windows phones.
not really sure about your question and as well, I am just digging into its functionality, however you could use something like
X : <span id="varx"></span>
Y : <span id="vary"></span>
Z : <span id="varz"></span>
<script>
window.ondevicemotion = function(event){
var accelerationX = event.accelerationIncludingGravity.x;
var accelerationY = event.accelerationIncludingGravity.y;
var accelerationZ = event.accelerationIncludingGravity.z;
document.getElementById("varx").innerHTML = accelerationX;
document.getElementById("vary").innerHTML = accelerationY;
document.getElementById("varz").innerHTML = accelerationZ;
};
</script>
it will show this value only if the event have the accelerationIncludingGravity property, this is only available in mobile, not 100% this is what you want, you could also trigger an event asking for if(accelerationX){//execute action}else{//execute planB} hope this help, if it doesn't I'll be happy to learn and get some feedback.
Have anybody out there found a simple way of detecting whether the browser supports the transitionend event or not in vanillaJs, especially in a way that actually works in all major browsers? :(
I have found this unanswered thread in here: Test for transitionend event support in Firefox, and quite a lot of almost working hacks.
Right now I am bulk adding eventlisteners to all the vendor prefixes, and it kind of works out (even though I think it is a hideous approach that hurts my eyes every time I look at it). But IE8 and IE9 does not support it at all, so I need to detect those two, and treat them separately.
I would prefer to do this without browser sniffing, and definitely without huge libraries/frameworks like jQuery
I have made a jsfiddler snippet that illustrates my problem. There is a button that spawns a dialog. When the dialog is removed by clicking close, it is transitioned in top and opacity, and after ended transition it is supposed to display=none. But if the transitionend is never fired (like in IE8 and IE9), the dialog is never removed, making it cover the show dialog button, destroying the UX. If I could detect when transitionend is not working, I could just set the display=none when closing for those browsers.
http://jsfiddle.net/QJwzF/22/
window.listenersSet = false;
window.dialogShouldBeVisible = false;
window.showMyDialog = function () {
var myDialog = document.getElementById('dialog'),
myClose = document.getElementById('close');
if (!listenersSet) {
if (!window.addEventListener) { // IE8 has no addEventListener
myclose.attachEvent('onclick', function () {
hideMyDialog();
});
} else {
myClose.addEventListener('click', function () {
hideMyDialog()
});
['webkitTransitionEnd','oTransitionEnd', 'otransitionend', 'transitionend'].forEach(function (eventName) {
myDialog.addEventListener(eventName, function (e) {
if (e.target === myDialog && e.propertyName === 'top') { // only do trigger if it is the top transition of the modalDialog that has ended
if (!dialogShouldBeVisible) {
myDialog.style.display = 'none';
e.stopPropagation();
}
}
});
});
}
listenersSet = true;
}
myDialog.style.display = 'block';
myDialog.style.top = '15px';
myDialog.style.opacity = '1';
dialogShouldBeVisible = true;
}
window.hideMyDialog = function () {
var myDialog = document.getElementById('dialog'),
myClose = document.getElementById('close');
myDialog.style.top = '-5%';
myDialog.style.opacity = '0.1';
dialogShouldBeVisible = false;
}
It is working in Opera, Firefox, Chrome and IE10, but not in IE8 and IE9 (afaik)
If I did a bad job explaining my problem, please let me know, and I will try do a better job! :)
Copied from bootstrap transition, it not only returns true if browser supports transition but also returns proper name of event
function transitionEnd() {
var el = document.createElement('div')//what the hack is bootstrap
var transEndEventNames = {
WebkitTransition : 'webkitTransitionEnd',
MozTransition : 'transitionend',
OTransition : 'oTransitionEnd otransitionend',
transition : 'transitionend'
}
for (var name in transEndEventNames) {
if (el.style[name] !== undefined) {
return transEndEventNames[name];
}
}
return false // explicit for ie8 ( ._.)
}
Hope this helps.
EIDT:
I modified a little bit default bootstrap function so it doesn't return object but string.
I would definitely use this small script available on Github.
It's listed among Modernizr "Cross-browser polyfills" page so it can be trusted but Modernizr itself is not required.
The examples in the Github page of the script are written using jQuery (and I can't understand why) but jQuery is also not required as it's written in vanilla js.
Like so you'll have a useful whichTransitionEnd method available. I can't test it right now being on my laptop without IE8/IE9 available but I guess that this method will return false (or anything falsy) in those browsers.
var transition = transitionEnd(box).whichTransitionEnd();
// return for example "webkitTransitionEnd"
It will then be quite easy to target those browsers where transitions (and thus transitionend events) are not supported. Hope this will be a nudge in the right direction.
EDIT
After tweaking with the above code the OP came up with a much shorter version of the original script. It saves a good deal of bytes and only detects support for this event, and, in case it's supported returns the name of the event itself.
You can find it here as a gist and read more about it in the comments to this answer.
A client recently asked me to implement a slideshow on our website. I'm concerned that constantly animating picture transitions on the homepage will peg the processor of most mobile devices, so I want to disable the automatic advancing to preserve battery life. Is there any way to do this without trying to detect the user agent?
I've seen that there is a battery status API drafted here, but I don't know how complete it is, or which browsers have implemented it.
Actually determining battery would be quite difficult and probably involve various permissions problems.
Try just executing a small piece of code and checking the time it took. Pick a cutoff and if the code executes too slowly, turn off the transitions/animation/autoadvance. This will catch more than just battery devices; anything too slow will get the un-animated version. Degrade gracefully.
Now you can, with this API: http://davidwalsh.name/javascript-battery-api
navigator.getBattery().then(function(result) {});
Another old topic, but still relevant - I now check if the device has motion sensors, not many laptops do, but all modern smart phones and tablets do - so laptop users can live with slightly more battery use -
jQuery:
if (window.DeviceOrientationEvent) {
$(window).one("devicemotion", function(event) {
if (event.originalEvent.acceleration
&& event.originalEvent.acceleration.x !== null) { // Chrome fakes it on desktop
isMobile = true;
}
});
}
Plain Javascript:
if (window.DeviceOrientationEvent) {
window.ondevicemotion = function(event) {
if (event.acceleration
&& event.acceleration.x !== null) { // Chrome fakes it on desktop
window.ondevicemotion = null;
isMobile = true;
}
};
}