11521 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

Sur cette portion de page vous voyez des blocks de codes disposants chacun d'un bouton permettant de sélectionner le texte.

Mon problème c'est que les boutons sélectionnent tous le dernier block, et non pas leur block adjacent.

Voici mon code jQuery :
jQuery.fn.selectText = function(){
	var element = this[0],
		doc = document.body;
	if (doc.createTextRange) {
		range = doc.createTextRange();
		range.moveToElementText(element);
		range.select();
	} else if (window.getSelection) {
		selection = window.getSelection();
		range = document.createRange();
		range.selectNodeContents(element);
		selection.removeAllRanges();
		selection.addRange(range);
	}
};

jQuery('pre code').each(function(){ // Création du bouton de commande
	var code = $(this);
	code.parent().css('position', 'relative')
		.prepend('<button class="button select">Select</button>');
	var button = $('.select');
	button.css({ //@todo À mettre dans la feuille de style ?
		'position': 'absolute',
		'z-index': '100',
		'right': '0',
		'width': 'inherit', // contrebalance une règle css par défaut
		'font-size': '50%'
	});
	button.on('click', function(){ // Fonction du bouton
		code.selectText();
	});
});

Le plugin, ce n'est pas moi qui l'ai codé, je l'ai trouvé sur stackoverflow. Je me suis dis que mon problème pouvait provenir de this[0], mais je n'arrive pas à adapter le truc afin qu'il sélectionne le block adjacent au bouton.

Merci de votre aide.
Modérateur
Salut,

Ta fonction est mal ajoutée au bouton. Je dirais même plus, c'est ton sélecteur qui foire tout
var button = $('.select');

est dans un .each() ce qui fait qu'a la premiere occurence la variable button contiendra le premier bouton et lui attache la fonction pour sélectionner le premier code. Jusque là Ok.
Seconde occurence du each, la variable button, avec ce sélecteur, contient les deux boutons créés et va coller à ces 2 boutons la fonction pour sélectionner le code 2.
Troisieme occurence du each, la variable button, avec ce sélecteur, contient les trois boutons créés et va coller à ces 3 boutons la fonction pour sélectionner le code 3.
etc.

Du coup si tu as 3 éléments, si tu clique sur le premier il y a 3 fonctions qui ont été attaché et qui vont être exécutées pour les 3 codes et donc finir par le dernier.

Il faut donc revoir ton sélecteur pour qu'il prenne le bouton tout juste créé et non pas tout les ".select"

Un simple console.log de tes variables t'aurait montré les multiples exécutions Smiley smile pense à les vérifier quand tu débug !

Bonne journée
Modifié par _laurent (08 Jul 2015 - 14:08)
Bingo ! Merci _laurent.

Voici le sélecteur final :
var button = $(this).parent().find('.select');


Sujet résolu.
Bonjour,

Je sais que j'arrive après la guerre, mais je pense que tu perds tout l'intérêt du on() de jQuery qui permet de faire de la délégation et en gros de coller l'événement qu'une fois (bien meilleur au niveau des performances).

Voici ce que j'aurais fait :
$('pre code').each(function(){ // Création du bouton de commande
  $(this).prepend('<button class="button select">Select</button>');
  // DO : le css dans le css ! XD
})

$('body').on('click', 'button.select', function(){
  $(this).next().selectText()
})

À noter le next() de jQuery, qui te permet de chopper l'élément après ton bouton plus facilement.
SolidSnake a écrit :
Je sais que j'arrive après la guerre...

Pas vraiment...

En effet, là, je suis en vacances, mais je continue à consulter le forum via mon portable. Merci beaucoup pour ton intervention qui m'intéresse beaucoup, je mettrai tes conseils en application à mon retour.