Is this possible to check with Javascript on page load. I know you can detect a change in orientation but is it possible to check what state the phone is in straight away?
Thanks
You could check the viewport width and height and see which one is larger:
var isLandscapeMode = window.innerWidth > window.innerHeight;
if (isLandscapeMode) {
// fit page to wide orientation here...
}
For a more in-depth discussion of viewport sizes on mobile devices, see
http://www.quirksmode.org/mobile/viewports2.html
(Updated code)
You can do this...
var currOrientation= '';
/************************
* Changes the (obj) element's class, to
* -vrt (vertical)
* -hrz (horizontal)
* depending on its width
*************************/
var orientation = function( obj ){
var w = getWidth(),
h = getHeight();
if( w <= h && currOrientation !== 'vrt' ){
obj.className = 'vrt';
currOrientation = 'vrt';
}
else if( currOrientation !== 'hrz' ) {
obj.className = 'hrz';
currOrientation = 'hrz';
}
}
/************************
* Binding a repeating timer
************************/
var orientationINIT = function() {
var content;
if( (content = document.getElementsByTagName('body')[0]) != undefined ){
orientation( content );
var Orient = setInterval( function() {
orientation( content );
}, 500 ); //each 500ms a call for orientation change
}
}
orientationINIT should be called on page load or DOM complete (or at the bottom of the page )
where getHeight() and getWidth() should be simple functions that return the window's width / height in number form.
Related
I only want to run a script when the viewport width is greater than a set value. I would also like this to check as the browser resizes and disable/enable as required. I've tried to achieve this using matchMedia and rather than checking every pixel, the script only triggers when the viewport is less/greater than a set value.
If I load a narrow viewport (less than 1080px) the JS doesn't trigger - perfect! Enlarging the viewport to have a width greater than 1080px then runs the script - also perfect!
The problem I have is when I scale down from a larger viewport (greater than 1080px) to narrow/small. The script still functions until I refresh the page - I'm hoping someone can help me with that.
As an aside, is it possible to change const mediaQuery = window.matchMedia('(min-width: 1080px)') to include a min-height or a more complex media query if required (not essential for this).
My script:
const mediaQuery = window.matchMedia('(min-width: 1080px)')
function viewportChange(e) {
// Check if the media query is true
if (e.matches) {
$(document).ready(function() {
var num_children = $('.split-loop__left').children().length;
var child_height = $('.split-loop__right').height() / num_children;
var half_way = num_children * child_height / 2;
$(window).scrollTop(half_way);
function crisscross() {
var parent = $(".split-loop");//.first();
var clone = $(parent).clone();
var leftSide = $(clone).find('.split-loop__left');
var rightSide = $(clone).find('.split-loop__right');
if (window.scrollY > half_way ) {
//We are scrolling up
$(window).scrollTop(half_way - child_height);
var firstLeft = $(leftSide).children().first();
var lastRight = $(rightSide).children().last();
lastRight.appendTo(leftSide);
firstLeft.prependTo(rightSide);
} else if (window.scrollY < half_way - child_height) {
var lastLeft = $(leftSide).children().last();
var firstRight = $(rightSide).children().first();
$(window).scrollTop(half_way);
lastLeft.appendTo(rightSide);
firstRight.prependTo(leftSide);
}
$(leftSide).css('bottom', '-' + window.scrollY + 'px');
$(rightSide).css('bottom', '-' + window.scrollY + 'px');
$(parent).replaceWith(clone);
}
$(window).scroll(crisscross);
});
}
}
// Register event listener
mediaQuery.addListener(viewportChange)
// Initial check
viewportChange(mediaQuery)
The page I am working on has a tilt effect, which affects the orientation of the site body. I want to turn this off when the page reaches a mobile viewport; I have looked and tried a few thing but can't seem to get the effect I want. The code below is what i am using. This script runs separate from my main JS code.
window.addEventListener("mousemove",function(e) {
var width = window.innerWidth;
var height = window.innerHeight;
var clientHeight = document.body.clientHeight;
var skew = {};
skew.y = (20 * ((e.x / width) - 0.5));
skew.x = -(20 * ((e.y / height) - 0.5));
document.body.style.webkitTransform = "perspective("+clientHeight+"px) rotateX("+skew.x+"deg) rotateY("+skew.y+"deg)";
});
CSS changes won't remove themselves, so you'll have to remove the transform manually if the browser window is under your desired size.
Check on window resize,
window.addEventListener('resize', function() {
if (window.innerWidth < 568) {
document.body.style.webkitTransform = '';
}
});
And also make sure not to reapply it if the user moves their mouse.
// This is the function you already have
window.addEventListener('mousemove', function(e) {
if (window.innerWidth < 568) {
return;
}
...
}
I'm using a code that scale images to fit the parent div, it's called "aspectcorrect".
The problem happens on the mobile version: my parent div has 100% width, and when the user changes the orientation of the screen to landscape, the image doesn't resize to fit the new div's width.
There is a way to rerun the onload event (which scales the image), when the user changes the orientation of the screen?
Here is my website: www.mcsoftware.com.br/sitemc
I'm still working on it.
(To understand what I'm saying, open it on your cellphone, and when you change the screen orientation just click on "Continuar mesmo assim" to navigate)
Thanks!
aspectcorrect.js
function ScaleImage(srcwidth, srcheight, targetwidth, targetheight, fLetterBox) {
var result = { width: 0, height: 0, fScaleToTargetWidth: true };
if ((srcwidth <= 0) || (srcheight <= 0) || (targetwidth <= 0) || (targetheight <= 0)) {
return result;
}
// scale to the target width
var scaleX1 = targetwidth;
var scaleY1 = (srcheight * targetwidth) / srcwidth;
// scale to the target height
var scaleX2 = (srcwidth * targetheight) / srcheight;
var scaleY2 = targetheight;
// now figure out which one we should use
var fScaleOnWidth = (scaleX2 > targetwidth);
if (fScaleOnWidth) {
fScaleOnWidth = fLetterBox;
}
else {
fScaleOnWidth = !fLetterBox;
}
if (fScaleOnWidth) {
result.width = Math.floor(scaleX1);
result.height = Math.floor(scaleY1);
result.fScaleToTargetWidth = true;
}
else {
result.width = Math.floor(scaleX2);
result.height = Math.floor(scaleY2);
result.fScaleToTargetWidth = false;
}
result.targetleft = Math.floor((targetwidth - result.width) / 2);
result.targettop = Math.floor((targetheight - result.height) / 2);
return result;
}
onimageload.js
function OnImageLoad(evt) {
var img = evt.currentTarget;
// what's the size of this image and it's parent
var w = $(img).width();
var h = $(img).height();
var tw = $(img).parent().width();
var th = $(img).parent().height();
// compute the new size and offsets
var result = ScaleImage(w, h, tw, th, false);
// adjust the image coordinates and size
img.width = result.width;
img.height = result.height;
$(img).css("left", result.targetleft);
$(img).css("top", result.targettop);
}
Where onload function goes
<img onload="OnImageLoad(event);" />
https://jsfiddle.net/ffxeqq21/
You can try some javascript library like jQuery mobile and use the orientationchange event This way you could just do
$( window ).on( "orientationchange", function( event ) {
//Some code
});
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
jQuery - Check if element is visible after scroling
I'm trying to determine if an element is visible on screen. In order to to this, I'm trying to find the element's vertical position using offsetTop, but the value returned is not correct. In this case, the element is not visible unless you scroll down. But despite of this, offsetTop returns a value of 618 when my screen height is 703, so according to offsetTop the element should be visible.
The code I'm using looks like this:
function posY(obj)
{
var curtop = 0;
if( obj.offsetParent )
{
while(1)
{
curtop += obj.offsetTop;
if( !obj.offsetParent )
{
break;
}
obj = obj.offsetParent;
}
} else if( obj.y )
{
curtop += obj.y;
}
return curtop;
}
Thank you in advance!
--- Shameless plug ---
I have added this function to a library I created
vanillajs-browser-helpers: https://github.com/Tokimon/vanillajs-browser-helpers/blob/master/inView.js
-------------------------------
Intersection Observer
In modern browsers you can use the IntersectionObserver which detects where an element is on the screen or compared to a parent.
The Intersection Observer API 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.
Today I would probably lean toward this API if I need to detect and react to when an element has entered or exited the screen.
But for a quick test/lookup when you just want to verify if an emelemt is currently on screen I would go with the version just below using the getBoundingClientRect.
Using getBoundingClientRect
Short version
This is a lot shorter and should do it as well:
function checkVisible(elm) {
var rect = elm.getBoundingClientRect();
var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
return !(rect.bottom < 0 || rect.top - viewHeight >= 0);
}
with a fiddle to prove it: http://jsfiddle.net/t2L274ty/1/
Longer version
And a version with threshold and mode included:
function checkVisible(elm, threshold, mode) {
threshold = threshold || 0;
mode = mode || 'visible';
var rect = elm.getBoundingClientRect();
var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
var above = rect.bottom - threshold < 0;
var below = rect.top - viewHeight + threshold >= 0;
return mode === 'above' ? above : (mode === 'below' ? below : !above && !below);
}
and with a fiddle to prove it: http://jsfiddle.net/t2L274ty/2/
A more traditional way to do it
As BenM stated, you need to detect the height of the viewport + the scroll position to match up with your top position. The function you are using is ok and does the job, though its a bit more complex than it needs to be.
If you don't use jQuery then the script would be something like this:
function posY(elm) {
var test = elm, top = 0;
while(!!test && test.tagName.toLowerCase() !== "body") {
top += test.offsetTop;
test = test.offsetParent;
}
return top;
}
function viewPortHeight() {
var de = document.documentElement;
if(!!window.innerWidth)
{ return window.innerHeight; }
else if( de && !isNaN(de.clientHeight) )
{ return de.clientHeight; }
return 0;
}
function scrollY() {
if( window.pageYOffset ) { return window.pageYOffset; }
return Math.max(document.documentElement.scrollTop, document.body.scrollTop);
}
function checkvisible( elm ) {
var vpH = viewPortHeight(), // Viewport Height
st = scrollY(), // Scroll Top
y = posY(elm);
return (y > (vpH + st));
}
Using jQuery is a lot easier:
function checkVisible( elm, evalType ) {
evalType = evalType || "visible";
var vpH = $(window).height(), // Viewport Height
st = $(window).scrollTop(), // Scroll Top
y = $(elm).offset().top,
elementHeight = $(elm).height();
if (evalType === "visible") return ((y < (vpH + st)) && (y > (st - elementHeight)));
if (evalType === "above") return ((y < (vpH + st)));
}
This even offers a second parameter. With "visible" (or no second parameter) it strictly checks whether an element is on screen. If it is set to "above" it will return true when the element in question is on or above the screen.
See in action: http://jsfiddle.net/RJX5N/2/
I hope this answers your question.
Could you use jQuery, since it's cross-browser compatible?
function isOnScreen(element)
{
var curPos = element.offset();
var curTop = curPos.top;
var screenHeight = $(window).height();
return (curTop > screenHeight) ? false : true;
}
And then call the function using something like:
if(isOnScreen($('#myDivId'))) { /* Code here... */ };
I have aplied jquery lighbox on my image gallery, but due to the variable size of images, the lightbox size is not fixed hence opens up with image's original size, this in turn causes the biga images to go out of screen and display horizontal scroll bar in browser.
Hence I am looking for the way to apply the fix width and height to lightbox so that every image must be displayed with this size in lightbox.
Please help..
Update
i Just tried with the solution Scott (http://geekswithblogs.net/wojan/archive/2009/06/17/jquerylightbox.aspx) has given to me, I did this,
function _resize_container_image_box(intImageWidth,intImageHeight) {
// Get current width and height
//rescale if necessary
if((settings.maxWidth != null && settings.maxHeight != null) && (intImageWidth > settings.maxWidth || intImageHeight > settings.maxHeight)){
var isWider = intImageWidth > intImageHeight;//is the image wide or tall?
var scale = isWider ? settings.maxWidth/intImageWidth : settings.maxHeight/intImageHeight;
intImageWidth = intImageWidth * scale;
intImageHeight = intImageHeight * scale;
}
$('#lightbox-image').height(intImageHeight);
$('#lightbox-image').width(intImageWidth);
var intCurrentWidth = $('#lightbox-container-image-box').width();
var intCurrentHeight = $('#lightbox-container-image-box').height();
// Get the width and height of the selected image plus the padding
var intWidth = (intImageWidth + (settings.containerBorderSize * 2)); // Plus the image´s width and the left and right padding value
var intHeight = (intImageHeight + (settings.containerBorderSize * 2)); // Plus the image´s height and the left and right padding value
// Diferences
var intDiffW = intCurrentWidth - intWidth;
var intDiffH = intCurrentHeight - intHeight;
// Perfomance the effect
$('#lightbox-container-image-box').animate({ width: intWidth, height: intHeight },settings.containerResizeSpeed,function() { _show_image(); });
if ( ( intDiffW == 0 ) && ( intDiffH == 0 ) ) {
if ( $.browser.msie ) {
___pause(250);
} else {
___pause(100);
}
}
$('#lightbox-container-image-data-box').css({ width: intImageWidth });
$('#lightbox-nav-btnPrev,#lightbox-nav-btnNext').css({ height: intImageHeight + (settings.containerBorderSize * 2) });
};
AND
$('#gallery a').lightBox( maxHeight: null,
maxWidth: null);
});
But whenever I do this and click on the image just gets open in browsers annother tab, all the lightbox functinalty fails
Please help me to correct it
Thanks
I modified the jquery.lightbox-0.5.js file by Leandro Vieira Pinho. What this modified javascript file does is, it will check each image and if the width or height exceeds the screen (viewport area), then the image is resized while preserving the aspect ratio.
To use this file, you just have to copy and paste entire contents of this javascript file in your already existing jquery.lightbox-0.5.js file or you just have to replace the old file with this.
I have given 2 links: First one will let you down load the entire javascript file and the second will display the source code which you can copy and paste into your existing jquery.lightbox-0.5.js.
Download javascript file: http://turboupload.com/081zwttawcb6
Source code : http://www.sourcepod.com/twhbtf88-5047
You need to specify the maxHeight and maxWidth against all calls of the lightbox().
Example:
$('#gallery a').lightBox({
maxHeight: 700,
maxWidth: 700
});
You lightbox call is missing a {.
Change your lightbox call to as follows:
$('#gallery a').lightBox( {maxHeight: null,
maxWidth: null
});
Sunimal Kaluarachchi's code works well but doesn't handle a landscape aspect ratio properly.
To work properly you need to change
if ( newViewPortWidth > viewPortHeight ) // if viewport width > viewport height
to
if ( newImageWidth > newViewPortWidth ) //
in his function ___calculateImageDimension function
here is the complete function
function ___calculateImageDimension(viewPortWidth, viewPortHeight, imageWidth, imageHeight)
{
// obtain 82% of ViewPort Height
var viewPortHeightPercent = viewPortHeight * (82/100);
var newImageHeight = imageHeight;
var newImageWidth = imageWidth;
var newViewPortWidth = viewPortWidth;
var scaleHeight =0;
var scaleWidth = 0;
// if ( newViewPortWidth > viewPortHeight ) // if viewport width > viewport height
if ( newImageWidth > newViewPortWidth ) // if viewport width > viewport height
{
// Get 80% of current viewport width so the image width will be displayed within this 80% of viewport width size
newViewPortWidth = viewPortWidth * (80/100);
}
// image width check
if ( newImageWidth > newViewPortWidth )
{
newImageWidth = newViewPortWidth;
scaleWidth = imageHeight/imageWidth;
newImageHeight = scaleWidth * newImageWidth;
}
// image height check
if ( newImageHeight > viewPortHeightPercent )
{
newImageHeight = viewPortHeightPercent;
//calculate scale to set width
scaleHeight = imageWidth/imageHeight;
newImageWidth = scaleHeight * newImageHeight;
}
arrayNewImageSize = new Array(newImageWidth,newImageHeight);
return arrayNewImageSize;
}
Your function should replace the one in the jquery.lightbox.js plugin file (look for the function that starts with function _resize_container_image_box somewhere around line 196).
What you need to do next is call lightBox()in your external JS file or inside html like #cocacola09 and #Chandu suggested:
$('#gallery a').lightBox( {maxHeight: null,
maxWidth: null
});
What i did in addition is to get the width and height of a window dynamically, so it fits the current window size:
$(function() {
//get height and width of window
var windowWidth = $(window).width();
var windowHeight = $(window).height();
//windowsize - 50px
var windowHeightFixed = windowHeight - 50;
var windowWidthFixed = windowWidth - 50;
$('a.lightbox').lightBox({
maxHeight: windowHeightFixed,
maxWidth: windowWidthFixed
});
});
But this method gives some buggy results. The problem occurs when you reload the page in a different window size. Some images preserve the width/height of previous window size, but some don't. Tested in Firefox 18, Chrome 24.