javascript - otro - evento keydown en la lista desplegable
menu desplegable javascript (12)
Ante todo. Debes elegir un evento para registrarte. No se registre en keyup y keydown al mismo tiempo. Le da al navegador un momento difícil, ya que afectan su resultado final. Para ver a qué me refiero, simplemente edite el plunk, agregue un evento keyup. El resultado final se comporta un poco descuidado.
keyup : evento activado cuando se suelta una tecla en el teclado.
keydown : evento activado cuando se presiona una tecla en el teclado.
pulsación de tecla : evento activado cuando se presiona una tecla en el teclado.
Tienen sus diferencias, mejor se adhieren a una, prefiero que en este ejemplo use keydown, solo juegue mejor conmigo, puede usar keyup.
Edición : Una nota rápida. La combinación de teclas para mi ejemplo no se reproduce bien, porque parece que el cambio en el índice seleccionado, aparece primero y luego el evento vinculado. En keydown, primero se desencadena el evento, funciona y, luego, el SelectedIndex cambia. Para jugar con keyup, el siguiente código necesita algunas modificaciones, lo que significa que el paso no es necesario cuando se usa keyup.
Tengo una demostración de plnkr here .
Lo he probado en IE10, Opera, Safari, Firefox y Chrome. Como es de esperar, los navegadores webkit no activan el evento keydown / keyup / keypress cuando se selecciona una lista de selección. Razón desconocida para mí, por el momento. En Firefox funciona muy bien. En IE funciona parcialmente. Entonces, para lograr tu objetivo, ¡código personalizado al rescate! Acabo de vincular un evento de cambio al documento, escucho para kewdown y cambiar. Si el tipo de evento es un cambio, entonces la solución entra en juego. Aquí un código:
$(document).ready(function(){
$(document).on(''keydown change'', ''select'', function(evt){
var shiftKey = evt.shiftKey;
var code = evt.keyCode || evt.which;
//if it''s a change event and i dont have any shiftKey or code
//set the to a default value of true
if(evt.type === ''change'' && !shiftKey && !code){
//special! only when change is fired
shiftKey = true;
code = true;
}
//if shift key
if(shiftKey && (code === 40 || code === 38 || code === true)){
var target = $(evt.target);
//if code is not true means it is not a change event, go ahead and set
//a step value, else no step value
var step = (code !== true) ? (code === 40) ? 1 : -1 : 0;
var index = target[0].selectedIndex + step;
//just to keep the lower and upper bound of the select list
if(index < 0){
index = 0;
}else if(index >= target[0].length){
index = target[0].length - 1;
}
//get all other select lists
var allOtherSelects = target.closest(''div'').siblings(''div'').children(''select'');
//foreach select list, set its selectedIndex
$.each(allOtherSelects, function(i, el){
el.selectedIndex = index;
});
}
});
});
Estoy tratando de crear una lista desplegable, que cuando un usuario tiene la tecla MAYÚS, seleccionará el mismo índice en todas las demás listas desplegables.
Actualmente, estoy haciendo lo siguiente:
$(document).on(''keyup keydown'', function (e) { shifted = e.shiftKey });
$(document).on(''change'', ''.report_info select'', function (e) {
if (shifted) {
//Code to change other drop down lists.
}
});
Esto solo funciona si mantiene presionada la tecla Mayús antes de ingresar a la lista desplegable. Si está dentro de la DDL y presiona la tecla de mayúsculas, el evento keyup / keydown no se activará y el shifted
permanecerá false
¿Hay alguna forma de detectar el evento keyup / keydown mientras una lista desplegable está enfocada?
Editar:
Parece que podría ser un problema solo con Chrome , solo intenté agregar lo siguiente y funciona en Firefox e IE, pero no en Chrome:
$(document).on(''keyup keydown'', ''select'', function (e) {
shifted = e.shiftKey;
});
Aquí hay un problema de él que no funciona en Chrome: http://jsfiddle.net/ue6xqm1q/4
Bryan, puedes intentar la siguiente manera de hacer esto. Lo probé en Jsfiddle it trabajando en tu camino si recibí tu pregunta correctamente.
var shifted = false;
$(document).on(''keyup keydown'', function (e) { shifted = e.shiftKey; });
$("select").on(''keyup keydown'', function (e) {
shifted = e.shiftKey;
});
$(''.report_info select'').on(''change'', function (e) {
var cr = $(this).val();
if (shifted) {
$(''.report_info select'').each(function () {
$(this).val(cr);
});
}
});
Por favor, dígame si le funciona.
Chrome hack: puedes configurar un evento personalizado para el documento. Y dispara este evento cuando se presiona la tecla de mayúsculas dentro del DDL. El disparador de disparo Jquery puede pasar parámetros personalizados.
Compruebe el trabajo JS FIDDLER
Prueba el siguiente script para tu escenario
<script type="text/javascript" language="javascript">
window.shifted = false;
$(document).on(''keyup keydown'', function (e) { shifted = e.shiftKey; });
$(document).on(''change'', ''select.report_info'', function (e) {
var cr = $(this).val();
if (shifted) {
$(''.report_info'').each(function () {
$(this).val(cr);
});
}
});
</script>
Creo que la respuesta de @juzja puede ser tu mejor apuesta. Estoy publicando esto como una "respuesta" en lugar de un comentario, porque he realizado mi propia investigación para determinar que no se dispara ningún evento cuando se abre un elemento select
en Chrome.
Ver Fiddle: http://jsfiddle.net/m4tndtu4/6/
He adjuntado todos los controladores de eventos posibles (creo) al elemento de input
y ambos elementos de select
.
En Chrome, verás muchos eventos que se activan cuando trabajas con el elemento de input
, pero no verás que se activen eventos cuando trabajas en el primer elemento select
cuando está abierto.
Curiosamente, los eventos se activan en Chrome si el elemento select
tiene el atributo o size
multiple
> 1.
En Firefox, verás eventos activados en los tres elementos.
Fuera de la sugerencia de @juzja, su mejor apuesta puede ser simular el elemento select
.
Encontré una solución única para este problema específicamente para Chrome. Aparece que Chrome se desplaza fuera del dom normal para seleccionar elementos cuando tienen enfoque, por lo que nunca obtendrás los eventos onkey (abajo | presionar | arriba) para capturar el código clave. Sin embargo, si el tamaño del cuadro de selección es> 1, entonces funciona. Pero cualquier persona que quiera un cuadro desplegable real en lugar de lo que parece un cuadro combinado puede resolver este problema con este código. En mi caso, intentaba evitar que la tecla de retroceso volviera a la página anterior del navegador.
Javascript se ve así:
$(document).ready(function() {
$(''select'').keypress(function(event)
{ return cancelBackspace(event) });
$(''select'').keydown(function(event)
{ return cancelBackspace(event) });
});
function cancelBackspace(event) {
if (event.keyCode == 8) {
return false;
}
}
Entonces el HTML se ve así:
<select id="coaacct" style="border:none;width:295px;" onclick="if (this.size){this.size=''''}else{this.size=''20''};">
Uso el evento onclick para cambiar el tamaño del cuadro de selección a 20 si no tiene tamaño y volver a cambiarlo a nada si tiene un tamaño. De esta manera, funciona como un menú desplegable de selección normal, pero debido a que tiene un tamaño mayor que 1 cuando selecciona la opción, detectará los códigos clave. No vi esta respuesta adecuadamente en ningún otro lugar, así que pensé en compartir mi solución.
Esta es una solución bastante intrincada para ser honesto, pero es un medio para un fin hasta que, con suerte, encuentre algo mejor.
Dado que el problema es que Chrome no registra los eventos keydown / keyup en los elementos select
hasta que desaparezca la lista desplegable, debemos:
a) averiguar cómo hacer que el evento se dispare (no tengo idea)
o
b) Comprobar si nuestras condiciones se cumplieron en un orden diferente.
Chrome activará el evento de cambio de tecla después de hacer clic, por lo que simplemente podemos verificar si se presionó el botón inmediatamente antes de este evento. Como otros navegadores se comportan de manera más esperada, también dejaremos el código anterior en su lugar.
Para hacer esto, establecemos un temporizador en el evento de clic, y luego, cuando se activa el evento de cambio para la selección, si el temporizador de evento de clic también se estableció, deberíamos ejecutar nuestro código aquí para que Chrome lo active. Reiniciamos el temporizador para que no se dispare varias veces.
NOTA : si presiona la tecla shift inmediatamente después de configurar los valores (dentro del límite del clic que especifique), también los establecerá todos. No creo que esto sea irrazonable, ya que en realidad se siente bastante natural cuando sucede.
Use el siguiente código:
var shifted = false;
var hackytimer = 0;
$(document).on(''keyup keydown'', function (e) {
shifted = e.shiftKey;
});
$(document).on(''keyup keydown'', ''select'', function (e) {
shifted = e.shiftKey;
if(Date.now() - hackytimer <200){
changeAllSelects($(this).val());
}
});
$(document).on(''change'', ''.report_info select'', function (e) {
hackytimer = Date.now();
if (shifted) {
changeAllSelects($(this).val());
}
});
function changeAllSelects(cr){
hackytimer = 0;
$(''.report_info select'').each(function () {
$(this).val(cr);
});
}
Vea el ejemplo de trabajo aquí: http://jsfiddle.net/0fz5vcq6/2/
Hola, eso no funcionó porque no se enfocó en su selección, que tiene un límite de reducción de teclas
prueba esto
$(''select'').first().focus();
Salta esta cosa que te ayude ... :)
var onkeydown = (function (ev) {
var key;
var isShift;
if (window.event) {
key = window.event.keyCode;
isShift = window.event.shiftKey ? true : false;
} else {
key = ev.which;
isShift = ev.shiftKey ? true : false;
}
if ( isShift ) {
switch (key) {
case 16: // ignore shift key
break;
default:
alert(key);
// do stuff here?
break;
}
}
});
Si necesita hacer cosas con un menú desplegable que es tan granular, es probable que no valga la pena utilizar el elemento nativo <select>
tal como está. Solo en este hilo, se discuten numerosas diferencias de implementación, y hay muchas más que están fuera del alcance de esta discusión pero que probablemente también lo afectarán. Hay varias bibliotecas de JS que pueden envolver este control, dejándolo como está en el móvil (donde realmente se necesita el control nativo) pero emulándolo en el escritorio, donde el control no hace mucho que no se pueda emular en JS .
- bootstrap - no envuelve automáticamente el control nativo para dispositivos móviles
- dropdown.js
- dropdown.dot.js
Su sintaxis parece incorrecta.
$("#target").keydown(function() {
alert( "Handler for .keydown() called." );
});
ACTUALIZAR
Advertencia: el comportamiento de Chrome (mis) difiere en diferentes plataformas. En Chrome Windows, se activa un evento keydown justo después de que se libera la selección, mientras que en OsX no se activa. Esto explica por qué la solución @judgeja funcionó para algunos, y no lo hizo para mí, mientras que la mía funcionó en OsX y no en Windows.
Así que creé un fiddle actualizado para combinar mi solución OsX con su Windows uno.
http://jsfiddle.net/0fz5vcq6/5/
En las plataformas en las que se desencadena el keydown utiliza la solución @judgeja, si no se desencadena, prueba el evento keyup sin el keydown anterior (mi solución anterior). Es feo, ya que funciona solo después de la LIBERACIÓN de la tecla de mayúsculas, pero feo solo en Chrome OsX.
var shifted = false;
var hackytimer = 0;
var lastval=null;
$(document).keydown(function(e){
if(e.which == 16){
if(Date.now() - hackytimer <200){
alert("you pressed shift inside the select (Win)");
changeAllSelects($(this).val());
} shifted = true;
}
});
$(document).keyup(function(e){
if(e.which == 16) {
if(!shifted && lastval!=null) {
alert("you pressed shift inside the select (OsX)");
$(''.report_info select'').each(function () {
changeAllSelects(lastval);
});
}
shifted = false;
}
});
$(document).on(''change'', ''.report_info select'', function (e) {
hackytimer = Date.now();
if (shifted) {
changeAllSelects($(this).val());
} else {
lastval=$(this).val();
}
});
function changeAllSelects(cr){
hackytimer = 0;
$(''.report_info select'').each(function () {
$(this).val(cr);
});
}
El crédito se destina principalmente a @judgeja por su solución de temporizador con una solución adicional para Mac (y otras plataformas que se comportan igual)
Sigo pensando que emular las selecciones con algo HTML como http://gregfranko.com/jquery.selectBoxIt.js/ está más limpio, ya que no deberían interferir con keydown / keyups.
SOLUCIÓN ANTERIOR (solo OsX)
La única solución que podría pensar, en ausencia total de cualquier evento, es probar si se produjo un cambio hacia arriba sin el cambio anterior hacia abajo. Esto puede funcionar si no tiene otros elementos que se comporten de la misma manera que los seleccionados
Es un poco complicado y sucio, funcionará DESPUÉS de que el usuario suelte la tecla de mayúsculas
var shifted = false;
var lastval=null;
$(document).keydown(function(e){
if(e.which == 16){
shifted = true;
}
});
$(document).keyup(function(e){
if(e.which == 16){
if(!shifted && lastval!=null) {
alert("you pressed shift inside the select");
$(''.report_info select'').each(function () {
$(this).val(lastval);
});
}
shifted = false;
}
});
$(document).on(''change'', ''.report_info select'', function (e) {
var cr = $(this).val();
if (shifted) {
$(''.report_info select'').each(function () {
$(this).val(cr);
});
} else {
lastval=cr;
}
});
Debe comportarse normalmente en los navegadores sin buggy. De todos modos, estoy de acuerdo en emular las selecciones con algo HTML como http://gregfranko.com/jquery.selectBoxIt.js/ podría ser la forma más limpia.