web-dev-qa-db-fra.com

La meilleure façon de créer un lien en utilisant JQuery?

Nous utilisons des formateurs personnalisés jqGrid pour générer des liens dans nos grilles JQuery. Nous construisons simplement les liens en utilisant la manipulation de chaîne à la:

var s = "<a title=\"Blah\" href=\"javascript:BlahFunc('" + options.rowId + "')\">This is blah<a>";

Existe-t-il un moyen plus "intelligent" de créer des liens (et d'autres éléments de formulaire) à l'aide de JQuery?

23
Marcus Leon

Comme Steven Xu l'a correctement mentionné, l'insertion de chaînes HTML est plus rapide que la manipulation du DOM, c'est pourquoi je recommanderais de créer des éléments avec une manipulation de chaîne au lieu de jQuery.

Vous avez seulement besoin de changer cela:

var s = "<a title=\"Blah\" href=\"javascript:BlahFunc('" + options.rowId +
        "')\">This is blah<a>";

pour ça:

var s = "<a title=\"Blah\" href=\"javascript:BlahFunc('" + options.rowId +
        "')\">This is blah</a>";

(fermez la balise <a> avec </a> à la fin de la chaîne).

La manipulation des chaînes est beaucoup plus rapide que la manipulation DOM (voir this par exemple). De plus, la différence sera bien plus grande si vous essayez d'insérer un fragment DOM au milieu d'un gros code HTML. L'utilisation de DOM DocumentFragments peut un peu améliorer les performances, mais l'utilisation de la concaténation de chaînes est le moyen le plus rapide.

Toutes les autres réponses ont écrit sa réponse sans connaître le contexte (formateur personnalisé jqGrid) où vous l'utilisez. J'essaie d'expliquer pourquoi c'est important dans votre cas.

En raison des avantages en termes de performances, jqGrid crée d'abord des fragments de code HTML pour la grille en tant que tableau de chaînes, puis crée une chaîne à partir du tableau de chaînes en respectant .join('') et insère le résultat dans le corps du tableau à la fin de tout seulement. (Je suppose que vous utilisez gridview: true jqGrid option qui est presque toujours recommandée). Le formateur personnalisé jqGrid est une fonction de rappel utilisée par jqGrid lors de la construction du corps de la grille (table). Le formateur personnalisé doit renvoyer le fragment de code HTML sous la forme de la chaîne . La chaîne sera concaténée avec d'autres chaînes qui construisent le corps de la grille (tableau).

Donc, si vous changez votre code actuel de la manipulation de chaîne pure en manipulation DOM DOM et que vous convertissez les résultats en chaîne (qui devait être renvoyée à la suite du formatage personnalisé), votre code fonctionnera lentement et vous n'aurez aucun autre avantage *.

Le seul inconvénient réel de l'utilisation des manipulations de chaînes est le problème de la vérification du code que vous construisez. Par exemple, l'utilisation de code sans les balises de fermeture </a> Est un problème potentiel que vous pouvez avoir. Dans la plupart des cas, le problème sera résolu lors de l'insertion du fragment DOM, mais parfois vous pouvez recevoir de vrais problèmes. Vous devez donc simplement tester le code que vous avez inséré très attentivement.

Encore une remarque: si vous voulez suivre style JavaScript discret vous pouvez utiliser "#" comme valeur pour l'attribut href et lier l'événement click correspondant à l'intérieur de gridComplete ou loadComplete gestionnaire d'événements. Si vous rencontrez des problèmes avec l'implémentation de ceci, vous pouvez ouvrir une nouvelle question et j'essaierai d'écrire l'exemple de code correspondant pour vous.

Remarque: Je pense que la meilleure façon d'implémentation sera d'utiliser onCellSelect ou beforeSelectRow au lieu de lier click événement à chaque élément <a> De la colonne. Je recommande de lire les réponses suivantes pour plus de détails: celui-ci , n autre et ne autre vieille réponse .

15
Oleg

Je trouve le meilleur pour être

$('<a>',{
    text: 'This is blah',
    title: 'Blah',
    href: '#',
    click: function(){ BlahFunc( options.rowId );return false;}
}).appendTo('body');

Exemple en direct sur http://www.jsfiddle.net/gaby/RhWgf/

J'ai remplacé le javascript en ligne par un gestionnaire attaché

Citation de la documentation sur jQuery ()

jQuery ( html, accessoires)

html Une chaîne définissant un seul, autonome, [ ~ # ~] html [~ # ~] élément (par exemple <div/> ou <div></div>).
accessoires Une carte d'attributs, d'événements et de méthodes pour appeler l'élément nouvellement créé .


Mise à jour

Si vous voulez le texte réel du lien, vous devez l'envelopper dans un div et renvoyer la .html() de cela.

( alternativement: vous pouvez utiliser l'accès à la propriété .outerHTML de l'élément brut)

Exemple complet sur http://www.jsfiddle.net/gaby/RhWgf/1/ ( supprimé le gestionnaire de clics, car il se perdrait dans une version chaîne, et le remplaçait par un gestionnaire live qui cible le type spécifique de liens)

99
Gabriele Petrioli
jQuery('<a>').attr('href', 'url').text('blah')

Fera un objet jquery et vous pouvez ensuite simplement l'ajouter au dom avec .append.

11
shoebox639

Ma façon préférée est la suivante:

$("<a>", {
  title: "Blah",
  href: "javascript:BlahFunc('" + options.rowId + "')"
  }).append( "This is blah" );

Il y a de bonnes informations dans cet article:
http://marcgrabanski.com/articles/building-html-in-jquery-and-javascript

8
TJB

En général, l'insertion d'une chaîne HTML est plus rapide et plusieurs injections DOM et manipulations DOM, ce à quoi cette manipulation DOM jQuery revient. Si vous souhaitez en insérer 500, la meilleure option, en termes de performances, serait de préparer la chaîne HTML, puis d'ajouter le code HTML.

Mais pour vos besoins simples, votre option actuelle vous conviendra très bien. Pour plus intelligent, vous pouvez utiliser la bibliothèque de manipulation DOM de jQuery sur vos nouveaux éléments. L'exemple ci-dessous devrait être explicite, mais si je n'ai pas été clair dans un cas particulier, laissez un commentaire et je vous aiderai.

var toBeAdded = [
  { title: "one", row: 1, content: "ONE" },
  { title: "two", row: 2, content: "TWO" },
  { title: "three", row: 3, content: "THREE" }
];

var s = toBeAdded.length;
for(i=0;i<s;i++) {
  var a = $('<a>');
  a.attr('title', toBeAdded[i].title);
  a.attr('rel', toBeAdded[i].row);
  a.text(toBeAdded[i].content);
  a.addClass('blah_class');
  a.appendTo($('body'));
}

Et puis dans votre script universel:

$('a.blah_class').live('click', function(){
  var rel = $(this).attr('rel');
  BlahFunc(rel);
});
1
Steven