11484 sujets

JavaScript, DOM et API Web HTML5

Bonjour
Dans une page HTML j'ai la ligne suivante

<p>
    <span id="counter" contenteditable="true">12</span>
    <span>123</span>
</p>

Ce qui affiche 12/123
Je veux pouvoir modifier manuellement le numéro, c'est pourquoi j'ai mis #counter en "contenteditable"
J'ai mis un eventlistener sur "change": ne fonctionne pas
sur "input": ça se déclenche à chaque entrée de caractère.

Quelle est la bonne méthode pour avoir l'équivalent de "change"?
Modérateur
Tu peut te servir de l’événement "input" pour les éléments éditables qui ne sont pas des éléments de formulaires. ( se déclenche en live)

https://developer.mozilla.org/fr/docs/Web/API/HTMLElement/input_event

test sur ton code :
e = document.querySelector('#counter');
 e.addEventListener("input", function() {   
   alert('change');
 });

et un pen pour tester en live : https://codepen.io/gc-nomade/pen/wvaYbge
(+ un jsbin pour les vieux IE où cela ne fonctionne pas )


OUPS, réponse inutile ...
Modifié par gcyrillus (25 Mar 2020 - 12:32)
Merci de ta réponse
C'est ce que j'ai essayé de faire, le résultat est que l'évènement se déclenche à l'entrée de chaque caractère: je ne peux donc pas entrer un nombre à 2 chiffres.
Peut être un keypress ?
Je nage...
Modérateur
ce que tu peut tenter c'est de mettre en mémoire ton contenu au focus et de le comparer à la perte du focus.

e = document.querySelector('#counter');
 e.addEventListener("focus", function() {  
// on recupere ce qu'il y a 
   console.log('focus');
 });
   e.addEventListener("blur", function() {  
// on recupere ce qu'il y a et on compare a ce qu'il y avait 
   console.log('blur');
 });

Voilà mon beau yaka Smiley decu
Modifié par gcyrillus (25 Mar 2020 - 12:54)
stryk a écrit :
Hello,

Comme ceci ça ne change qu'à la sortie de l'input:
https://codepen.io/exemple/pen/LYVgoeE

Pour le moment, j'en suis effectivement à mettre in <input> à la place de mon <span>
Le problème c'est "comment on en sort" avec un clavier?
J'ai fait une bidouille

this.keyup = function(event) {
  if(event.key == 'Enter') this.change(event);
}

ça marche mais c'est pas génial
Et d'autre part j'aimerais bien comprendre comment utiliser ces fichus contenteditable.
gcyrillus a écrit :
ce que tu peut tenter c'est de mettre en mémoire ton contenu au focus et de le comparer à la perte du focus.

e = document.querySelector('#counter');
 e.addEventListener("focus", function() {  
// on recupere ce qu'il y a 
   console.log('focus');
 });
   e.addEventListener("blur", function() {  
// on recupere ce qu'il y a et on compare a ce qu'il y avait 
   console.log('blur');
 });

Voilà mon beau yaka Smiley decu

Ouais. Pourquoi pas ? Smiley decu Smiley decu Smiley decu Smiley cligne
Modérateur
En fait avec focusout, c'est plus simple pour faire la comparaison, exemple mis à jour : https://codepen.io/gc-nomade/pen/wvaYbge


e = document.querySelector("#counter");
// e.addEventListener("input", function() {
//   alert('change');// brrr
// });

state = document.querySelector("#statut");
verb = "Event: \n";
e.addEventListener("focusin", function() {
  text1 = e.textContent;
  console.log("focusin " + text1);
  state.textContent = verb + "focusin ";
});

e.addEventListener("focusout", function() {
  text2 = e.textContent;
  console.log("focusout " + text2);
  state.textContent = verb + "focusout ";
  if (text2 != text1) {
    console.log("different");
    state.textContent =verb +  "focusout different ";
  }
});

e.addEventListener("keydown", event => {
  if (event.code == "Enter") {
    event.preventDefault();
    console.log("Enter ");
    state.textContent = verb + "Enter ";
    text2 = e.textContent;
    if (text2 != text1) {
      // also tested on focusout !
      console.log("Enter different");
      state.textContent = verb + "Enter different";
    }
  }
});



https://caniuse.com/#search=focusout

edit (MAJ avec les infos des derniers échange , avec ajout de keydown
Modifié par gcyrillus (25 Mar 2020 - 17:05)
Modérateur
je ne vois pas de différence avec ton script, il faut cliquer en dehors de l'input pour mettre à jour l'image.
La différence avec focusout c'est que l'événement est déclanché juste avant l’événement blur ce qui permet, dans mon exemple de passer la variable à comparer avant que celle-ci devienne inaccessible/perdue.

remplace console.log("Pas pareil"); par alert("Pas pareil"); si tu n'as remarqué la différence , puis utilise blur à la place de focusout Smiley cligne a l'opposé de "input" , "focusin/focusout" fonctionne aussi avec ie11 Smiley cligne

Ou il est bien possible que je n'ai pas compris tout à fait ton soucis.

Cdt

edit bonne fin de repas
Modifié par gcyrillus (25 Mar 2020 - 14:58)
Mon soucis c’est que je ne peux pas demander à un utilisateur d’entrer un nombre PUIS de faire autre chose que CR pour que ça soit pris en compte. D’autant qu’il s’agit d’une page d’affichage. Les gens regardent puis passent à la slide suivante. Je me suis dit que leur donner la possibilité d’aller à une solide donnée pourrait être interessant. Encore faut-il que ce soit facile à faire.
Comme toujours les interfaces utilisateur sont un point difficile à traiter
Modifié par PapyJP (26 Mar 2020 - 15:47)
Voici ce que j'ai mis (et que je garde pour le moment, j'ai passé trop de temps sur ce bidule

this.change = function(event) {
  event.stopPropagation();
  var index = this.index;
  var value = this.counter.value.replace(/(^\s*|\s*$)/g, '');
  if(value.match(/^\d+$/)) {
    if(value > 0 && value <= this.slides.length) index = value - 1;
  }
  this.showSlide(index); /* afficher la slide */
}

this.keyup = function(event) {
 if(event.key == 'Enter') this.counter.blur(event);
}
...
this.counter.addEventListener('keyup', this.keyup.bind(this));
this.counter.addEventListener('blur', this.change.bind(this));

Vous remarquez qu'ayant été contaminé par virus POO dans les années 80 tout ce code est dans un "simili objet JS"
Modérateur
reste éventuellement un setTimeOut pour comparer entre 2 temps si la valeur à changée, déclenché au focus et détruit à la perte du focus et te passer de "Enter".
Modifié par gcyrillus (25 Mar 2020 - 15:49)
Merci de ta réponse
En fait je réalise que les conteneditable n’ont de sens que s’il y a un bouton pour qu’ils soient pris en compte. Ça ne convient donc pas pour ce cas précis. J’a remplacé par un <input> stylé pour qu’on ne se rende pas compte de sa nature. Il se déclenche sur l’entrée d’un CR.
Peut-être aurais-je pu faire la même chose avec un texte éditable. Il s’agit d’un point sans grande importance, mais comme je refais quelques parties du site, j’en profite pour m’instruire sur des technos que je n’ai jamais utilisées auparavant. Il faut bien utiliser le confinement à quelque chose Smiley smile