36

There's a lot of discussion about the soft keyboard but I haven't found a good solution for my problem yet.

I have a resize function like:

$(window).resize(function() {
    ///do stuff
});

I want to do the 'stuff' in that function on all resize events except for when it is triggered by the soft keyboard. How can I determine if the soft keyboard has triggered the resize?

Jose Calderon
  • 551
  • 2
  • 5
  • 11
  • 1
    Do all mobile soft keyboards trigger resize events? It looks to me that they act like 'overlays' and do not resize the browser window.. – Robin van Baalen Feb 15 '13 at 19:57
  • 1
    They are like overlays if you don't resize your content. But they trigger the window.resize event. – Jose Calderon Feb 15 '13 at 20:01
  • is there a way to check whether a soft keyboard is being displayed? – Derek Feb 15 '13 at 20:47
  • if not, does the resize event trigger for anything else in a mobile environment? how about when the user zooms in/out using pinch gesture? if not... then you shouldn't need to check at all. – Derek Feb 15 '13 at 20:50

8 Answers8

22

I recently ran into some problems that needed a check for this. I managed to solve it like so:

$(window).on('resize', function(){
   // If the current active element is a text input, we can assume the soft keyboard is visible.
   if($(document.activeElement).attr('type') === 'text') {
      // Logic for while keyboard is shown
   } else {
      // Logic for while keyboard is hidden
   }
});

I only needed it for text inputs, but obviously this could be expanded for any kind of element which might trigger the soft keyboard/number picker etc.

Black
  • 18,150
  • 39
  • 158
  • 271
kirisu_kun
  • 329
  • 1
  • 2
  • 10
  • 4
    This will only work if you have explicitly set the attribute to "text" in your html code. Better to use prop() instead of attr(). – CpnCrunch Sep 24 '15 at 18:47
  • 1
    also if I close the keyboard by bottom back button in android it will have still activeElement as type=text (or last focused input) and still resize event triggered due to hiding of keyboard. this solution is good but not complete and full proof. – Talk is Cheap Show me Code May 06 '19 at 11:57
11

I've just fixed kirisu_kun's answer to use prop() instead of attr():

$(window).on('resize', function(){
   // If the current active element is a text input, we can assume the soft keyboard is visible.
   if($(document.activeElement).prop('type') === 'text') {
      // Logic for while keyboard is shown
   } else {
      // Logic for while keyboard is hidden
   }
});
Black
  • 18,150
  • 39
  • 158
  • 271
CpnCrunch
  • 4,831
  • 1
  • 33
  • 31
6

The problem is that, if the active element is focused, you can trigger the resize event just by closing the keyboard without altering the focus.. so, the keyboard will hidden but the code will enter into the condition of focus.

mobiledeckyou
  • 61
  • 1
  • 1
5

This question relies on there being a reliable way to detect when the onscreen keyboard appears (or disappears) on mobile devices. Unfortunately, there is no reliable way to detect this. Similar questions have come up several times on SO, with various hacks, tricks and workarounds suggested (see this answer for links to several relevant answer threads).

Also note that the resize event is not always triggered when the onscreen keyboard appears (see this answer).

My general suggestion would be to detect presence of touchscreen + detection of whether the active element is of a type that triggers an onscreen keyboard (something similar to this answer). However, this approach would still fail for hybrid windows devices (such as Surface Pro), where sometimes the onscreen keyboard may be present on browser resize, and sometimes the hardware keyboard may be in use on browser resize.

Community
  • 1
  • 1
Tomas Langkaas
  • 4,551
  • 2
  • 19
  • 34
  • I seem to have come to the same conclusion unfortunately. I moved on to trying to cancel the default zoom event but that was [just as fruitless](https://bugs.chromium.org/p/chromium/issues/detail?id=181560#c28). – lpd Nov 30 '16 at 14:21
  • @lpd, I have tried to wrap my head around this issue, but can not seem to find any solution that will cover all use cases as long as there is no specific event triggered by change in onscreen keyboard visibility. This means that we are left with hacks and workarounds that may work in some, but not all, use cases. – Tomas Langkaas Nov 30 '16 at 14:26
3

Similar to previous answer, but targets all kinds of forms with focus (obviously, would fail on inputs without a form parent)

$(window).resize(function() {
    if($('form *').focus()) {
        alert('ignore this');
    } else {
        // do the thing
    }
});

So maybe this one...

$(window).resize(function() {
    if($('input, select, etc').focus()) {
        alert('ignore this');
    } else {
        // do the thing
    }
});
Black
  • 18,150
  • 39
  • 158
  • 271
Dawson
  • 7,567
  • 1
  • 26
  • 25
3

I've been looking for a solution to a similar issue. My resize event was triggering when the url input came in and out of view. This is something I've been working on... Could have a possible solution?

So basically you just check if the width of the screen alone has changed or not, and only fire your functions on the resize if it is different:

eg:

var saveWindowWidth = true;
    var savedWindowWidth;

//set the initial window width
    if (saveWindowWidth = true){
        savedWindowWidth = windowWidth;
        saveWindowWidth = false;
    }


//then on resize...


$(window).resize(function() {

//if the screen has resized then the window width variable will update
        windowWidth = window.innerWidth;


//if the saved window width is still equal to the current window width do nothing
        if (savedWindowWidth == windowWidth){
            return;
        }


//if saved window width not equal to the current window width do something
        if(savedWindowWidth != windowWidth) {
           // do something

            savedWindowWidth = windowWidth;
        }

    });
Gee_63
  • 76
  • 1
  • 8
3

There are a few things u need to concentrate about

  1. All soft keyboards affects only the height and not width.
  2. Focus elements tags can be either input or textarea.
  3. The height will decrease when element get focused (or) the height will increase when focused out.

You can use these combinations when the browser gets resized

function getWidth(){
return $( window ).width();
}

function getHeight(){
return $( window ).height();
}

function isFocus(){
return $(document.activeElement).prop('tagName')=='INPUT' || $(document.activeElement).prop('tagName')=='TEXTAREA';
}

var focused = false;
var windowWidth=getWidth(),windowHeight=getHeight();

//then on resize...    
$(window).resize(function() {

var tWidth=getWidth(),tHeight=getHeight(),tfocused=isFocus();

//if the saved window width is still equal to the current window width do nothing
if (windowWidth == tWidth && ((tHeight < windowHeight && !focused && tfocused) || (tHeight > windowHeight && focused && !tfocused))){
 windowWidth=tWidth;
 windowHeight=tHeight;
 focused=tfocused;
 return;
}
else{
 windowWidth=tWidth;
 windowHeight=tHeight;
 focused=tfocused;

 //Your Code Here

}
});
jafarbtech
  • 6,842
  • 1
  • 36
  • 55
  • 1
    Opening the keyboard _could_ trigger a change in zoom though, which would affect at least some width measurements. – lpd Nov 25 '16 at 05:49
  • oh... yaa... if it is so we can change the condition. both width and height will differ at the same time with any input focused, right? – jafarbtech Nov 25 '16 at 05:51
  • Further, at least in Android chrome/firefox, it's possible to dismiss an onscreen keyboard without blurring the input element. – lpd Nov 25 '16 at 09:19
  • can you give me some fiddle. It ll be better to test it exactly – jafarbtech Nov 25 '16 at 09:22
  • Thanks! I took only this part `function isFocus(){ return $(document.activeElement).prop('tagName')=='INPUT' || $(document.activeElement).prop('tagName')=='TEXTAREA'; }` and transformer into this: $(window).resize(function(){ var focusedTagName = $(document.activeElement).prop('tagName'); if (focusedTagName == 'INPUT' || focusedTagName == 'TEXTAREA' || focusedTagName == 'SELECT' || focusedTagName == 'IFRAME' ) { // Fix for android keyboard. Do nothing. } else {} }); – mialdi98 Dec 22 '21 at 11:51
0

Working fine in current version of chrome webview. I just implemented window resize functionality in Angular by using below code.

@HostListener('window:resize', ['$event'])
  onResize(event) {
  // Do you handling here.
}

Note: Same can be achieved by using

 window.addEventListener('resize', () => {
   // Do handling here
 });
harsh
  • 247
  • 1
  • 2
  • 12