2010-12-03 17 views
2

Ok, il m'a fallu un peu de temps pour trouver un titre pour cette question. Imaginons que vous ayez une liste de sélection multiple et que vous utilisiez jQuery pour détecter l'événement de modification. Cela fonctionnera bien sous Firefox et IE dans des conditions normales. Mais dans IE, si vous sélectionnez quelque chose dans la liste, et que vous ne relâchez la souris qu'après que votre curseur se trouve en dehors de la sélection, l'événement ne sera pas déclenché. Cela fonctionne dans Firefox.jQuery change d'événement ne se déclenche pas dans IE lors de la libération de la souris en dehors de la sélection multiple

HTML:

<select size="4" name="ListBox" multiple="multiple" id="ListBox"> 
    <option value="32">32</option> 
    <option value="48">48</option> 
</select> 

Javascript:

$(ListBox).change(function() 
{ 
    alert("Change fired"); 
}); 

Vous pouvez tester l'exemple ici: http://jsfiddle.net/as7EN/1/

FF 3.6.12: TRAVAUX
IE8: NE FONCTIONNE PAS

Merci pour toute suggestio n.

+1

Ce que vous mentionnez ci-dessus ne fonctionne pas pour moi dans FF http://jsfiddle.net/as7FR/1/ – Raynos

+0

Peut-être que vous pourriez faire un événement sur la mise au point - une fois qu'il perd le focus vérifier. – Bob

+0

Merci Raynos pour cet exemple en direct, je ne connaissais pas ce site. Incroyable. Je posterai votre lien à la question principale. Je suis sous FF 3.6.12 et ça marche pour moi. Quelle est ta version? – md1337

Répondre

2

s'avère que c'est un jQuery 1.4. * Bug!

J'ai testé le Fiddle à nouveau avec une version antérieure de jQuery, 1.3.2, et bien sûr cela fonctionne!

J'ai posté un rapport de bogue à jQuery de, s'il vous plaît voter là mon rapport si vous les aimez pour y remédier (flèches très petits au-dessus du billet à côté du lien « Ticket précédent »):

http://bugs.jquery.com/ticket/7698

0

Une solution hackish

[solution Edité]

var clickDown = false; 
var currentlySelected = null; 

$("#ListBox").mousedown(function (event) 
{ 
    clickDown = this; 
}); 

$(document).mouseup(function() { 
    setTimeout(function() { 
     if (clickDown) { 
      if (currentlySelected != clickDown.selectedIndex) { 
       alert("change"); 
       currentlySelected = clickDown.selectedIndex; 
      } 
      clickDown = false; 
     } 
    }, 0); 
}); 

Fondamentalement sur mouseDown nous positionnons un drapeau en disant que vous cliquez sur la zone de liste.

Puis nous vérifions chaque mouseUp dans le document entier. Nous enveloppons la fonction entière dans un délai d'expiration pour nous assurer que IE8 définit correctement l'index selected. Et si le drapeau clickDown est défini, nous savons que le clickUp provient d'une liste. Pour convience, je stocke également l'objet listbox dans le flag depuis (object === true) en javascript.

Ensuite, nous vérifions simplement si notre variable contenant l'index actuel a changé. Si c'est le cas, une modification se produit et nous mettons à jour cette variable pour refléter le nouvel index.

Enfin, nous devons définir à nouveau sur clickDown false à l'extérieur d'autres clics dans le document penserait à partir de la liste.

Cela implique de vérifier chaque clic et est pas une solution élégante

http://jsfiddle.net/as7EN/37/

[Edit] Cela ne fixe pour le chrome. Pas pour IE8. J'y travaille.

Je l'ai réduit au fait que IE modifie l'élément selectedIndex après le déclenchement de l'événement mouseUp.

Ce bug peut être évité en l'enveloppant dans un timeOut de sorte que la fonction soit appelée après qu'IE8 ait défini selectedIndex à la valeur réelle. Je ne me soucie pas de IE6/7 fix que vous-même.

Aussi, si vous voulez travailler MultiSelect me dire et je vais pirater autour aswell que

+0

J'apprécie vos efforts pour m'aider. Cependant, voir mon autre réponse, j'ai découvert qu'il s'agissait d'un bug jQuery introduit dans la branche 1.4. – md1337