Pouvez-vous s'il vous plaît me dire comment déplacer le focus sur le champ suivant lorsque la touche Entrée est enfoncée? J'utilise le plugin dform
(qui convertit JSON en formulaire).
Je l'ai googlé, mais cela ne fonctionne pas. Pourquoi mon objectif ne passe-t-il pas au champ suivant?
$(document).keypress(function(e) {
if(e.which == 13) {
// Do something here if the popup is open
alert("dd")
var index = $('.ui-dform-text').index(this) + 1;
$('.ui-dform-text').eq(index).focus();
}
});
* Remarque (tiré des commentaires): Il doit également fonctionner sur les pages pour lesquelles les valeurs tabindex
ne sont pas définies.
Elle échoue car this
est la document
dans votre code.
Vous souhaitez utiliser l'index de l'élément actuellement sélectionné (document.activeElement
) ou, si vous utilisez des événements délégués, vous pouvez vous assurer que this
est l'élément actuel.
Cette version finale fonctionne qu’il existe ou non tabindexes
. Il entoure également:
Ils utilisent tous les deux un sélecteur jQuery personnalisé que j’ai ajouté et appelé :focusable
pour sélectionner tous les éléments activables (y compris les liens):
// register jQuery extension
jQuery.extend(jQuery.expr[':'], {
focusable: function (el, index, selector) {
return $(el).is('a, button, :input, [tabindex]');
}
});
$(document).on('keypress', 'input,select', function (e) {
if (e.which == 13) {
e.preventDefault();
// Get all focusable elements on the page
var $canfocus = $(':focusable');
var index = $canfocus.index(this) + 1;
if (index >= $canfocus.length) index = 0;
$canfocus.eq(index).focus();
}
});
Vous pouvez utiliser le même sélecteur personnalisé dans le gestionnaire d'événements si vous le souhaitez. Ensuite, cela fonctionnera même sur les liens d'ancrage (si vous modifiez l'événement en keydown au lieu d'appuyer sur la touche):
$(document).on('keydown', ':focusable', function (e) {
Ceci utilise également une on
déléguée, à l'écoute de l'événement keydown
sur la document
. Il then applique le sélecteur jQuery, il then applique la fonction à tout élément correspondant ayant provoqué l'événement. Ceci est beaucoup plus efficace car il n'applique que le sélecteur au moment de l'événement (plutôt que d'appliquer plusieurs gestionnaires d'événements à chaque élément de correspondance DOM).
$(document).keypress(function(e) {
if(e.which == 13) {
// Do something here if the popup is open
//alert("dd")
var index = $('.ui-dform-text').index(document.activeElement) + 1;
$('.ui-dform-text').eq(index).focus();
}
});
* Remarque: alerts pouvant interférer avec focus
, utilisez donc console.log
pour une sortie comme celle-ci et affichez-la dans la fenêtre de débogage de la plupart des navigateurs (comme les outils de débogage de Chrome F12).
Celui-ci revient au premier élément du dernier et fonctionne également sur les sélections (le comportement par défaut est bloqué, de sorte que vous ne pouvez utiliser que de l'espace pour ouvrir ou monter/descendre pour sélectionner des options.
$('input,select').on('keypress', function (e) {
if (e.which == 13) {
e.preventDefault();
var $next = $('[tabIndex=' + (+this.tabIndex + 1) + ']');
console.log($next.length);
if (!$next.length) {
$next = $('[tabIndex=1]');
}
$next.focus();
}
});
$(document).on('keypress', 'input,select', function (e) {
if (e.which == 13) {
e.preventDefault();
var $next = $('[tabIndex=' + (+this.tabIndex + 1) + ']');
console.log($next.length);
if (!$next.length) {
$next = $('[tabIndex=1]');
}
$next.focus();
}
});
Ill créé une version non-jQuery. Donc, seulement du Javascript pur; https://jsfiddle.net/mm0uctuv/2/
Javascript:
var inputs = document.querySelectorAll("input,select");
for (var i = 0 ; i < inputs.length; i++) {
inputs[i].addEventListener("keypress", function(e){
if (e.which == 13) {
e.preventDefault();
var nextInput = document.querySelectorAll('[tabIndex="' + (this.tabIndex + 1) + '"]');
if (nextInput.length === 0) {
nextInput = document.querySelectorAll('[tabIndex="1"]');
}
nextInput[0].focus();
}
})
}
HTML:
<form>
Field 1: <input type="text" tabindex="1"><br>
Field 3: <input type="text" tabindex="3"><br>
Field 2: <input type="text" tabindex="2">
</form>
Le code suivant devrait le faire; il utilise la propriété tabIndex
. Faites-nous savoir si ce n'est pas acceptable:
$(function() {
$('input').on('keypress', function(e) {
e.which !== 13 || $('[tabIndex=' + (+this.tabIndex + 1) + ']')[0].focus();
});
});
La liste déroulante a déjà la touche entrée destinée à l’ouvrir.
Pour pouvoir faire quelque chose avant de passer à l'élément de formulaire suivant, vous pouvez utiliser la version suivante:
$(function() {
$(document).on('keypress', function(e) {
var that = document.activeElement;
if( e.which == 13 ) {
e.preventDefault();
alert( "dd" );
$('[tabIndex=' + (+that.tabIndex + 1) + ']')[0].focus();
}
});
});
Sur la div
de niveau supérieur, ajoutez onKeyDown={this.onKeyDown.bind(this)}
et ajoutez la méthode suivante (ES6) à la même classe que la div
:
onKeyDown(event) {
if (event.keyCode === 13) {
event.preventDefault()
const inputs =
Array.prototype.slice.call(document.querySelectorAll("input"))
const index =
(inputs.indexOf(document.activeElement) + 1) % inputs.length
const input = inputs[index]
input.focus()
input.select()
}
}
Essayez le code JavaScript suivant que j'ai modifié de votre violon. Le comportement par défaut des éléments sélectionnés consiste à développer la pression de touche. Le signe plus au début de + $ (this) .attr ("tabindex")
Convertit la valeur de l'attribut text en int.
$(".ui-dform-text").keypress(function(e) {
if(e.which == 13) {
// Do something here if the popup is open
alert($(this).attr("tabindex"));
var index = +$(this).attr("tabindex") + 1;
$("[tabindex='" + index +"']").focus();
}
});