How does this page detect movement of a desktop browser window? - javascript

In messing around with some DeviceOrientation stuff, I came across this page.
When you shake the browser, the site reacts! What API is being used here where the browser movement is detected? I notice it works in the latest versions of Safari, Firefox and Chrome.
I don't see any mention of this in the DeviceOrientation docs, nor on three.js...

They use the window.screenX/screenY properties to get browser window position and window.innerWidth/innerHeight to get window's size.
The Window.screenX read-only property returns the horizontal distance, in CSS pixels, of the left border of the user's browser viewport to the left side of the screen.
The below function is used in that code:
function getBrowserDimensions() {
var changed = false;
if (stage[0] != window.screenX) {
delta[0] = (window.screenX - stage[0]) * 50;
stage[0] = window.screenX;
changed = true;
}
if (stage[1] != window.screenY) {
delta[1] = (window.screenY - stage[1]) * 50;
stage[1] = window.screenY;
changed = true;
}
if (stage[2] != window.innerWidth) {
stage[2] = window.innerWidth;
changed = true;
}
if (stage[3] != window.innerHeight) {
stage[3] = window.innerHeight;
changed = true;
}
return changed;
}

use screen.orientation property.
reference

Related

Detecting a system window overlaying an iframe

After looking at this youtube video I was curious how some of the features shown, can be implemented with JS.
One of my major questions is how can one detect another system window (like the word window, shown in the video) on the iframe.
On another video there is a hint suggesting that the technic is based on the fact that browsers optimize rendering for elements that are out of the view.
I couldn't tap into what are the exact methods/properties that are used.
What are your thoughts?
What I know it's possible to detect if page is in foreground or in background - or more precisely: if has focus or has not focus.
var focus = true;
window.onblur = function() { focus = false; action(); }
window.onfocus = function() { focus = true; action(); }
document.onblur = window.onblur;
document.focus = window.focus;
function action(){
if(focus) {
document.body.style.background = "green";
} else {
document.body.style.background = "lightgray";
}
}
try click inside and then outside
The above code snippet uses event listeners onblur and onfocus for events focus and blur.
 
 
Better can be to use Visibility API:
it works when switching tabs (page can detect that user has opened another tab)
Note: While onblur and onfocus will tell you if the user switches windows, it doesn't necessarily mean it's hidden. Pages only become hidden when the user switches tabs or minimizes the browser window containing the tab.
see Detect if browser tab is active or user has switched away
http://jsbin.com/lowocepazo/edit?js,output
For scrolling there is an Intersection Observer
provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document's viewport
//EDIT:
Nowdays is not possible to detect such cases like for example in 1st video you posted (in 2:09) when another window is obscured some element:
 
If I'm wrong, please correct me.
related:
How can I tell when the browser stops repainting DOM layers/nodes because they are obscured?
https://www.html5rocks.com/en/tutorials/speed/animated-gifs/
You have to check document.hasFocus and position/size of windows and screen monitor.
Maybe like this :
You can try my demo here : https://jsfiddle.net/p9ahuo3t/
let bool = document.hasFocus();
$("p.info").text("in");
console.log(outerWidth + screenX)
if (screen.width < outerWidth + screenX) {
bool = false;
$("p.info").text("right side: out");
} else if ((outerWidth - innerWidth) + screenX < 0) {
bool = false;
$("p.info").text("left side: out");
} else if (screen.height < outerHeight + screenY) {
bool = false;
$("p.info").text("bottom side: out");
} else if ((outerHeight - innerHeight) + screenY < 0) {
bool = false;
$("p.info").text("top side: out");
}
if (currentChild && !currentChild.closed) {
let rectPage = {
left: (outerWidth - innerWidth) + screenX,
top: (outerHeight - innerHeight) + screenY,
right: outerWidth + screenX,
bottom: outerHeight + screenY
};
let rectPopup = {
left: currentChild.screenX,
top: currentChild.screenY,
right: currentChild.outerWidth + currentChild.screenX,
bottom: currentChild.outerHeight + currentChild.screenY
};
if (intersectRect(rectPage, rectPopup)) {
$("p.info").text("eclipse with popup");
bool = false;
}
}
$page.text(pin(bool));
Also :
You can compare the time (+new Date()) between two setInterval to detect inactive browser. Chrome and Firefox throttle setTimeout/setInterval in inactive tabs.

Hide address bar not working - bulletproof approach needed

At the moment I am writing some kind of web app and I want to hide the address bar on iOS devices and preferably also on Android devices.
Normally I do this with
window.addEventListener( 'load', function () {
setTimeout( function () {
window.scrollTo( 0, 1 );
}, 0 );
});
but this won't work now because the page hasn't enough content to scroll.
Now I know this is a common problem and I know that there are multiple solutions, but I would prefer a small, bulletproof solution.
Actually I was quite happy when I found this question: http://stackoverflow.com/questions/9678194/cross-platform-method-for-removing-the-address-bar-in-a-mobile-web-app
where this code was posted:
function hideAddressBar()
{
if(!window.location.hash)
{
if(document.height < window.outerHeight)
{
document.body.style.height = (window.outerHeight + 50) + 'px';
}
setTimeout( function(){ window.scrollTo(0, 1); }, 50 );
}
}
window.addEventListener("load", function(){ if(!window.pageYOffset){ hideAddressBar(); } } );
window.addEventListener("orientationchange", hideAddressBar );
Unfortunately, this doesn't work for me. I see that something happens because some elements that have padding-top set in percentages move down, but the address bar stays.
Of course I also did a Google search and tried many snippets I found. Some did nothing, some just moved the elements with padding-top down a bit.
The only working code I found is this:
var page = document.getElementById('page'),
ua = navigator.userAgent,
iphone = ~ua.indexOf('iPhone') || ~ua.indexOf('iPod'),
ipad = ~ua.indexOf('iPad'),
ios = iphone || ipad,
// Detect if this is running as a fullscreen app from the homescreen
fullscreen = window.navigator.standalone,
android = ~ua.indexOf('Android'),
lastWidth = 0;
if (android) {
// Android's browser adds the scroll position to the innerHeight, just to
// make this really difficult. Thus, once we are scrolled, the
// page height value needs to be corrected in case the page is loaded
// when already scrolled down. The pageYOffset is of no use, since it always
// returns 0 while the address bar is displayed.
window.onscroll = function() {
page.style.height = window.innerHeight + 'px'
}
}
var setupScroll = window.onload = function() {
// Start out by adding the height of the location bar to the width, so that
// we can scroll past it
if (ios) {
// iOS reliably returns the innerWindow size for documentElement.clientHeight
// but window.innerHeight is sometimes the wrong value after rotating
// the orientation
var height = document.documentElement.clientHeight;
// Only add extra padding to the height on iphone / ipod, since the ipad
// browser doesn't scroll off the location bar.
if (iphone && !fullscreen) height += 60;
page.style.height = height + 'px';
} else if (android) {
// The stock Android browser has a location bar height of 56 pixels, but
// this very likely could be broken in other Android browsers.
page.style.height = (window.innerHeight + 56) + 'px'
}
// Scroll after a timeout, since iOS will scroll to the top of the page
// after it fires the onload event
setTimeout(scrollTo, 0, 0, 1);
};
(window.onresize = function() {
var pageWidth = page.offsetWidth;
// Android doesn't support orientation change, so check for when the width
// changes to figure out when the orientation changes
if (lastWidth == pageWidth) return;
lastWidth = pageWidth;
setupScroll();
})();
Source
But I am not really happy with this solution as I am not a friend of UA sniffing.
Do you have any suggestions what I could try to make it work without UA sniffing? Can it be my HTML that causes problems with some scripts I posted?
Don't know if it's bulletproof, but it works on a bunch of devices. If you find caveat, let me know.
if (((/iphone/gi).test(navigator.userAgent) || (/ipod/gi).test(navigator.userAgent)) &&
(!("standalone" in window.navigator) && !window.navigator.standalone)) {
offset = 60;
$('body').css('min-height', (window.innerHeight + offset) + 'px');
setTimeout( function(){ window.scrollTo(0, 1); }, 1 );
}
if ((/android/gi).test(navigator.userAgent)) {
offset = 56;
$('html').css('min-height', (window.innerHeight + offset) + 'px');
setTimeout( function(){ window.scrollTo(0, 1); }, 0 );
}

Browser detection using javascript failing on refresh

I'm trying to detect for devices that do not have support for position:fixed. EDIT: I've fixed the code so it's detecting features rather than browser/OS detection.
I think I was confusing people when I first typed this out. My issue is coming into play when I refresh the page. The height is being incorrectly calculated, which is a completely different issue I know, but am looking for assistance nonetheless.
Updated detection script below:
function fixed() {
var container = document.body;
if (document.createElement && container && container.appendChild && container.removeChild) {
var el = document.createElement('div');
if (!el.getBoundingClientRect) return null;
el.innerHTML = 'x';
el.style.cssText = 'position:fixed;top:100px;';
container.appendChild(el);
var originalHeight = container.style.height,
originalScrollTop = container.scrollTop;
container.style.height = '3000px';
container.scrollTop = 500;
var elementTop = el.getBoundingClientRect().top;
container.style.height = originalHeight;
var isSupported = (elementTop === 100);
container.removeChild(el);
container.scrollTop = originalScrollTop;
return isSupported;
}
return null;
}
//TEST FOR MOBILE, SET TOP IMAGE TO RELATIVE
if(fixed()) {
image_height = jQuery("#outer_homepage_image").height() - 45;
jQuery("#content").css("top",image_height);
jQuery(window).resize(function() {
image_height = jQuery("#outer_homepage_image").height() - 45;
alert(image_height);
jQuery("#content").css("top",image_height);
});
} else {
jQuery("#outer_homepage_image").css("position","relative");
}
This is an extremely brittle and ill-conceived thing to be doing.
if(/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)) {
For example, iOS has fully supported position:fixed properly since iOS 4. We're now on 6. For Android & Blackberry, I'm not sure but would err on the side of "supported".
You need to test for features, not user agent. As I said, you could have one iOS device that doesn't support it and another one that does. Indeed, most do these days.
Here's a helpful link to lead you to moral, godly choices: http://kangax.github.com/cft/#IS_POSITION_FIXED_SUPPORTED
Thanks for all the support guys. I solved it with jQuery(window).load(function() {
it works now because everything else is loaded so I can calculate the proper height.

Resizing an image using Javascript running in Opera Browser

I hope someone can help with this quirky issue I am having with the Opera Browser, I have version 11 Beta installed, but I suspect is a common problem in Opera.
The website and page in question is http://www.amigaos.net/index.html.
At the bottom of the body of the html I have the following code which resizes the 3 images you see on this webpage depending on width of the viewport at page load. In Safari and FireFox the code works fine, but in Opera the following lines which involve resizing the width and height of an image do not work:
document.getElementById('img1').width = '475';
document.getElementById('img1').height = '375';
Here is the code in full (sorry, about the layout, stackoverflow hasn't formatted carriage returns correctly)
<script type="text/javascript">
function GetWidth()
{
var x = 0;
if (typeof window.innerWidth != 'undefined')
{
x = window.innerWidth;
}
else if (document.documentElement && document.documentElement.clientHeight)
{
x = document.documentElement.clientWidth;
}
else if (document.body)
{
x = document.getElementsByTagName('body')[0].clientWidth;
}
return x;
}
width = GetWidth();
if (width>=1680)
{
document.getElementById('img1').width = '475';
document.getElementById('img1').height = '375';
document.getElementById('img2').width = '475';
document.getElementById('img2').height = '375';
document.getElementById('img3').width = '475';
document.getElementById('img3').height = '375';
}
else if ((width>800) && (width<=1280))
{
document.getElementById('img1').width = '300';
document.getElementById('img1').height = '235';
document.getElementById('img2').width = '300';
document.getElementById('img2').height = '235';
document.getElementById('img3').width = '300';
document.getElementById('img3').height = '235';
}
else if (width<=800)
{
document.getElementById('img1').width = '225';
document.getElementById('img1').height = '195';
document.getElementById('img2').width = '225';
document.getElementById('img2').height = '195';
document.getElementById('img3').width = '225';
document.getElementById('img3').height = '195';
}
</script>
instead of doing width and height attributes, I think you can just set width: 33% via CSS and have the scaling happen automatically, regardless of the browser window size. Better solution than trying to use javascript, IMHO.
Here's a simple tutorial: http://haslayout.net/css-tuts/CSS-Proportional-Image-Scale
you are making this way too complicated. I don't think your issue is browser-specific, you just need to recode your script.
First. I would recommmend using percentages.. Not sure how you will guess the visitors browser width in pixels.
Let's say that your three resizeable images are 20% width of your browser. So your css would be:
#img1, #img2, #img3 {
width: 20%;
}
now that your css says that your images are 20% of the total with, you're good to add some js. Keep in mind that the percentage will be that of its outer container.
<script type=text/javascript">
function resizeImages() {
document.getElementById('img1').style.height = (document.body.clientHeight - 100) * 0.2;
document.getElementById('img2').style.height = (document.body.clientHeight - 100) * 0.2;
document.getElementById('img3').style.height = (document.body.clientHeight - 100) * 0.2;
}
</script>
and most importantly.. call your function:
add this to your body tag:
<body onresize="resizeImages()">
boom.. you're done.

What is different with window and div widths between firefox and IE

I have a web page that uses a scrolling div to display table information. When the window is resized (and also on page load), the display is centered and the div's scrollbar positioned to the right of the page by setting its width. For some reason, the behaviour is different under firefox than IE. IE positions/sizes the div as expected, but firefox seems to make it too wide, such that the scrollbar begins to disappear when the window client width reaches about 800px. I'm using the following methods to set the position and size:
function getWindowWidth() {
var windowWidth = 0;
if (typeof(window.innerWidth) == 'number') {
windowWidth=window.innerWidth;
}
else {
if (document.documentElement && document.documentElement.clientWidth) {
windowWidth=document.documentElement.clientWidth ;
}
else {
if (document.body && document.body.clientWidth) {
windowWidth=document.body.clientWidth;
}
}
}
return windowWidth;
}
function findLPos(obj) {
var curleft = 0;
if (obj.offsetParent) {
curleft = obj.offsetLeft
while (obj = obj.offsetParent) {
curleft += obj.offsetLeft
}
}
return curleft;
}
var bdydiv;
var coldiv;
document.body.style.overflow="hidden";
window.onload=resizeDivs;
window.onresize=resizeDivs;
function resizeDivs(){
bdydiv=document.getElementById('bdydiv');
coldiv=document.getElementById('coldiv');
var winWdth=getWindowWidth();
var rghtMarg = 0;
var colHdrTbl=document.getElementById('colHdrTbl');
rghtMarg = parseInt((winWdth - 766) / 2) - 8;
rghtMarg = (rghtMarg > 0 ? rghtMarg : 0);
coldiv.style.paddingLeft = rghtMarg + "px";
bdydiv.style.paddingLeft = rghtMarg + "px";
var bdydivLft=findLPos(bdydiv);
if ((winWdth - bdydivLft) >= 1){
bdydiv.style.width = winWdth - bdydivLft;
coldiv.style.width = bdydiv.style.width;
}
syncScroll();
}
function syncScroll(){
if(coldiv.scrollLeft>=0){
coldiv.scrollLeft=bdydiv.scrollLeft;
}
}
Note that I've cut out other code which sets height, and other non-relevant parts. The full page can be seen here. If you go to the link in both IE and firefox, resize width until "800" is displayed in the green box top-right, and resize height until the scrollbar at the right is enabled, you can see the problem. If you then resize the IE width, the scrollbar stays, but if you resize the firefox width wider, the scrollbar begins to disappear. I'm at a loss as to why this is happening....
Note that AFAIK, getWindowWidth() should be cross-browser-compatible, but I'm not so sure about findLPos().... perhaps there's an extra object in Firefox's DOM or something, which is changing the result??
You are dealing with "one of the best-known software bugs in a popular implementation of Cascading Style Sheets (CSS)" according to Wikipedia. I recommend the Element dimensions and CSS Object Model View pages on Quirksmode.org.
Also: I think you'll find that Safari and Opera behave like Firefox in most circumstances. A more compatible approach to working around these problems is testing for, and making exceptions for, MSIE instead of the other way around.
Ok, I found the problem. Seems to be that firefox does not include the style.paddingLeft value in its style.width setting, whereas IE does, thus the div was ending up exactly style.paddingLeft too wide. That is, if for example style.paddingLeft is 8, IE's style.width value would be 8 more than FireFox's - and thus the inverse when setting the value, for FireFox I needed to subtract the style.paddingLeft value
Modified code with:
if (__isFireFox){
bdydiv.style.width = winWdth - bdydivLft - rghtMarg;
} else {
bdydiv.style.width = winWdth - bdydivLft;
}
As long as you don't include a valid doctype, you can't expect consistent results, due to Quirks Mode. Go add one (HTML 4.01 Transitional is fine), then let us know if it still occurs.
Also see http://en.wikipedia.org/wiki/Quirks_mode.
In your getWindowWidth() function, whenever you grab the width of something, instead of this:
windowWidth = document.documentElement.clientWidth;
try this
windowWidth = Math.max(document.documentElement.scrollWidth, document.documentElement.clientWidth);
A detail to help optimize some of your code:
function getPos(elm) {//jumper
for(var zx=zy=0;elm!=null;zx+=elm.offsetLeft,zy+=elm.offsetTop,elm=elm.offsetParent);
return {x:zx,y:zy}
}
(jumper is a user who posted this code in Eksperten.dk)

Categories

Resources