简体   繁体   中英

Javascript focus() not working when onkeyup event is executed in iOS

I have 4 input boxes to enter 4 digit passcode. I want to focus to the next input box when the first input box is filled by user.

I had to use document.getElementById('second').focus(); to focus to the next input box. Unfortunately this does not work in iOs.

I did further research and found that focusing is not happened with the event like "onkeyup", "onkeypress", but it works with "onclick" event.

Do you guys any idea to fix this problem or alternative solution to fix this problem.

HTML

<input id="first" name="first" type="number" style="width: 50px; height: 50px;" maxlength="1" onkeyup="focusSecondBox(event);" />

<input id="second" name="second" type="number" style="width: 50px; height: 50px;" maxlength="1" onkeyup="focusThirdBox(event);"/>

JS

function getEventCharCode(evt){
        evt = (evt) ? evt : window.event;
        var charCode = (evt.which) ? evt.which : evt.keyCode;
        return charCode;
    }

    function isEmptyElement(element){

        return (element === null || element.value === null || element.value === '');
    }

    function focusSecondBox(evt){



        var element = document.getElementById('first');
        var previousElement = document.getElementById('first');
        var nextElement = document.getElementById('second');
        focusInput();

    }

    function focusInput(){
        var charCode = getEventCharCode(evt);
        if (isEmptyElement(element)) {

            if (charCode === 8) {
                previousElement.focus();
                previousElement.value = previousElement.value;

            } 
        } else if (nextElement !== null) {

            nextElement.focus();

        }
    }

Thank you

In iOS safari. Difficult or impossible to show keyboard by call focus() without mouse event as far as I know.

alternative solution

But, in this case, I implemented what expect in the following ways:

  • Use invisible input field.
  • Focus invisible input field when any input passcode field focused.
  • Move invisible input field position with key event.
  • Change passcode field by invisible input field.

HTML

<div id="dummyDiv" style="width:0px;height:0px;overflow:hidden;">
<input id="dummy" type="number" />
</div>
<input id="p0" type="number" style="width: 50px; height: 50px;" maxlength="1" />
<input id="p1" type="number" style="width: 50px; height: 50px;" maxlength="1" />
<input id="p2" type="number" style="width: 50px; height: 50px;" maxlength="1" />
<input id="p3" type="number" style="width: 50px; height: 50px;" maxlength="1" />

JavaScript

window.addEventListener('load', function() {
    var words = [];
    for(var i=0; i < 4; i++) {
        words[i]  = document.getElementById('p'+i);
    }
    var dummy = document.getElementById('dummy');
    var dummyDiv = document.getElementById('dummyDiv');
    words.forEach(function(word) {
        word.addEventListener('click', function(e) {
            dummy.focus();
        });
    });
        dummy.addEventListener('keypress', function(e) {
            if (dummy.value.length >= 4 || !String.fromCharCode(e.keyCode).match(/[0-9\.]/)) {
                e.preventDefault();
            }
        });

    dummy.addEventListener('keyup', function(e) {
        console.log(dummy.value);
        var len = dummy.value.length;

        for(var i=0; i<4; i++) {
            if(len <= i) {
                words[i].value = '';
            } else {
                words[i].value = dummy.value[i];
            }
        }
        if (len>=4) {
            return;
        }
        dummyDiv.style.position = 'absolute';
        var rect = words[len].getBoundingClientRect();
        dummyDiv.style.left = rect.left+'px';
        dummyDiv.style.top = (rect.top+15)+'px';
    });
});

working sample

http://nakaji-dayo.github.com/ios-safari-passcode-boxes/

Please look on iOS

<!DOCTYPE html>
<html>
<head>
    <style type="text/css">
     #hidebox {position:absolute; border: none; background:transparent;padding:1px;}
     #hidebox:focus{outline: 0;}

    </style>
</head>

<body>

<input type="text" maxlength="1" onkeyup="keyUp(this)" onkeydown="keyDown(this)" size="2" id="hidebox" at="1">
<input type="text" maxlength="1" size="2" id="mFirst" at="1" onfocus="onFocus(this)"><input type="text" maxlength="1" size="2" id="mSecond" at="2" onfocus="onFocus(this)"><input type="text" maxlength="1" size="2" id="mThird" at="3" onfocus="onFocus(this)"><input type="text" maxlength="1" size="2" id="mFourth" at="4" onfocus="onFocus(this)">
</li>
<script type="text/javascript">

window.onload = function() {
     document.getElementById("mFirst").focus(); 
}
var array = ["mFirst","mSecond","mThird","mFourth"];
function keyUp(e) {
  var curId = array[Number(e.getAttribute("at"))-1];
  var nextId = array[Number(e.getAttribute("at"))];
  var curval= e.value;


var letters = /^[0-9a-zA-Z]+$/;
if(e.value.match(letters)){
  document.getElementById(curId).value = curval;
  if(e.getAttribute("at") <= 3){
  var nextPos = document.getElementById(nextId).offsetLeft;
  e.setAttribute("at",Number(e.getAttribute("at"))+1);
  e.style.left = nextPos+"px";
  }
 e.value = ""
}else {
 e.value = "";
}
} 
function keyDown(e) {
    var curId = array[Number(e.getAttribute("at"))-1];
    document.getElementById(curId).value = "";
} 

function onFocus(e) {
  document.getElementById("hidebox").focus();
  document.getElementById("hidebox").setAttribute("at",Number(e.getAttribute("at")));
  document.getElementById("hidebox").style.left = e.offsetLeft+"px";
  document.getElementById("hidebox").style.top = e.offsetTop+"px";
}

</script>
</body>
</html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM