11521 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

Je me suis créé un petit script pour des infobulles en jQuery qui diffère dans son approche de celui de GrafikArt. J'utilise notamment un .each() :
(function($){
	$('.addtooltips a').each(function(){
		var link = $(this);
		var title = link.attr('title'); // Stockage de tous les titles dans une variable
		link.css('position', 'relative');
		link.on('mouseenter', function(){
			if (title === undefined || title === '') return false; // Pas d'infobule si title manquant ou vide
			link.append('<div class="tooltip">' + title + '</div>');
			link.attr('title', ''); // Empêche l'affichage des infobules par défaut en vidant les titles
			var tooltip = $('.tooltip');
			tooltip.css({
				'position' : 'absolute',
				'opacity' : '0'
			});
			tooltip.animate({
				'opacity' : '1'
			}, 500);
		});
		link.on('mouseout', function(){
			$('.tooltip').fadeOut(500);
			link.attr('title', title); // Réinjecter la valeur du title pour l'accessibilité
		});
	});
})(jQuery);

Voir sur cette page de démo précisément ici.

Afin d'empêcher l'affichage des infobulles par défaut je supprime le contenu du title des liens au moment ou le pointeur de la souris passe sur le lien. Afin de ne pas m'embêter je pourrais me passer des valeurs de ces titles puisque je les ai tous en mémoire dans ma variable title, mais afin de garder l'accessibilité je les réinjecte quand la souris sort du lien :
link.attr('title', title); // Réinjecter la valeur du title pour l'accessibilité

Mon problème est le suivant : quand la souris "se promène" sur le lien, le contenu du title est susceptible de se réinjecter et l'infobulle par défaut réapparait alors.

J'ai pensé mettre un .delay() dans mon code, mais sans succès... Je ne vois pas ce que j'oublie :
link.delay(1000).attr('title', title);

Si vous pouviez m'auditer... Merci d'avance.
Modérateur
Salut,

Je pense que ton problème n'est pas dans le js mais dans le positionnement du pophover. Il est un poil trop haut. En fait c'est ton trick du triangle qui mange sur ton lien. Il est transparent mais il reste dessus du coup quand ta souris le chevauche c'est comme si elle sortait du lien :

upload/42161-arrow.png

Soit tu décales un peu plus le pophover vers le bas soit tu réajuste juste un poil ton ::before qui fait la flèche en mettant a 0 le border-top (t'en a pas besoin pour une flèche comme ça).

Autre remarque, tu crées à chaque fois un nouvel élément sans supprimer l'ancien. On se retrouve avec une tartine de div inutiles dans le dom....

Bonne journée
Modifié par _laurent (21 May 2015 - 10:46)
@_laurent : Merci pour ton passage. Pour le problème des infobulles persistantes j'ai trouvée la solution :
link.on('mouseout', function(){
	var tooltip = $('.tooltip');
	tooltip.fadeOut(500, function(){
		tooltip.remove();
	});
	link.attr('title', title); // Réinjecter la valeur du title pour l'accessibilité
});

_laurent a écrit :
Je pense que ton problème n'est pas dans le js mais dans le positionnement du pophover. Il est un poil trop haut. En fait c'est ton trick du triangle qui mange sur ton lien. Il est transparent mais il reste dessus du coup quand ta souris le chevauche c'est comme si elle sortait du lien...

Ah oui, merci. J'avais pourtant vu ce problème tantôt en pensant l'avoir réglé une fois pour toute...

Mais ceci dit, même après correction, le système n'est pas infaillible : je peux encore avoir une infobulle par défaut et j'aurais aimé palier à ce problème en ajoutant une temporisation avant la réinjection de la valeur du title. Comment procéder ?
Modifié par Olivier C (21 May 2015 - 11:45)
Modérateur
Olivier C a écrit :
je peux encore avoir une infobulle par défaut et j'aurais aimé palier à ce problème en ajoutant une temporisation avant la réinjection de la valeur du title. Comment procéder ?
Ah ça y est, je viens de raccrocher les wagons. C'est quand tu fait apparaitre la tooltip et que tu survol direct la tooltip, le title par défaut apparait avant que la tooltip disparaisse. Pfiou, je suis en mode cerf-volant ce matin.

Olivier C a écrit :
si je met un .remove() sur mon .tooltip dans la fonction commandée par mouseout j'ai le même problème avec cette fois une infobulle qui disparait instantanément, même avec une tentative de temporisation

#troll# Hehehe c'est ça d'utiliser ce JQuery de ¤¨%!§ Smiley diablo #troll#

Si j'ai bien compris la doc JQuery de delay() le delai n'est relatif qu'a la ligne ou il est, il ne retarde pas les lignes suivantes... du coup un truc comme ça (mettre aussi un delay sur le title) règlerait peut etre le pb (au pif j'ai pas testé) :
link.on('mouseout', function(){
	$('.tooltip').fadeOut(500).delay(500).remove(); // Suppression de l'infobulle via .remove(), par contre la tempo .delay() ne marche pas dans ce cas non plus...
	link.delay(600).attr('title', title); // Réinjecter la valeur du title pour l'accessibilité
});


Après on peut aussi lire :
JQuery a écrit :
The .delay() method is best for delaying between queued jQuery effects. Because it is limited—it doesn't, for example, offer a way to cancel the delay—.delay() is not a replacement for JavaScript's native setTimeout function, which may be more appropriate for certain use cases.

Du coup tu peux aussi passer par un bon vieux setTimeout()
Modifié par _laurent (21 May 2015 - 11:52)
Modérateur
Ah bah du coup avec la mise à jour de ton post et de ton code pendant que je répondais (petit coquinou) tu devrais pouvoir mettre l'actualisation du title à coté du remove, no ?

link.on('mouseout', function(){
	var tooltip = $('.tooltip');
	tooltip.fadeOut(500, function(){
		tooltip.remove();
		link.attr('title', title); // Réinjecter la valeur du title pour l'accessibilité
	});
});
@_laurent : nous nous sommes croisé tu m'as répondu quand je rééditais mon message...
_laurent a écrit :
Si j'ai bien compris la doc JQuery de delay() le delai n'est relatif qu'a la ligne ou il est, il ne retarde pas les lignes suivantes... du coup un truc comme ça (mettre aussi un delay sur le title) règlerait peut etre le pb (au pif j'ai pas testé) :
link.on('mouseout', function(){
	$('.tooltip').fadeOut(500).delay(500).remove(); // Suppression de l'infobulle via .remove(), par contre la tempo .delay() ne marche pas dans ce cas non plus...
	link.delay(600).attr('title', title); // Réinjecter la valeur du title pour l'accessibilité
});

Oui, j'avais tenté cette solution dans mon premier post, mais ça ne marchait pas justement. Du coup je me demande si le problème n'est pas lié au fait que cette méthode soie placée dans la fonction commandée par mouseover ?
_laurent a écrit :
Du coup tu peux aussi passer par un bon vieux setTimeout()

J'avais aussi tenté un setTimeout(), mais pas mieux... Smiley bawling :
	var titleAfter = link.attr('title', title); // Réinjecter la valeur du title pour l'accessibilité
	setTimeout(titleAfter, 1000);
_laurent a écrit :
Ah bah du coup avec la mise à jour de ton post et de ton code pendant que je répondais...

Décidément...
a écrit :
tu devrais pouvoir mettre l'actualisation du title à coté du remove, no ?

Je viens de tester à l'instant... et ça ne marche pas...

EDIT : Ah si c'est bon ! Bingo ! (entre l'exemple que je vous sers en ligne et ma version locale je me suis mélangé les pinceaux Smiley confus ). La solution n'est pas parfaite car la réapparition de la valeur du title est liée à la disparition de l'infobule, soit 500ms, ce qui est peut si l'on reste pointé sur le lien, mais c'est toujours ça.

Merci à toi. Sujet résolu.
Modifié par Olivier C (21 May 2015 - 12:21)