jQuery convertit les sauts de ligne en br (équivalent nl2br)


109

Je demande à jQuery de prendre du contenu textarea et de l'insérer dans un li.

Je veux qu'il conserve visuellement les sauts de ligne.

Il doit y avoir un moyen très simple de faire cela ...


Remarque XSS: Si vous faites cela, il semble que vous mélangiez directement les entrées de l'utilisateur et celles de <br/>, ce qui signifie que vous affichez des nouvelles lignes ou des <br/s>, et que vous pouvez donc être ouvert à une attaque XSS , c'est-à-dire si votre contribution provient d'un autre utilisateur du site.
user420667

Réponses:


163

démo: http://so.devilmaycode.it/jquery-convert-line-breaks-to-br-nl2br-equivalent

function nl2br (str, is_xhtml) {   
    var breakTag = (is_xhtml || typeof is_xhtml === 'undefined') ? '<br />' : '<br>';    
    return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1'+ breakTag +'$2');
}

5
Merci cela fonctionne parfaitement. Bizarre comment ce n'est pas une fonction officielle de jQuery.
gbhall

4
car jQuery n'est pas destiné à remplacer la fonction javascript native comme replace, il se concentre sur le chaînage des sélecteurs CSS et un accès facile! peut-être dans la future version ;-)
Luca Filosofi

Impressionnant. M'a aidé à surmonter le problème avec IE7 ne prenant pas en charge les espaces blancs: pré-wrap
Kevin Pauli

Cette expression régulière ne signifierait-elle pas que si une ligne se termine par ">", elle n'ajouterait pas le BR? Je sais que dans mon HTML, j'utilise & gt; mais le contenu généré par l'utilisateur ne fonctionne pas si bien avec ça ...
Dave Stein

@DaveStein non j'ai essayé ceci avec les deux '>' et '& gt;' et les deux fois les sauts de ligne sont ajoutés. Je pense que ce code de fonction est fondamentalement parfait :)
Jake

91

vous pouvez simplement faire:

textAreaContent=textAreaContent.replace(/\n/g,"<br>");

Bravo, ce genre de travail a fonctionné, sauf qu'il traiterait plusieurs sauts de ligne comme un seul saut de ligne.
gbhall

4
Je l'ai mis à jour et maintenant il utilise une expression régulière, donc si vous voulez traiter plusieurs sauts de ligne comme un seul br, changez l'expression rationnelle avec: / \ n + / g
mck89

Je vous remercie. J'espère que quelqu'un trouvera votre réponse utile, mais la fonction ci-dessous fonctionne également. Je me sens un peu mal que vous fassiez plus d'efforts, mais une fonction est plus souhaitable.
gbhall

si vous obtenez l'erreur "x.replace n'est pas une fonction", utilisez x.toString (). replace
Vörös Amadea

29

Mettez ceci dans votre code (de préférence dans une bibliothèque de fonctions js générale):

String.prototype.nl2br = function()
{
    return this.replace(/\n/g, "<br />");
}

Usage:

var myString = "test\ntest2";

myString.nl2br();

la création d'une fonction prototype de chaîne vous permet de l'utiliser sur n'importe quelle chaîne.


29

Dans l'esprit de changer le rendu au lieu de changer le contenu , le CSS suivant fait que chaque nouvelle ligne se comporte comme un<br> :

white-space: pre;
white-space: pre-line;

Pourquoi deux règles: pre-linen'affecte que les nouvelles lignes (merci pour l'indice, @KevinPauli). IE6-7 et d'autres anciens navigateurs reviennent au plus extrême prequi inclut nowrapet rend également plusieurs espaces. Détails sur ces paramètres et d'autres ( pre-wrap) sur mozilla et css-tricks (merci @Sablefoste).

Bien que je sois généralement opposé à la prédilection SO pour remettre en question la question plutôt que d'y répondre, dans ce cas, le remplacement des nouvelles lignes par du <br>balisage peut augmenter la vulnérabilité aux attaques par injection avec une entrée utilisateur non lavée. Vous franchissez une ligne rouge vif chaque fois que vous vous trouvez en train de changer d' .text()appels .html()auxquels la question littérale implique qu'il faudrait faire. (Merci @AlexS d'avoir souligné ce point.) Même si vous excluez un risque de sécurité à ce moment-là, des changements futurs pourraient l'introduire involontairement. Au lieu de cela, ce CSS vous permet d'obtenir des sauts de ligne durs sans balisage en utilisant le plus sûr .text().


1
Selon le cas, c'est la solution la plus simple et répond vraiment le mieux à la question. Vous pouvez également envisager l'une des autres white-space:options, telles que pre-wrap. Voir css-tricks.com/almanac/properties/w/whitespace
Sablefoste

C'est vraiment la meilleure réponse - des solutions de remplacement de chaîne signifieraient la nécessité d'utiliser .html()pour définir le contenu, ce qui permettrait à l'utilisateur d'insérer du HTML arbitraire à moins que vous ne le filtriez à l'avance.
Alex S

Bon point sur le .html()danger @AlexS, a essayé d'incorporer.
Bob Stein

2

Solution

Utilisez ce code

jQuery.nl2br = function(varTest){
  return varTest.replace(/(\r\n|\n\r|\r|\n)/g, "<br>");
};

1

Cette fonction JavaScript considère s'il faut utiliser l'insertion ou le remplacement pour gérer le swap.

(Insérer ou remplacer des sauts de ligne HTML)

/**
 * This function is same as PHP's nl2br() with default parameters.
 *
 * @param {string} str Input text
 * @param {boolean} replaceMode Use replace instead of insert
 * @param {boolean} isXhtml Use XHTML 
 * @return {string} Filtered text
 */
function nl2br (str, replaceMode, isXhtml) {

  var breakTag = (isXhtml) ? '<br />' : '<br>';
  var replaceStr = (replaceMode) ? '$1'+ breakTag : '$1'+ breakTag +'$2';
  return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, replaceStr);
}

Démo - JSFiddle

Fonctions JavaScript nl2br et br2nl


1

J'ai écrit une petite extension jQuery pour cela:

$.fn.nl2brText = function (sText) {
    var bReturnValue = 'undefined' == typeof sText;
    if(bReturnValue) {
        sText = $('<pre>').html(this.html().replace(/<br[^>]*>/i, '\n')).text();
    }
    var aElms = [];
    sText.split(/\r\n|\r|\n/).forEach(function(sSubstring) {
        if(aElms.length) {
            aElms.push(document.createElement('br'));
        }
        aElms.push(document.createTextNode(sSubstring));
    });
    var $aElms = $(aElms);
    if(bReturnValue) {
        return $aElms;
    }
    return this.empty().append($aElms);
};

0

pour améliorer la réponse acceptée de @Luca Filosofi,

si nécessaire, changer la clause de début de cette expression rationnelle en /([^>[\s]?\r\n]?)sera également intégrer les cas où le retour à la ligne vient après une balise ET des espaces, au lieu d'une simple balise immédiatement suivie d'une nouvelle ligne


0

Une autre façon d'insérer du texte à partir d'une zone de texte dans le DOM en conservant les sauts de ligne consiste à utiliser la propriété Node.innerText qui représente le contenu du texte rendu d'un nœud et de ses descendants.

En tant que getter, il se rapproche du texte que l'utilisateur obtiendrait s'il mettait en évidence le contenu de l'élément avec le curseur, puis copié dans le presse-papiers.

La propriété est devenue la norme en 2016 et est bien prise en charge par les navigateurs modernes. Puis-je utiliser : une couverture mondiale de 97% lorsque j'ai publié cette réponse.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.