shiftKey in Safari on iOS

2019-03-26 07:56发布

问题:

Is there any way to determine in javascript whether shift key is pressed on mobile keyboard, and distinguish it from the caps lock(twice pressed shift key)

回答1:

Some Facts

First, let's look at some facts about iOS keyboards I assume you already know:

  • When you enter the keyboard mode, the shift key is always activated
  • Caps Lock must be activated manually (I guess this is not used too widely)

iPhone Shift Key Handling

I investigated a bit into this issue, and here's what I found:

  • The shift Key triggers no key Event

  • There is no special iPhone Browser API to detect whether the shift key is pressed or not, except in an iOS App (duh)

  • The keydown, keypress, keyup event triggered by iOS look normal, except they do not indicate shiftKey usage, and apart from their timestamp and type cannot be distinguished.

  • You cannot manually dispatch a Keyboard Event in iOS because of this issue, keyCode and which are readonly and always set to 0. Retriggering a Keyboard event to get some indication about the shift key still being on is impossible.

  • Actually, The iPhone treats the shift key like some sort of Short Term Caps Lock key. The difference is that normally, you activate it once, and it deactivates automatically.

What can be done

I assume you want to indicate on an input field whether the user should be careful about having Shift/Caps Lock pressed (a password field, for example). What I came up with is some sort of a workaround, but I think it's better than nothing.

You can also test the jsfiddle here.

DOM Setup

<div id="wrapper">
  <label for="test">ENTER SOMETHING HERE</label>
  <input type="text" name="test" id="test"/>
</div>
<div id="warning"></div>​

Javascript

This checks wheter the user did enter capitalized input, and it assumes the user is using caps lock if two capitalized letters where entered.

var isCaps = false,
isUppercase = false,
str = '',
test = document.getElementById('test'),
warning = document.getElementById('warning');

function capsDetection(e) {

    // Since where on iOS, we at least don't have to care 
    // about cross-browser stuff
    var s = String.fromCharCode(e.which);
    isCaps = isUppercase;

    // if the char doesn't match its lower case friend, and the shift key is 
    // not pressed (which is always the case on iOS, but we leave it there 
    // for readability), we have uppercase input
    isUppercase = (s.toUpperCase() === s && s.toLowerCase() !== s && !e.shiftKey);

    // if its the second uppercase input in a row, we may have caps lock input
    isCaps = isCaps && isUppercase;

    // set the warning
    if (isUppercase && !isCaps) {
        str = 'You where using the shift key';
    }
    else if (isCaps) {
        str = 'Caps lock seems to be activated';
    } else {
        str = '';
    }
    warning.innerHTML = str;
}

// the right event properties are only available on keypress
test.addEventListener('keypress', capsDetection);

As I said, better than nothing, but not a solution if you need to know the shift key is pressed without the user doing any input. That seems to be impossible right now.



回答2:

I don't think that this is possible with Javascript. It is possible with objective C though.

http://developer.apple.com/library/safari/#documentation/UserExperience/Reference/TouchEventClassReference/TouchEvent/TouchEvent.html