Comment détectez-vous l'effacement d'une entrée HTML5 «recherche»?

154

En HTML5, le searchtype d'entrée apparaît avec un petit X sur la droite qui effacera la zone de texte (au moins dans Chrome, peut-être d'autres). Existe-t-il un moyen de détecter le moment où ce X est cliqué dans Javascript ou jQuery autre que, par exemple, détecter le moment où la case est cliquée ou faire une sorte de détection de clic d'emplacement (position x / position y)?

Jason
la source
Je ne connais pas grand-chose à HTML 5, mais n'y a-t-il pas d' onchangeévénement?
Pekka
1
Eh bien, vous pouvez déterminer si le champ de recherche est effacé de cette façon, mais pas si cela s'est produit en cliquant sur ce bouton par rapport à la sélection et à la suppression
mVChr
duplication possible de Y a
Naftali aka Neal
Réponse possible stackoverflow.com/a/59389615/11973798 Vérifiez si cela aide
Shubham Khare
vous devriez ajouter des événements keyup et de recherche ..
Burak Öztürk

Réponses:

105

En fait, il y a un événement de «recherche» qui est déclenché chaque fois que l'utilisateur recherche, ou lorsque l'utilisateur clique sur le «x». Ceci est particulièrement utile car il comprend l'attribut "incrémental".

Maintenant, cela dit, je ne suis pas sûr que vous puissiez faire la différence entre cliquer sur le «x» et rechercher, à moins que vous n'utilisiez un hack «onclick». Dans tous les cas, j'espère que cela aide.

Références:

http://help.dottoro.com/ljdvxmhr.php

Pauan
la source
2
Merci, searchje ne peux pas savoir quand l' événement se produit autrement que lorsque vous cliquez sur le 'x' Il ne semble pas tirer sur keyup, blurou quand il est en forme est soumis. Mais cela mérite d'être marqué comme une réponse.
Maksim Vi.
4
L' searchévénement doit se déclencher lorsque l'utilisateur appuie sur Enter. Et si la zone de recherche a l' incrementalattribut, elle se déclenchera également lorsque l'utilisateur arrête de taper pendant une seconde.
Pauan
6
FYI: au moment de la rédaction de ce commentaire, cela ne fonctionne que dans Chrome.
Jason
4
IE11 déclenche l' inputévénement mais pas l' searchévénement.
Joseph Lennox
1
L'événement "recherche" n'est pas standard. Regarde ça . Je ne recommanderais pas son utilisation sans poly-fill.
rstackhouse
59

Liez search-évitez le champ de recherche comme indiqué ci-dessous-

$('input[type=search]').on('search', function () {
    // search logic here
    // this function will be executed on click of X (clear button)
});
Sharad Biradar
la source
1
C'est la bonne réponse pour ceux qui ne sont pas sûrs
Erik Grosskurth
6
bon à savoir qu'un événement de recherche est pris en charge dans Chrome, mais non pris en charge dans IE ou FF et selon MDN, il s'agit d'une fonctionnalité non standard et non sur la piste des normes. developer.mozilla.org/en-US/docs/Web/Events/search
Rich Finelli
50

Je veux ajouter une réponse «tardive», parce que j'ai eu du mal avec change, keyupet searchaujourd'hui, et peut-être que ce que j'ai trouvé à la fin peut être utile pour d'autres aussi. En gros, j'ai un panneau de recherche en tant que type, et je voulais juste réagir correctement à la presse du petit X (sous Chrome et Opera, FF ne l'implémente pas), et effacer un volet de contenu en conséquence.

J'avais ce code:

 $(some-input).keyup(function() { 
    // update panel
 }
 $(some-input).change(function() { 
    // update panel
 }
 $(some-input).on("search", function() { 
    // update panel
 }

(Ils sont séparés car je voulais vérifier quand et dans quelles circonstances chacun était appelé).

Il s'avère que Chrome et Firefox réagissent différemment. En particulier, Firefox traite changecomme «chaque modification apportée à l'entrée», tandis que Chrome la traite comme «lorsque le focus est perdu ET que le contenu est modifié». Ainsi, sur Chrome, la fonction "panneau de mise à jour" a été appelée une fois, sur FF deux fois pour chaque frappe (une entrée keyup, une entrée change)

De plus, effacer le champ avec le petit X (qui n'est pas présent sous FF) a déclenché l' searchévénement sous Chrome: non keyup, non change.

La conclusion? Utilisez à la inputplace:

 $(some-input).on("input", function() { 
    // update panel
 }

Il fonctionne avec le même comportement sous tous les navigateurs que j'ai testés, réagissant à chaque changement dans le contenu d'entrée (copier-coller avec la souris, saisie semi-automatique et "X" inclus).

Lorenzo Dematté
la source
1
Merci Lorenzo ... cela a été très utile.
Sterling Bourne
2
Génial, tout simplement génial. Un grand merci m'a fait gagner du temps en essayant de comprendre celui-ci.
user2029541
Il semble que Firefox ait changé de comportement depuis? J'ai testé avec Firefox 42.0 et il traite l' changeévénement comme Chrome, ne tirant que sur Enter ou focus perdu.
Suzana
J'aime l'option sur entrée ... sympa!
Cam Tullos
14

En utilisant la réponse de Pauan, c'est la plupart du temps possible. Ex.

<head>
    <script type="text/javascript">
        function OnSearch(input) {
            if(input.value == "") {
                alert("You either clicked the X or you searched for nothing.");
            }
            else {
                alert("You searched for " + input.value);
            }
        }
    </script>
</head>
<body>
    Please specify the text you want to find and press ENTER!
    <input type="search" name="search" onsearch="OnSearch(this)"/>
</body>
Ggutenberg
la source
5
Pour moi, l' changeévénement ne se déclenche qu'en blurgros. Le simple fait de cliquer sur l' (x)intérieur du champ de recherche de Chrome ne semble déclencher aucun événement pour moi. Après une enquête plus approfondie (et la lecture des commentaires ci-dessous), je me suis mis clickà travailler pour moi. Alors ça $("input[type='search']").bind('click', function(e) { if ( this.value=="") {//this just cleared!} });marche de ma fin
Jannis
2
Mais $("input[type='search']").bind('click', function(e) { if ( this.value=="") {//this just cleared!} });se déclencherait également lorsque l'utilisateur clique dans le champ de saisie.
Scott
8

Je sais que c'est une vieille question, mais je cherchais la même chose. Déterminez quand vous avez cliqué sur le «X» pour effacer la zone de recherche. Aucune des réponses ici ne m'a aidé du tout. L'un était proche mais également affecté lorsque l'utilisateur cliquait sur le bouton «Entrée», il déclencherait le même résultat qu'en cliquant sur le «X».

J'ai trouvé cette réponse sur un autre article et cela fonctionne parfaitement pour moi et ne se déclenche que lorsque l'utilisateur efface le champ de recherche.

$("input").bind("mouseup", function(e){
   var $input = $(this),
   oldValue = $input.val();

   if (oldValue == "") return;

   // When this event is fired after clicking on the clear button
   // the value is not cleared yet. We have to wait for it.
   setTimeout(function(){
     var newValue = $input.val();

      if (newValue == ""){
         // capture the clear
         $input.trigger("cleared");
      }
    }, 1);
});
lostInTheTetons
la source
5

Il me semblait logique que cliquer sur le X soit considéré comme un événement de changement. J'avais déjà organisé l'événement onChange pour faire ce dont j'avais besoin. Donc, pour moi, le correctif consistait simplement à faire cette ligne jQuery:

$('#search').click(function(){ $(this).change(); });

Cory Gagliardi
la source
Si vous souhaitez que cela se déclenche lorsque vous appuyez sur le bouton d'effacement, vous pouvez également ajouter une vérification de la valeur de l'entrée, le commentaire d'ala Jannis ci-dessous: stackoverflow.com/questions/2977023/... if (this.value === "") { ... }
Sam
4

Il ne semble pas que vous puissiez y accéder dans le navigateur. L'entrée de recherche est un wrapper HTML Webkit pour Cocoa NSSearchField. Le bouton d'annulation semble être contenu dans le code client du navigateur sans référence externe disponible à partir du wrapper.

Sources:

On dirait que vous devrez le comprendre en positionnant la souris sur un clic avec quelque chose comme:

$('input[type=search]').bind('click', function(e) {
  var $earch = $(this);
  var offset = $earch.offset();

  if (e.pageX > offset.left + $earch.width() - 16) { // X button 16px wide?
    // your code here
  }
});
mVChr
la source
eh bien, ça craint. peut-être que j'irai avec le plan B, qui a été exécuté un événement surCliquez si l'entrée est maintenant vide ... peut-être le mettre sur une minuterie de 25 ms
Jason
@Jason ouais, et vous pouvez utiliser le code que j'ai mis ci-dessus pour l'exécuter uniquement si le clic s'est produit dans la zone où se trouve le X. Cela en plus de vérifier si l'entrée est vide comme vous l'avez dit devrait suffire
mVChr
1

J'ai trouvé ce post et je me rends compte qu'il est un peu vieux, mais je pense que j'ai peut-être une réponse. Cela gère le clic sur la croix, le recul et la frappe sur la touche ESC. Je suis sûr que cela pourrait probablement être mieux écrit - je suis encore relativement nouveau en javascript. Voici ce que j'ai fini par faire - j'utilise jQuery (v1.6.4):

var searchVal = ""; //create a global var to capture the value in the search box, for comparison later
$(document).ready(function() {
  $("input[type=search]").keyup(function(e) {
    if (e.which == 27) {  // catch ESC key and clear input
      $(this).val('');
    }
    if (($(this).val() === "" && searchVal != "") || e.which == 27) {
      // do something
      searchVal = "";
    }
    searchVal = $(this).val();
  });
  $("input[type=search]").click(function() {
    if ($(this).val() != filterVal) {
      // do something
      searchVal = "";
    }
  });
});
ScottG
la source
On dirait que filterVal n'est pas défini
dlsso
1

essayez ceci, j'espère vous aider

$("input[name=search-mini]").on("search", function() {
  //do something for search
});
Don Zanurano
la source
1

Je crois que c'est la seule réponse qui se déclenche UNIQUEMENT lorsque le x est cliqué.

Cependant, c'est un peu hacky et la réponse de ggutenberg fonctionnera pour la plupart des gens.

$('#search-field').on('click', function(){
  $('#search-field').on('search', function(){
    if(!this.value){
      console.log("clicked x");
      // Put code you want to run on clear here
    }
  });
  setTimeout(function() {
    $('#search-field').off('search');
  }, 1);
});

'#search-field'est le sélecteur jQuery pour votre entrée. Utilisez 'input[type=search]'pour sélectionner toutes les entrées de recherche. Fonctionne en recherchant un événement de recherche (réponse de Pauan) immédiatement après un clic sur le champ.

dlsso
la source
1

La solution complète est là

Cela effacera la recherche lorsque vous cliquerez sur la recherche x. ou appellera l'API de recherche lorsque l'utilisateur appuiera sur Entrée. ce code peut être encore étendu avec un matcher d'événement de keyup supplémentaire. mais cela devrait tout faire.

document.getElementById("userSearch").addEventListener("search", 
function(event){
  if(event.type === "search"){
    if(event.currentTarget.value !== ""){
      hitSearchAjax(event.currentTarget.value);
    }else {
      clearSearchData();  
    }
  }
});

À votre santé.

Tarandeep Singh
la source
1

basé sur la boucle d'événement de js, le clickbouton on clear déclenchera l' searchévénement sur l' entrée , donc le code ci-dessous fonctionnera comme prévu:

input.onclick = function(e){
  this._cleared = true
  setTimeout(()=>{
    this._cleared = false
  })
}
input.onsearch = function(e){
  if(this._cleared) {
    console.log('clear button clicked!')
  }
}

Le code ci-dessus, l' événement onclick a réservé une this._cleared = falseboucle d'événements, mais l'événement sera toujours exécuté après l' onsearchévénement, vous pouvez donc vérifier de manière stable l' this._clearedétat pour déterminer si l'utilisateur a simplement cliqué sur le Xbouton puis déclenché un onsearchévénement.

Cela peut fonctionner sur presque toutes les conditions , texte collé , attribut incrémentiel , touche ENTER / ESC , etc.

James Yang
la source
1

Voici un moyen d'y parvenir. Vous devez ajouter un attribut incrémentiel à votre html ou cela ne fonctionnera pas.

window.onload = function() {
  var tf = document.getElementById('textField');
  var button = document.getElementById('b');
  button.disabled = true;
  var onKeyChange = function textChange() {
    button.disabled = (tf.value === "") ? true : false;
  }
  tf.addEventListener('keyup', onKeyChange);
  tf.addEventListener('search', onKeyChange);

}
<input id="textField" type="search" placeholder="search" incremental="incremental">
<button id="b">Go!</button>

Revanth
la source
1
document.querySelectorAll('input[type=search]').forEach(function (input) {
   input.addEventListener('mouseup', function (e) {
                if (input.value.length > 0) {
                    setTimeout(function () {
                        if (input.value.length === 0) {
                            //do reset action here
                        }
                    }, 5);
                }
            });
}

ECMASCRIPT 2016

realmag777
la source
0

La recherche ou onclick fonctionne ... mais le problème que j'ai trouvé était avec les anciens navigateurs - la recherche échoue. De nombreux plugins (jquery ui autocomplete ou fancytree filter) ont des gestionnaires de flou et de focus. L'ajout de ceci à une boîte de saisie de saisie semi-automatique a fonctionné pour moi (utilisé this.value == "" car il était plus rapide à évaluer). Le flou puis la mise au point gardaient le curseur dans la case lorsque vous frappiez le petit «x».

Le PropertyChange et l'entrée ont fonctionné pour IE 10 et IE 8 ainsi que pour d'autres navigateurs:

$("#INPUTID").on("propertychange input", function(e) { 
    if (this.value == "") $(this).blur().focus(); 
});

Pour l'extension de filtre FancyTree, vous pouvez utiliser un bouton de réinitialisation et forcer son événement de clic comme suit:

var TheFancyTree = $("#FancyTreeID").fancytree("getTree");

$("input[name=FT_FilterINPUT]").on("propertychange input", function (e) {
    var n,
    leavesOnly = false,
    match = $(this).val();
    // check for the escape key or empty filter
    if (e && e.which === $.ui.keyCode.ESCAPE || $.trim(match) === "") {
        $("button#btnResetSearch").click();
        return;
    }

    n = SiteNavTree.filterNodes(function (node) {
        return MatchContainsAll(CleanDiacriticsString(node.title.toLowerCase()), match);
        }, leavesOnly);

    $("button#btnResetSearch").attr("disabled", false);
    $("span#SiteNavMatches").text("(" + n + " matches)");
}).focus();

// handle the reset and check for empty filter field... 
// set the value to trigger the change
$("button#btnResetSearch").click(function (e) {
    if ($("input[name=FT_FilterINPUT]").val() != "")
        $("input[name=FT_FilterINPUT]").val("");
    $("span#SiteNavMatches").text("");
    SiteNavTree.clearFilter();
}).attr("disabled", true);

Devrait pouvoir l'adapter à la plupart des utilisations.

Richard Dufour
la source
-2

Lors d'un clic sur le bouton croisé TextField (X) onmousemove () est déclenché, nous pouvons utiliser cet événement pour appeler n'importe quelle fonction.

<input type="search" class="actInput" id="ruleContact" onkeyup="ruleAdvanceSearch()" placeholder="Search..." onmousemove="ruleAdvanceSearch()"/>
priyaranjan sahoo
la source