显示键盘android(cordova)

T先生

大家好,我想将这个简单的打字游戏集成到我的应用程序中,但是键盘不会在android中自动显示,如果我添加一个输入字段,那么该脚本将无法正常工作,有什么主意吗?(注意:我没有使用jQuery)

loadGame();
polyfillKey(); 


function loadGame() {
  var button = document.createElement('button');
  button.textContent = 'Start Game';
  var main = document.getElementById('main');
  main.appendChild(button);
  var rules = document.createElement('p');
  rules.textContent = 'Letters will fall... if you have a keyboard, press the correct key to knock it away before it hits the ground';
  main.appendChild(rules);
  button.addEventListener('click', function startIt(e) {
    main.textContent = '';
    playGame();
  });
}

function playGame(replay) {
  var LETTERS = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
  var animations = {'a':[],'b':[],'c':[],'d':[],'e':[],'f':[],'g':[],'h':[],'i':[],'j':[],'k':[],'l':[],'m':[],'n':[],'o':[],'p':[],'q':[],'r':[],'s':[],'t':[],'u':[],'v':[],'w':[],'x':[],'y':[],'z':[]};
  var gameOn = true;
  var timeOffset = 2000; //interval between letters starting, will be faster over time
  var DURATION = 10000;
  var main = document.getElementById('main');
  var header = document.querySelector('header');
  var scoreElement = document.getElementById('score');
  var score = parseFloat(scoreElement.textContent);
  var rate = 1;
  var RATE_INTERVAL = .05; //playbackRate will increase by .05 for each letter... so after 20 letters, the rate of falling will be 2x what it was at the start
  var misses = 0;

  //Create a letter element and setup its falling animation, add the animation to the active animation array, and setup an onfinish handler that will represent a miss. 
  function create() {
    var idx = Math.floor(Math.random() * LETTERS.length);
    var x = (Math.random() * 85) + 'vw';
    var container = document.createElement('div');
    var letter = document.createElement('span');
    var letterText = document.createElement('b');
    letterText.textContent = LETTERS[idx];
    letter.appendChild(letterText);
    container.appendChild(letter);
    main.appendChild(container);
    var animation = container.animate([
      {transform: 'translate3d('+x+',-2.5vh,0)'},
      {transform: 'translate3d('+x+',82.5vh,0)'}
    ], {
      duration: DURATION,
      easing: 'linear',
      fill: 'both'
    });
    
    animations[LETTERS[idx]].splice(0, 0, {animation: animation, element: container});
    rate = rate + RATE_INTERVAL;
    animation.playbackRate = rate;
    
    //If an animation finishes, we will consider that as a miss, so we will remove it from the active animations array and increment our miss count
    animation.onfinish = function(e) {
      var target = container;
      var char = target.textContent;
                                      
      animations[char].pop();
      target.classList.add('missed');
      handleMisses();
    }
  }
  
  //When a miss is registered, check if we have reached the max number of misses
  function handleMisses() {
    misses++;
    var missedMarker = document.querySelector('.misses:not(.missed)');
    if (missedMarker) {
      missedMarker.classList.add('missed');
    } else {
      gameOver();
    }
  }
  
  //End game and show screen
  function gameOver() {
    gameOn = false;
    clearInterval(cleanupInterval);
    getAllAnimations().forEach(function(anim) {
      anim.pause();
    });

    //Could use Web Animations API here, but showing how you can use a mix of Web Animations API and CSS transistions
    document.getElementById('game-over').classList.add('indeed');
  }

  //Periodically remove missed elements, and lower the interval between falling elements
  var cleanupInterval = setInterval(function() {
    timeOffset = timeOffset * 4 / 5;
    cleanup();
  }, 20000);
  function cleanup() {
    [].slice.call(main.querySelectorAll('.missed')).forEach(function(missed) {
      main.removeChild(missed);
    });
  }
  
  //Firefox 48 supports document.getAnimations as per latest spec, Chrome 52 and polyfill use older spec
  function getAllAnimations() {
    if (document.getAnimations) {
      return document.getAnimations();
    } else if (document.timeline && document.timeline.getAnimations) {
      return document.timeline.getAnimations();
    }
    return [];
  }
  
  //On key press, see if it matches an active animating (falling) letter. If so, pop it from active array, pause it (to keep it from triggering "finish" logic), and add an animation on inner element with random 3d rotations that look like the letter is being kicked away to the distance. Also update score.
  function onPress(e) {
    var char = e.key;
    if (char.length === 1) {
      char = char.toLowerCase();
      if (animations[char] && animations[char].length) {
        var popped = animations[char].pop();
        popped.animation.pause();
        var target = popped.element.querySelector('b');
        var degs = [(Math.random() * 1000)-500,(Math.random() * 1000)-500,(Math.random() * 2000)-1000];
        target.animate([
          {transform: 'scale(1) rotateX(0deg) rotateY(0deg) rotateZ(0deg)',opacity:1},
          {transform: 'scale(0) rotateX('+degs[0]+'deg) rotateY('+degs[1]+'deg) rotateZ('+degs[2]+'deg)', opacity: 0}
        ], {
          duration: Math.random() * 500 + 850,
          easing: 'ease-out',
          fill: 'both'
        });
        addScore();
        header.textContent += char;
      }
    }
  }
  function addScore() {
    score++;
    scoreElement.textContent = score;
  }
  
  document.body.addEventListener('keypress', onPress);

  //start the letters falling... create the element+animation, and setup timeout for next letter to start
  function setupNextLetter() {
    if (gameOn) {
      create();
      setTimeout(function() {
        setupNextLetter();
      }, timeOffset);
    }
  }
  setupNextLetter();
}

function polyfillKey() {
  if (!('KeyboardEvent' in window) ||
        'key' in KeyboardEvent.prototype) {
    return false;
  }
  
  console.log('polyfilling KeyboardEvent.prototype.key')
  var keys = {};
  var letter = '';
  for (var i = 65; i < 91; ++i) {
    letter = String.fromCharCode(i);
    keys[i] = letter.toUpperCase();
  }
  for (var i = 97; i < 123; ++i) {
    letter = String.fromCharCode(i);
    keys[i] = letter.toLowerCase();
  }
  var proto = {
    get: function (x) {
      var key = keys[this.which || this.keyCode];
      console.log(key);
      return key;
    }
  };
  Object.defineProperty(KeyboardEvent.prototype, 'key', proto);
}
$light: #eee;
$dark: #252627;
$bar: #aa6657;

body {
  height: 100vh;
  background: $dark;
  overflow: hidden;
  display: flex;
  align-items: stretch;
  flex-direction: column;
  color: $light;
  font-family: -apple-system, 'Segoe UI', 'Roboto', 'Helvetica Neue', sans-serif;
  font-family: monospace;
  font-size: 5vh;
  position: relative;
}
main {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  
  p {
    font-size: 1rem;
    text-align: center;
    margin-top: 5vh;
    padding: 0 2rem;
    max-width: 30rem;
    line-height: 1.4;
  }
}
header,
footer {
  height: 5vh;
  line-height: 5vh;
  font-size: 3vh;
  background: $bar;
  text-align: right;
  text-transform: uppercase;
  padding: 0 2.5vh;
}
footer {
  display: flex;
  justify-content: space-between;
  ul {
    display: flex;
    flex-direction: row-reverse;
    
    .misses {
      padding: .5vh;
      transition: all .225s ease-out;
      &.missed {
        opacity: .4;
        transform: rotate(-45deg);
      }
    }
  }
}

main > div {
  position: absolute;
  top: 5vh;
  left: 0;
  text-transform: uppercase;
  perspective: 300px;
  transition: opacity .7s ease-in;
  font-size: 5vh;
  
  &.popped {
    opacity: 0;
    > span {
      b {
        opacity: 0;
      }
      animation-play-state: paused;
    }
  }
  &.missed {
    opacity: 0;
    > span {
      //  transform: scaleY(0);
      animation-play-state: paused;
    }
  }
  
  > span {
    position: absolute;
    display: block;
    animation: waver 2s infinite alternate ease-in-out;
    perspective: 300px;
    b {
      display: block;
      padding: 2.5vh;
      transition: opacity .25s linear;
    }
  }
}

@keyframes waver {
  100% {
    transform: translate3d(6vw, 0, 0);
  }
}


#game-over {
  opacity: 0;
  pointer-events: none;
  transition: opacity .75s ease-out;
  background: rgba(0,0,0,.75);
  
  position: absolute;
  top: 5vh;
  right: 0;
  bottom: 5vh;
  left: 0;
  width: 100%;
  
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  
  text-transform: uppercase;
  
  &.indeed {
    opacity: 1;
    pointer-events: auto;
  }
}
button {
  appearance: none;
  border-radius: 0;
  border: .3rem solid $light;
  color: $light;
  font-size: 3vh;
  padding: 1.5vh 2vh;
  background: transparent;
  margin-top: 5vh;
  font-family: monospace;
  
  &:hover {
    border-color: $bar;
  }
}
<header></header>
<main id="main"></main>
<footer>
  <ul>
    <li class="misses">+</li>
    <li class="misses">+</li>
    <li class="misses">+</li>
    <li class="misses">+</li>
    <li class="misses">+</li>
    <li class="misses">+</li>
  </ul>
  <div id="score">0</div>
</footer>
<div id="game-over">
  <p>Game Over</p>
</div>

请忽略此内容(lorem ipsum文本,您的问题无法提交。请参见上面的错误。您的问题无法提交。请参见上面的错误。您的问题无法提交。请参见上面的错误。您的问题无法提交。请参阅上面的错误。您的问题无法提交。请参阅上面的错误。您的问题无法提交。请参阅上面的错误。您的问题无法提交。请参见上面的错误。您的问题无法提交。请参见上面的错误。

马斯韦德纳

loadGame();
polyfillKey();


function loadGame() {
  var button = document.createElement('button');
  button.textContent = 'Start Game';
  var main = document.getElementById('main');
  main.appendChild(button);
  var rules = document.createElement('p');
  rules.textContent = 'Letters will fall... if you have a keyboard, press the correct key to knock it away before it hits the ground';
  main.appendChild(rules);
  button.addEventListener('click', function startIt(e) {
    main.textContent = '';
    playGame();
  });
}

function getfocus() {
  document.getElementById("myAnchor").focus();
}

function losefocus() {
  document.getElementById("myAnchor").blur();
}

function playGame(replay) {
  var LETTERS = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
  var animations = {
    'a': [],
    'b': [],
    'c': [],
    'd': [],
    'e': [],
    'f': [],
    'g': [],
    'h': [],
    'i': [],
    'j': [],
    'k': [],
    'l': [],
    'm': [],
    'n': [],
    'o': [],
    'p': [],
    'q': [],
    'r': [],
    's': [],
    't': [],
    'u': [],
    'v': [],
    'w': [],
    'x': [],
    'y': [],
    'z': []
  };
  var gameOn = true;
  var timeOffset = 2000; //interval between letters starting, will be faster over time
  var DURATION = 10000;
  var main = document.getElementById('main');
  var header = document.querySelector('header');
  var scoreElement = document.getElementById('score');
  var score = parseFloat(scoreElement.textContent);
  var rate = 1;
  var RATE_INTERVAL = .05; //playbackRate will increase by .05 for each letter... so after 20 letters, the rate of falling will be 2x what it was at the start
  var misses = 0;

  //Create a letter element and setup its falling animation, add the animation to the active animation array, and setup an onfinish handler that will represent a miss. 
  function create() {
    var idx = Math.floor(Math.random() * LETTERS.length);
    var x = (Math.random() * 85) + 'vw';
    var container = document.createElement('div');
    var letter = document.createElement('span');
    var letterText = document.createElement('b');
    letterText.textContent = LETTERS[idx];
    letter.appendChild(letterText);
    container.appendChild(letter);
    main.appendChild(container);
    var animation = container.animate([{
        transform: 'translate3d(' + x + ',-2.5vh,0)'
      },
      {
        transform: 'translate3d(' + x + ',82.5vh,0)'
      }
    ], {
      duration: DURATION,
      easing: 'linear',
      fill: 'both'
    });

    animations[LETTERS[idx]].splice(0, 0, {
      animation: animation,
      element: container
    });
    rate = rate + RATE_INTERVAL;
    animation.playbackRate = rate;

    //If an animation finishes, we will consider that as a miss, so we will remove it from the active animations array and increment our miss count
    animation.onfinish = function(e) {
      var target = container;
      var char = target.textContent;

      animations[char].pop();
      target.classList.add('missed');
      handleMisses();
    }
  }

  //When a miss is registered, check if we have reached the max number of misses
  function handleMisses() {
    misses++;
    var missedMarker = document.querySelector('.misses:not(.missed)');
    if (missedMarker) {
      missedMarker.classList.add('missed');
    } else {
      gameOver();
    }
  }

  //End game and show screen
  function gameOver() {
    gameOn = false;
    clearInterval(cleanupInterval);
    getAllAnimations().forEach(function(anim) {
      anim.pause();
    });

    //Could use Web Animations API here, but showing how you can use a mix of Web Animations API and CSS transistions
    document.getElementById('game-over').classList.add('indeed');
  }

  //Periodically remove missed elements, and lower the interval between falling elements
  var cleanupInterval = setInterval(function() {
    timeOffset = timeOffset * 4 / 5;
    cleanup();
  }, 20000);

  function cleanup() {
    [].slice.call(main.querySelectorAll('.missed')).forEach(function(missed) {
      main.removeChild(missed);
    });
  }

  //Firefox 48 supports document.getAnimations as per latest spec, Chrome 52 and polyfill use older spec
  function getAllAnimations() {
    if (document.getAnimations) {
      return document.getAnimations();
    } else if (document.timeline && document.timeline.getAnimations) {
      return document.timeline.getAnimations();
    }
    return [];
  }

  //On key press, see if it matches an active animating (falling) letter. If so, pop it from active array, pause it (to keep it from triggering "finish" logic), and add an animation on inner element with random 3d rotations that look like the letter is being kicked away to the distance. Also update score.
  function onPress(e) {
    // var char = e.key;
    var char = this.value[this.value.length - 1];
    this.value = '';
    document.getElementById('myBox').innerText = char;

    if (char.length === 1) {
      char = char.toLowerCase();
      if (animations[char] && animations[char].length) {
        var popped = animations[char].pop();
        popped.animation.pause();
        var target = popped.element.querySelector('b');
        var degs = [(Math.random() * 1000) - 500, (Math.random() * 1000) - 500, (Math.random() * 2000) - 1000];
        target.animate([{
            transform: 'scale(1) rotateX(0deg) rotateY(0deg) rotateZ(0deg)',
            opacity: 1
          },
          {
            transform: 'scale(0) rotateX(' + degs[0] + 'deg) rotateY(' + degs[1] + 'deg) rotateZ(' + degs[2] + 'deg)',
            opacity: 0
          }
        ], {
          duration: Math.random() * 500 + 850,
          easing: 'ease-out',
          fill: 'both'
        });
        addScore();
        header.textContent += char;
      }
    }
  }

  function addScore() {
    score++;
    scoreElement.textContent = score;
  }

  // document.body.addEventListener('keypress', onPress);
  document.getElementById('myAnchor').addEventListener('keyup', onPress);

  //start the letters falling... create the element+animation, and setup timeout for next letter to start
  function setupNextLetter() {
    if (gameOn) {
      create();
      setTimeout(function() {
        setupNextLetter();
      }, timeOffset);
    }
  }
  setupNextLetter();
}

function polyfillKey() {
  if (!('KeyboardEvent' in window) ||
    'key' in KeyboardEvent.prototype) {
    return false;
  }

  console.log('polyfilling KeyboardEvent.prototype.key')
  var keys = {};
  var letter = '';
  for (var i = 65; i < 91; ++i) {
    letter = String.fromCharCode(i);
    keys[i] = letter.toUpperCase();
  }
  for (var i = 97; i < 123; ++i) {
    letter = String.fromCharCode(i);
    keys[i] = letter.toLowerCase();
  }
  var proto = {
    get: function(x) {
      var key = keys[this.which || this.keyCode];
      console.log(key);
      return key;
    }
  };
  Object.defineProperty(KeyboardEvent.prototype, 'key', proto);
}
$light: #eee;
$dark: #252627;
$bar: #aa6657;
body {
  height: 100vh;
  background: $dark;
  overflow: hidden;
  display: flex;
  align-items: stretch;
  flex-direction: column;
  color: $light;
  font-family: -apple-system, 'Segoe UI', 'Roboto', 'Helvetica Neue', sans-serif;
  font-family: monospace;
  font-size: 5vh;
  position: relative;
}

main {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  p {
    font-size: 1rem;
    text-align: center;
    margin-top: 5vh;
    padding: 0 2rem;
    max-width: 30rem;
    line-height: 1.4;
  }
}

header,
footer {
  height: 5vh;
  line-height: 5vh;
  font-size: 3vh;
  background: $bar;
  text-align: right;
  text-transform: uppercase;
  padding: 0 2.5vh;
}

footer {
  display: flex;
  justify-content: space-between;
  ul {
    display: flex;
    flex-direction: row-reverse;
    .misses {
      padding: .5vh;
      transition: all .225s ease-out;
      &.missed {
        opacity: .4;
        transform: rotate(-45deg);
      }
    }
  }
}

main>div {
  position: absolute;
  top: 5vh;
  left: 0;
  text-transform: uppercase;
  perspective: 300px;
  transition: opacity .7s ease-in;
  font-size: 5vh;
  &.popped {
    opacity: 0;
    >span {
      b {
        opacity: 0;
      }
      animation-play-state: paused;
    }
  }
  &.missed {
    opacity: 0;
    >span {
      //  transform: scaleY(0);
      animation-play-state: paused;
    }
  }
  >span {
    position: absolute;
    display: block;
    animation: waver 2s infinite alternate ease-in-out;
    perspective: 300px;
    b {
      display: block;
      padding: 2.5vh;
      transition: opacity .25s linear;
    }
  }
}

@keyframes waver {
  100% {
    transform: translate3d(6vw, 0, 0);
  }
}

#game-over {
  opacity: 0;
  pointer-events: none;
  transition: opacity .75s ease-out;
  background: rgba(0, 0, 0, .75);
  position: absolute;
  top: 5vh;
  right: 0;
  bottom: 5vh;
  left: 0;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  text-transform: uppercase;
  &.indeed {
    opacity: 1;
    pointer-events: auto;
  }
}

button {
  appearance: none;
  border-radius: 0;
  border: .3rem solid $light;
  color: $light;
  font-size: 3vh;
  padding: 1.5vh 2vh;
  background: transparent;
  margin-top: 5vh;
  font-family: monospace;
  &:hover {
    border-color: $bar;
  }
}
<header></header>
<div>
  <input id="myAnchor" style="">
  <span id="myBox"></span>
</div>
<input type="button" onclick="getfocus()" value="Get focus">
<input type="button" onclick="losefocus()" value="Lose focus">
<main id="main"></main>
<footer>
  <ul>
    <li class="misses">+</li>
    <li class="misses">+</li>
    <li class="misses">+</li>
    <li class="misses">+</li>
    <li class="misses">+</li>
    <li class="misses">+</li>
  </ul>
  <div id="score">0</div>
</footer>
<div id="game-over">
  <p>Game Over</p>
</div>

有几种解决问题的方法:您可以添加此插件https://github.com/driftyco/ionic-plugin-keyboardshow在需要时调用其方法到键盘。尽管它在许多情况下不能按预期工作,但是它可能非常适合您自己的需求。

但是,由于上述方法依赖于本机键盘,我相信这会减少您的游戏运行的可用空间(键盘至少占用屏幕高度的30%),因此您可以创建自己的虚拟键盘并将键码分配给它。按键可以垂直排列在屏幕的两侧(每侧13个),这样,您可以完全控制屏幕,键盘的放置位置,隐藏时间和显示时间。

如果您可以开源该项目,那么我已经可以使用虚拟键盘插件来在多个应用程序上输入验证令牌和OTP,因此可以为实现提供帮助。

编辑

进行了以下更改:

    //The styles were removed to be able to visualize what was going on behind
    <div>
        <input id="myAnchor" style="" >
        <span id="myBox"></span> <!-- box added to show the captured value -->
    </div>
    <input type="button" onclick="getfocus()" value="Get focus">
    <input type="button" onclick="losefocus()" value="Lose focus">

    function onPress(e) {
        // remove the next line
        // var char = e.key;
        // replace the above line with this
        var char = this.value[this.value.length - 1];
        // we have to apply this hack in order to get the last key pressed
        // Android would keep the initial values
        // until the space key or the return key is pressed
        // So, even if we clear the value programmatically, as we did below,
        // the OS would still keep it alive
        this.value = '';//this line could be omitted, but the input would be overloaded
        document.getElementById('myBox').innerText = char;

        if (char.length === 1) {
          char = char.toLowerCase();
          if (animations[char] && animations[char].length) {
            var popped = animations[char].pop();
            popped.animation.pause();
            var target = popped.element.querySelector('b');
            var degs = [(Math.random() * 1000)-500,(Math.random() * 1000)-500,(Math.random() * 2000)-1000];
            target.animate([
              {transform: 'scale(1) rotateX(0deg) rotateY(0deg) rotateZ(0deg)',opacity:1},
              {transform: 'scale(0) rotateX('+degs[0]+'deg) rotateY('+degs[1]+'deg) rotateZ('+degs[2]+'deg)', opacity: 0}
            ], {
              duration: Math.random() * 500 + 850,
              easing: 'ease-out',
              fill: 'both'
            });
            addScore();
            header.textContent += char;
          }
        }
      }

    // remove the line below    
    // document.body.addEventListener('keypress', onPress);
    // replace the above line with this one
    document.getElementById('myAnchor').addEventListener('keyup', onPress);

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Cordova + Android:如果显示虚拟键盘,如何停止屏幕缩小?

来自分类Dev

从javascript显示Android键盘

来自分类Dev

保持显示Android SOF键盘

来自分类Dev

显示来自javascript的android键盘

来自分类Dev

Apache Cordova InAppBrowser显示键盘并立即将其隐藏

来自分类Dev

键盘显示/隐藏事件在Cordova 5.1.1中未触发

来自分类Dev

如何将事件绑定到Cordova中的键盘显示

来自分类Dev

锁定android键盘以仅显示数字

来自分类Dev

Android,仅显示自定义键盘

来自分类Dev

在Android上显示表情符号键盘?

来自分类Dev

在Android TabLayout中显示虚拟键盘

来自分类Dev

Android软键盘显示在Webview上

来自分类Dev

键盘未显示在WebView Android中

来自分类Dev

Android-以编程方式显示键盘

来自分类Dev

android-edittext键盘不显示

来自分类Dev

Android软键盘显示在Webview上

来自分类Dev

在Android中显示软键盘

来自分类Dev

键盘未显示在WebView Android中

来自分类Dev

android:不自动显示软键盘

来自分类Dev

在Android TabLayout中显示虚拟键盘

来自分类Dev

弹出菜单上方的 Android 显示键盘

来自分类Dev

Android键盘-在Cordova应用中无法访问

来自分类Dev

处理 Android 键盘上的搜索按钮 - cordova 应用程序

来自分类Dev

仅在Ionic / Cordova应用上显示数字键盘

来自分类Dev

Cordova 应用程序 - 键盘显示/打开前的事件侦听器

来自分类Dev

显示软键盘时后退键的Android键事件?

来自分类Dev

单击Webview中的输入时未显示Android键盘

来自分类Dev

Android同时显示和隐藏键盘。怪异的行为

来自分类Dev

对话框片段下方显示的Android软键盘