web-dev-qa-db-fra.com

simuler la fonction de touche de tabulation en javascript

Je vais avoir un formulaire avec beaucoup d'entrées. Je voudrais changer mon focus sur la zone de texte suivante, une fois que j'ai entré la valeur dans la zone de texte actuelle. et veulent continuer ce processus jusqu'au dernier champ. Ma question est la suivante: est-il possible de simuler une touche de tabulation via un code javascript une fois que j’ai saisi la valeur dans la zone de texte.

Sans appuyer sur la touche de tabulation du clavier, je voudrais apporter la même fonctionnalité via javascript. Est-ce possible ?

28
praveenjayapal

il vous suffit de donner le focus au prochain champ de saisie (en invoquant la méthode focus () sur cet élément de saisie), par exemple, si vous utilisez jQuery, ce code simulera la touche de tabulation lors de la saisie de:

var inputs = $(':input').keypress(function(e){ 
    if (e.which == 13) {
       e.preventDefault();
       var nextInput = inputs.get(inputs.index(this) + 1);
       if (nextInput) {
          nextInput.focus();
       }
    }
});
39
krcko

J'avais besoin d'émuler la fonctionnalité des onglets il y a quelque temps, et maintenant j'ai publié sous forme de bibliothèque qui utilise jquery .

EmulateTab : Un plugin jQuery pour émuler la tabulation entre les éléments d'une page.

Vous pouvez voyez comment cela fonctionne dans la démo .

if (myTextHasBeenFilledWithText) {
  // Tab to the next input after #my-text-input
  $("#my-text-input").emulateTab();
}
19
Joel Purra
function nextField(current){
    for (i = 0; i < current.form.elements.length; i++){
        if (current.form.elements[i].tabIndex == current.tabIndex+1){
            current.form.elements[i].focus();
            if (current.form.elements[i].type == "text"){
                current.form.elements[i].select();
            }
        }
    }
}

Ceci, lorsqu'il est fourni avec le champ actuel, fera passer le focus au champ avec l'index de tabulation suivant. L'utilisation serait comme suit

<input type="text" onEvent="nextField(this);" />
13
Gausie

Je ne pouvais pas trouver une réponse qui pourrait faire ce que je voulais. J'ai eu un problème lié à certains éléments de lien sur lesquels je ne voulais pas que les utilisateurs cliquent. Voici ce que je suis venu avec:

(Notez que dans mon propre code, j'ai utilisé a:not(.dropdown-item) à la place de a sur la ligne allElements afin d'empêcher les utilisateurs de passer à a.dropdown-item.)

function(event){
        //Note that this doesn't honour tab-indexes

        event.preventDefault();

        //Isolate the node that we're after
        const currentNode = event.target;

        //find all tab-able elements
        const allElements = document.querySelectorAll('input, button, a, area, object, select, textarea, [contenteditable]');

        //Find the current tab index.
        const currentIndex = Array.from(allElements).findIndex(el => currentNode.isEqualNode(el))

        //focus the following element
        allElements[currentIndex + 1].focus();
}
5
Andrew Peters

Ceci simule une tabulation dans un formulaire et met en évidence la prochaine entrée lorsque la touche Entrée est enfoncée.

window.onkeypress = function(e) {
    if (e.which == 13) {
        e.preventDefault();
        var inputs = document.getElementsByClassName('input');
        for (var i = 0; i < inputs.length; i++) {
        if (document.activeElement.id == inputs[i].id && i+1 < inputs.length ) {
            inputs[i+1].focus();
            break;   
        }
    }
4
Zach M

Dans la première question, vous n'avez pas besoin d'un écouteur d'événement pour chaque entrée qui serait une perte de temps.

Au lieu de cela, écoutez la touche Entrée et pour trouver l’élément en cours d’utilisation, utilisez document.activeElement

window.onkeypress = function(e) {
    if (e.which == 13) {
       e.preventDefault();
       var nextInput = inputs.get(inputs.index(document.activeElement) + 1);
       if (nextInput) {
          nextInput.focus();
       }
    }
};

Un écouteur d'événements est meilleur que beaucoup, en particulier sur les navigateurs à faible consommation/mobiles.

2
mattdlockyer

Cela devrait marcher. Travailler avec et sans tabindex.

var currentlyFocused = undefined;
var tabableElements = undefined;

/**
 * Compare function for element sort
 * @param {string | null} a
 * @param {string | null} b
 * @param {boolean} asc
 */
function sortCompare(a, b, asc = true) {
  let result = null;
  if (a == null) result = 1;
  else if (b == null) result = -1;
  else if (parseInt(a) > parseInt(b)) result = 1;
  else if (parseInt(a) < parseInt(b)) result = -1;
  else result = 0;
  return result * (asc ? 1 : -1);
}

/**
 * When an element is focused assign it to the currentlyFocused variable
 * @param {Element} element
 */
function registerOnElementFocus(element) {
  element.addEventListener("focus", function(el) {
    currentlyFocused = el.srcElement;
  });
}

/**
 * Tab Trigger
 */
function onTabClick() {
  //Select currently focused element
  let currentIndex;
  tabableElements.forEach((el, idx) => {
    //return if no element is focused
    if (!currentlyFocused) return;
    if (currentlyFocused.isEqualNode(el)) {
      //assign current index and return
      currentIndex = idx;
      return;
    }
  });
  //if theres no focused element or the current focused element is last start over
  let lastIndex = tabableElements.length - 1;
  let nextElementidx = currentIndex === undefined || currentIndex == lastIndex ? 0 : currentIndex + 1;
  //Focus
  currentlyFocused = tabableElements[nextElementidx];
  currentlyFocused.focus();
}
/**
 * Init must be run after all elements are loadead in the dom
 */
function init() {
  //Get all tab-able elements
  let nodeList = document.querySelectorAll("input, button, a, area, object, select, textarea, [tabindex]");
  //To array for easier manipulation
  tabableElements = Array.prototype.slice.call(nodeList, 0);
  //Correcting tabindexes to ensure correct order
  tabableElements.forEach((el, idx, list) => {
    let tabindex = el.getAttribute("tabindex");
    //-1 tabindex will not receive focus
    if (tabindex == -1) list.splice(idx, 1);
    //null or 0 tabindex in normal source order
    else if (tabindex == null || tabindex == 0) {
      list[idx].setAttribute("tabindex", 9999 + idx);
    }
  });
  //sort elements by their tabindex in ascending order
  tabableElements.sort((elementA, elementB) => sortCompare(elementA.getAttribute("tabindex"), elementB.getAttribute("tabindex")));
  //register focus event to elements
  tabableElements.forEach(el => registerOnElementFocus(el));
}
<!doctype html>
<html lang="en">

<head>
  <!-- Required meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

  <title>Virtual tab</title>
</head>

<body onload="init()">
  <div class="container">
    <h3>Virtual Tab Demo</h3>
    <form>
      <div class="btn btn-primary" style="position: fixed;" onclick="onTabClick()">
        Tab!
      </div>
      <br>
      <br>
      <button id="button1" type="button" onclick="alert('button 1')">Button1</button>
      <button id="button2" type="button" onclick="alert('button 2')">Button2</button>
      <br>
      <br>
      <input id="text" type='text'>text
      <br>
      <input id="password" type='password' tabindex="-1">password
      <br>
      <input id="number" type='number' tabindex="5">number
      <br>
      <input id="checkbox" type='checkbox'>checkbox
      <br>
      <input id="radio" type='radio'>radio
      <br>
      <br>
      <button id="button3" type="button" onclick="alert('button 3')">Button3</button>
      <button id="button4" type="button" onclick="alert('button 4')">Button4</button>
      <br>
      <br>
      <select id="select">
        <option value="volvo">Volvo</option>
        <option value="saab">Saab</option>
        <option value="mercedes">Mercedes</option>
        <option value="audi">Audi</option>
      </select>
      <br>
      <br> textarea
      <br>
      <textarea id="textarea"></textarea>
        <br>
        <br>
        <span id="span" tabindex="1">Focus other elements.</span>
    </form>
  </div>
  <!-- Optional JavaScript -->
  <!-- jQuery first, then Popper.js, then Bootstrap JS -->
  <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
</body>

</html>