web-dev-qa-db-fra.com

jQuery: déclenchez l'événement click () before blur ()

J'ai un champ de saisie dans lequel j'essaie de faire une suggestion de saisie semi-automatique. Le code ressemble à

<input type="text" id="myinput">
<div id="myresults"></div>

Sur l'entrée blur() de l'entrée, je veux masquer les résultats de résultats:

$("#myinput").live('blur',function(){
     $("#myresults").hide();
});

Lorsque j'écris quelque chose dans mon entrée, j'envoie une requête au serveur et reçois une réponse json, l'analyse dans une structure ul-> li et met cet ul dans mon #myresults Div.

Lorsque je clique sur cet élément li analysé, je souhaite définir la valeur de li à entrée et masquer #myresults Div

$("#myresults ul li").live('click',function(){
     $("#myinput").val($(this).html());
     $("#myresults").hide();
});

Tout se passe bien, mais lorsque je clique sur mon événement li blur(), celui-ci se déclenche avant click() et la valeur de l'entrée n'obtient pas le code html de li.

Comment puis-je configurer un événement click() avant blur()?

124
Egor Sazanovich

Solution 1

Écoutez mousedown au lieu de click.

Les événements mousedown et blur se produisent l'un après l'autre lorsque vous appuyez sur le bouton de la souris, mais click ne se produit que lorsque vous le relâchez.

Solution 2

Vous pouvez preventDefault() dans mousedown pour empêcher le menu déroulant de voler le focus. Le léger avantage est que la valeur sera sélectionnée lorsque le bouton de la souris sera relâché, ce qui correspond au fonctionnement des composants de sélection natifs. JSFiddle

$('input').on('focus', function() {
    $('ul').show();
}).on('blur', function() {
    $('ul').hide();
});

$('ul').on('mousedown', function(event) {
    event.preventDefault();
}).on('click', 'li', function() {
    $('input').val(this.textContent).blur();
});
287
Alexey Lebedev

Je viens de répondre à une question similaire: https://stackoverflow.com/a/46676463/227578

Une alternative aux solutions de mousedown consiste à ignorer les événements de flou provoqués par un clic sur des éléments spécifiques (c'est-à-dire, dans votre gestionnaire de flou, ignorez l'exécution s'il s'agit du résultat d'un clic sur un élément spécifique).

$("#myinput").live('blur',function(e){
     if (!e.relatedTarget || !$(e.relatedTarget).is("#myresults ul li")) {
         $("#myresults").hide();
     }
});
2
dule
$(document).on('blur', "#myinput", hideResult);

$(document).on('mousedown', "#myresults ul li", function(){
     $(document).off('blur', "#myinput", hideResult); //unbind the handler before updating value
     $("#myinput").val($(this).html()).blur(); //make sure it does not have focus anymore
     hideResult(); 
     $(document).on('blur', "#myinput", hideResult);  //rebind the handler if needed
});

function hideResult() {
     $("#myresults").hide();
}

[~ # ~] violon [~ # ~]

2
adeneo

J'ai fait face à ce problème et utiliser mousedown n'est pas une option pour moi.

J'ai résolu ceci en utilisant setTimeout dans la fonction de gestionnaire

        elem1.on('blur',function(e) {

            var obj = $(this);

            // Delay to allow click to execute
            setTimeout(function () {
                if (e.type == 'blur') {

                  // Do stuff here

                }
            }, 250);
        });

        elem2.click( function() {
            console.log('Clicked');
        });
1
geckob

Les solutions Mousedown ne fonctionnent pas pour moi lorsque je clique sur des éléments autres que des boutons. Voici donc ce que j'ai fait avec la fonction de flou dans mon code:

.on("blur",":text,:checkbox,:radio,select",function() {
/*
* el.container 
* container, you want detect click function on.
*/
            var outerDir = el.container.find(':hover').last();
            if (outerDir.length) {
                if ($.inArray(outerDir.prop('tagName'), ["A","SELECT"] ) != -1 || outerDir.prop('type') == 'button' || outerDir.prop('type') == 'submit') {
                    outerDir.click();
                }
                if (outerDir.prop('type') == 'checkbox') {
                    outerDir.change();
                }
                return false;
            }
/*          
* YOUR_BLUR_FUNCTION_HERE;
*/
});
0
Andriy