automatically detect web browser window width change? - javascript

i know that you with $(window).width() can get the size of the web browser.
i want to detect when the user change the size of his web browser so i could readjust the columns width. is there a way to automatically detect this or do i have to use setTimeinterval to loop and see if it has changed?

Try the resize event
$(window).resize(function() {
console.log('window was resized');
});

Writing this down cause somehow none of these answers give the modern best-practices way of doing this:
window.addEventListener("resize", function(event) {
console.log(document.body.clientWidth + ' wide by ' + document.body.clientHeight+' high');
})

The JavaScript event is named window.onresize.
The JQuery binding is named .resize()

In MDN they give a really good Javascript standalone code:
window.onresize = resize;
function resize()
{
alert("resize event detected!");
}
If you need just this kind of functionality I would recommend to go for it.

You might want to use debounce :
https://davidwalsh.name/javascript-debounce-function
Otherwise the
window.addEventListener("resize")
Will fire the whole time as the window resize is in progress.
Which will tax your CPU overhead.

Something to keep in mind- in IE, at least, resize events bubble, and positioned elements and the document body can fire independent resize events.
Also, IE fires a continuous stream of 'resize' events when the window or element is resized by dragging. The other browsers wait for the mouseup to fire.
IE is a big enough player that it is useful to have an intermediate handler that fields resize events- even if you branch only IE clients to it.
The ie handler sets a short timeout(100-200 msec)before calling the 'real' resize handler. If the same function is called again before the timeout, it is either a bubblng event or the window is being dragged to a new size, so clear the timeout and set it again.

Here's a little piece of code I put together for the same thing.
(function () {
var width = window.innerWidth;
window.addEventListener('resize', function () {
if (window.innerWidth !== width) {
window.location.reload(true);
}
});
})();

I use
media="only screen and (min-width: 750px)" href="... css file for wide windows"
media="only screen and (max-width: 751px)" href="...css file for mobiles"
When I move the right windows border left and right to increase and decrease my window size, my web browser will automatically switch from the wide window to the mobile. I do not have to include any Javascript code to detect window width. This works for Chrome, Firefox and Internet Explorer on both Windows and Macintosh computers.

Related

detect a change of screen resolution, and execute a code or another in javascript

I have this doubt, I have a menu in which I run a javascript code or another depending on whether its width is greater or less than its height, works me well the first time the screen resolution is detected, but if there is a change of resolution or a change of orientation does not detect it, and despite for example of having changed to portrait orientation still executing the landscape orientation code. Is there any way to solve this? regards
You could use an eventlistener and listen on the resize event.
window.addEventListener('resize', () => {
// function body
});
But I think this is rather a styling issue and you should consider to use a different approach.
Here is an extention of #mstruebing 's answer :
function resisePageMobile(){
if (window.innerWidth <= 696) { //Detect mobile
aside.classList.remove('pc-stuff');
aside.classList.add('mobile-stuff');
}else{ //Detect other higher resolution screens
aside.classList.remove('mobile-stuff');
aside.classList.add('pc-stuff');
}
}
resisePageMobile();//run once on page load
//then attach to the event listener
window.addEventListener('resize',resisePageMobile);
Running this function once at the start of the page is important because the resize event will not trigger until the window is getting resized so we must initialize page at the start !

$(window).resize() executes when scrolling on mobile devices

For example:
HTML
<div><p>A lot of text that goes off the page so you have to scroll down.........</p></div>
JavaScript
$(window).resize(function(){
$("div").append("<p>appended</p>");
});
This works and appends the paragraph as expected on resize, but it is also appended when I scroll down. This means when I get to the end of the original text there is about 20 appended paragraphs.
This is only happening on mobile devices (so far I've checked Chrome, Safari and Firefox), not on desktop browsers.
Is there a way to stop this happening and have the paragraph appended only when the window (that you see) is resized?
Or maybe only have the code within the resize execute every so often?
Thanks.
The problem with mobile devices is that they have the browser toolbars that are hidden when you scroll and this leads to screen change (activates the resize event) and this means that you have to make some validations to your code and detect why was the resize event fired.
One way I have used is by saving the window width and checking if the correct window width is the same or changed. If it changes then it means that the append should happen (in your case).
var dwidth = $(window).width();
$(window).resize(function(){
var wwidth = $(window).width();
if(dwidth!==wwidth){
dwidth = $(window).width();
console.log('Width changed');
}
});

How to actively seek and receive the browser window's width?

The JQuery code:
if ($(window).width() < 1000) {
alert("width is less than 1000");
}
Only returns the window width value when the page is loaded. If the user's window started out being greater than 1000 and the shrunk the window width so that it was lower than 1000, the above code would not run. How do I get a constant check for the width of the window to account for this scenario.
You listen to window resize event (as well as the load event):
$(window).on("load resize", function() {
console.log($(this).width());
});
Note that the resize event fires constantly while the user is dragging the window. If you add complex logic in the event handler you might experience sluggish performance. It would be nice to wrap your code inside a debounce function... a function that fires few milliseconds after the user is finished resizing the window.

Call jquery function only when window width gets resized

I have a function responsive that changes behaviour of certain elements on my website, including hiding popups etc. I call it in 2 cases:
$(document).ready(responsive);
$(window).resize(responsive);
The problem occurs on android chrome, as the virtual keyboard actually changes the height of the screen, and triggers responsive function, which closes my popups (some of them have text fields, making it impossible to type).
How can I prevent this from happening? I read somewhere a good point that android virtual keyboard only changes height of the screen, not a width, so I assume it would be a good idea to compare width before and after resize. So I created this function to compare the widths before and after and run resize() if width is different, but it doesn't work as expected, and console logs show different document widths even though I only changed the height of the screen (using chrome developer tools).
Any idea what went wrong or how can I prevent function responsive being launched on height change?
function resizeWidth() {
var existingWidth = $(document).width();
$(window).resize(function() {
var newWidth = $(document).width();
if (existingWidth != newWidth) {
$(window).resize(responsive);
console.log(existingWidth);
console.log(newWidth);
};
});
};
$(window).resize(resizeWidth);
Firstly you are attaching a handler to the resize event multiple times. One on load, then another every time the resize happens and resizeWidth is called. You should remove the handler within that function. Also, I guess you just want to call the responsive() function, not attach yet another resize handler when the width changes.
The main issue you have is that the scope of existingWidth is not low enough for it to be seen over multiple events. You could make it global, although that is generally considered bad practice. Instead you could use a data attribute, like this:
function resizeWidth() {
var existingWidth = $(document).data('resize-width');
var newWidth = $(document).width();
if (existingWidth != newWidth) {
responsive();
$(document).data('resize-width', newWidth);
};
};
$(window).resize(resizeWidth);

iPad Web App: Detect Virtual Keyboard Using JavaScript in Safari?

I'm writing a web app for the iPad (not a regular App Store app - it's written using HTML, CSS and JavaScript). Since the keyboard fills up a huge part of the screen, it would make sense to change the app's layout to fit the remaining space when the keyboard is shown. However, I have found no way to detect when or whether the keyboard is shown.
My first idea was to assume that the keyboard is visible when a text field has focus. However, when an external keyboard is attached to an iPad, the virtual keyboard does not show up when a text field receives focus.
In my experiments, the keyboard also did not affect the height or scrollheight of any of the DOM elements, and I have found no proprietary events or properties which indicate whether the keyboard is visible.
I found a solution which works, although it is a bit ugly. It also won't work in every situation, but it works for me. Since I'm adapting the size of the user interface to the iPad's window size, the user is normally unable to scroll. In other words, if I set the window's scrollTop, it will remain at 0.
If, on the other hand, the keyboard is shown, scrolling suddenly works. So I can set scrollTop, immediately test its value, and then reset it. Here's how that might look in code, using jQuery:
$(document).ready(function(){
$('input').bind('focus',function() {
$(window).scrollTop(10);
var keyboard_shown = $(window).scrollTop() > 0;
$(window).scrollTop(0);
$('#test').append(keyboard_shown?'keyboard ':'nokeyboard ');
});
});
Normally, you would expect this to not be visible to the user. Unfortunately, at least when running in the Simulator, the iPad visibly (though quickly) scrolls up and down again. Still, it works, at least in some specific situations.
I've tested this on an iPad, and it seems to work fine.
You can use the focusout event to detect keyboard dismissal. It's like blur, but bubbles. It will fire when the keyboard closes (but also in other cases, of course). In Safari and Chrome the event can only be registered with addEventListener, not with legacy methods. Here is an example I used to restore a Phonegap app after keyboard dismissal.
document.addEventListener('focusout', function(e) {window.scrollTo(0, 0)});
Without this snippet, the app container stayed in the up-scrolled position until page refresh.
If there is an on-screen keyboard, focusing a text field that is near the bottom of the viewport will cause Safari to scroll the text field into view. There might be some way to exploit this phenomenon to detect the presence of the keyboard (having a tiny text field at the bottom of the page which gains focus momentarily, or something like that).
maybe a slightly better solution is to bind (with jQuery in my case) the "blur" event on the various input fields.
This because when the keyboard disappear all form fields are blurred.
So for my situation this snipped solved the problem.
$('input, textarea').bind('blur', function(e) {
// Keyboard disappeared
window.scrollTo(0, 1);
});
hope it helps.
Michele
Edit: Documented by Apple although I couldn't actually get it to work: WKWebView Behavior with Keyboard Displays: "In iOS 10, WKWebView objects match Safari’s native behavior by updating their window.innerHeight property when the keyboard is shown, and do not call resize events" (perhaps can use focus or focus plus delay to detect keyboard instead of using resize).
Edit: code presumes onscreen keyboard, not external keyboard. Leaving it because info may be useful to others that only care about onscreen keyboards. Use http://jsbin.com/AbimiQup/4 to view page params.
We test to see if the document.activeElement is an element which shows the keyboard (input type=text, textarea, etc).
The following code fudges things for our purposes (although not generally correct).
function getViewport() {
if (window.visualViewport && /Android/.test(navigator.userAgent)) {
// https://developers.google.com/web/updates/2017/09/visual-viewport-api Note on desktop Chrome the viewport subtracts scrollbar widths so is not same as window.innerWidth/innerHeight
return {
left: visualViewport.pageLeft,
top: visualViewport.pageTop,
width: visualViewport.width,
height: visualViewport.height
};
}
var viewport = {
left: window.pageXOffset, // http://www.quirksmode.org/mobile/tableViewport.html
top: window.pageYOffset,
width: window.innerWidth || documentElement.clientWidth,
height: window.innerHeight || documentElement.clientHeight
};
if (/iPod|iPhone|iPad/.test(navigator.platform) && isInput(document.activeElement)) { // iOS *lies* about viewport size when keyboard is visible. See http://stackoverflow.com/questions/2593139/ipad-web-app-detect-virtual-keyboard-using-javascript-in-safari Input focus/blur can indicate, also scrollTop:
return {
left: viewport.left,
top: viewport.top,
width: viewport.width,
height: viewport.height * (viewport.height > viewport.width ? 0.66 : 0.45) // Fudge factor to allow for keyboard on iPad
};
}
return viewport;
}
function isInput(el) {
var tagName = el && el.tagName && el.tagName.toLowerCase();
return (tagName == 'input' && el.type != 'button' && el.type != 'radio' && el.type != 'checkbox') || (tagName == 'textarea');
};
The above code is only approximate: It is wrong for split keyboard, undocked keyboard, physical keyboard. As per comment at top, you may be able to do a better job than the given code on Safari (since iOS8?) or WKWebView (since iOS10) using window.innerHeight property.
I have found failures under other circumstances: e.g. give focus to input then go to home screen then come back to page; iPad shouldnt make viewport smaller; old IE browsers won't work, Opera didnt work because Opera kept focus on element after keyboard closed.
However the tagged answer (changing scrolltop to measure height) has nasty UI side effects if viewport zoomable (or force-zoom enabled in preferences). I don't use the other suggested solution (changing scrolltop) because on iOS, when viewport is zoomable and scrolling to focused input, there are buggy interactions between scrolling & zoom & focus (that can leave a just focused input outside of viewport - not visible).
During the focus event you can scroll past the document height and magically the window.innerHeight is reduced by the height of the virtual keyboard. Note that the size of the virtual keyboard is different for landscape vs. portrait orientations so you'll need to redetect it when it changes. I would advise against remembering these values as the user could connect/disconnect a bluetooth keyboard at any time.
var element = document.getElementById("element"); // the input field
var focused = false;
var virtualKeyboardHeight = function () {
var sx = document.body.scrollLeft, sy = document.body.scrollTop;
var naturalHeight = window.innerHeight;
window.scrollTo(sx, document.body.scrollHeight);
var keyboardHeight = naturalHeight - window.innerHeight;
window.scrollTo(sx, sy);
return keyboardHeight;
};
element.onfocus = function () {
focused = true;
setTimeout(function() {
element.value = "keyboardHeight = " + virtualKeyboardHeight()
}, 1); // to allow for orientation scrolling
};
window.onresize = function () {
if (focused) {
element.value = "keyboardHeight = " + virtualKeyboardHeight();
}
};
element.onblur = function () {
focused = false;
};
Note that when the user is using a bluetooth keyboard, the keyboardHeight is 44 which is the height of the [previous][next] toolbar.
There is a tiny bit of flicker when you do this detection, but it doesn't seem possible to avoid it.
The visual viewport API is made for reacting to virtual keyboard changes and viewport visibility.
The Visual Viewport API provides an explicit mechanism for querying and modifying the properties of the window's visual viewport. The visual viewport is the visual portion of a screen excluding on-screen keyboards, areas outside of a pinch-zoom area, or any other on-screen artifact that doesn't scale with the dimensions of a page.
function viewportHandler() {
var viewport = event.target;
console.log('viewport.height', viewport.height)
}
window.visualViewport.addEventListener('scroll', viewportHandler);
window.visualViewport.addEventListener('resize', viewportHandler);
Only tested on Android 4.1.1:
blur event is not a reliable event to test keyboard up and down because the user as the option to explicitly hide the keyboard which does not trigger a blur event on the field that caused the keyboard to show.
resize event however works like a charm if the keyboard comes up or down for any reason.
coffee:
$(window).bind "resize", (event) -> alert "resize"
fires on anytime the keyboard is shown or hidden for any reason.
Note however on in the case of an android browser (rather than app) there is a retractable url bar which does not fire resize when it is retracted yet does change the available window size.
Instead of detecting the keyboard, try to detect the size of the window
If the height of the window was reduced, and the width is still the same, it means that the keyboard is on.
Else the keyboard is off, you can also add to that, test if any input field is on focus or not.
Try this code for example.
var last_h = $(window).height(); // store the intial height.
var last_w = $(window).width(); // store the intial width.
var keyboard_is_on = false;
$(window).resize(function () {
if ($("input").is(":focus")) {
keyboard_is_on =
((last_w == $(window).width()) && (last_h > $(window).height()));
}
});
Try this one:
var lastfoucsin;
$('.txtclassname').click(function(e)
{
lastfoucsin=$(this);
//the virtual keyboard appears automatically
//Do your stuff;
});
//to check ipad virtual keyboard appearance.
//First check last focus class and close the virtual keyboard.In second click it closes the wrapper & lable
$(".wrapperclass").click(function(e)
{
if(lastfoucsin.hasClass('txtclassname'))
{
lastfoucsin=$(this);//to avoid error
return;
}
//Do your stuff
$(this).css('display','none');
});`enter code here`
The idea is to add fixed div to bottom.
When virtual keyboard is shown/hidden scroll event occurs.
Plus, we find out keyboard height
const keyboardAnchor = document.createElement('div')
keyboardAnchor.style.position = 'fixed'
keyboardAnchor.style.bottom = 0
keyboardAnchor.style.height = '1px'
document.body.append(keyboardAnchor)
window.addEventListener('scroll', ev => {
console.log('keyboard height', window.innerHeight - keyboardAnchor.getBoundingClientRect().bottom)
}, true)
This solution remembers the scroll position
var currentscroll = 0;
$('input').bind('focus',function() {
currentscroll = $(window).scrollTop();
});
$('input').bind('blur',function() {
if(currentscroll != $(window).scrollTop()){
$(window).scrollTop(currentscroll);
}
});
The problem is that, even in 2014, devices handle screen resize events, as well as scroll events, inconsistently while the soft keyboard is open.
I've found that, even if you're using a bluetooth keyboard, iOS in particular triggers some strange layout bugs; so instead of detecting a soft keyboard, I've just had to target devices that are very narrow and have touchscreens.
I use media queries (or window.matchMedia) for width detection and Modernizr for touch event detection.
As noted in the previous answers somewhere the window.innerHeight variable gets updated properly now on iOS10 when the keyboard appears and since I don't need the support for earlier versions I came up with the following hack that might be a bit easier then the discussed "solutions".
//keep track of the "expected" height
var windowExpectedSize = window.innerHeight;
//update expected height on orientation change
window.addEventListener('orientationchange', function(){
//in case the virtual keyboard is open we close it first by removing focus from the input elements to get the proper "expected" size
if (window.innerHeight != windowExpectedSize){
$("input").blur();
$("div[contentEditable]").blur(); //you might need to add more editables here or you can focus something else and blur it to be sure
setTimeout(function(){
windowExpectedSize = window.innerHeight;
},100);
}else{
windowExpectedSize = window.innerHeight;
}
});
//and update the "expected" height on screen resize - funny thing is that this is still not triggered on iOS when the keyboard appears
window.addEventListener('resize', function(){
$("input").blur(); //as before you can add more blurs here or focus-blur something
windowExpectedSize = window.innerHeight;
});
then you can use:
if (window.innerHeight != windowExpectedSize){ ... }
to check if the keyboard is visible. I've been using it for a while now in my web app and it works well, but (as all of the other solutions) you might find a situation where it fails because the "expected" size is not updated properly or something.
Perhaps it's easier to have a checkbox in your app's settings where the user can toggle 'external keyboard attached?'.
In small print, explain to the user that external keyboards are currently not detectable in today's browsers.
I did some searching, and I couldn't find anything concrete for a "on keyboard shown" or "on keyboard dismissed". See the official list of supported events. Also see Technical Note TN2262 for iPad. As you probably already know, there is a body event onorientationchange you can wire up to detect landscape/portrait.
Similarly, but a wild guess... have you tried detecting resize? Viewport changes may trigger that event indirectly from the keyboard being shown / hidden.
window.addEventListener('resize', function() { alert(window.innerHeight); });
Which would simply alert the new height on any resize event....
I haven't attempted this myself, so its just an idea... but have you tried using media queries with CSS to see when the height of the window changes and then change the design for that? I would imagine that Safari mobile isn't recognizing the keyboard as part of the window so that would hopefully work.
Example:
#media all and (height: 200px){
#content {height: 100px; overflow: hidden;}
}
Well, you can detect when your input boxes have the focus, and you know the height of the keyboard. There is also CSS available to get the orientation of the screen, so I think you can hack it.
You would want to handle the case of a physical keyboard somehow, though.

Categories

Resources