2010-12-15 291 views
1

Je veux essentiellement faire quelque chose de très simple: je veux que l'utilisateur tape un tweet, et après 140 caractères, je veux que le texte qui sera coupé soit grisé. Si devrait être simple, non? J'utilise la propriété contentEditable pour le formatage. Sur l'événement keyup, je vérifie si le texte est trop long et déplace les caractères supplémentaires dans un <span> si c'est le cas. Cependant, la sélection se perd en chemin.Mettre en forme l'élément Elément de contenu au moment de la frappe

J'ai déjà essayé beaucoup de choses (y compris this), mais rien n'a fonctionné - pouvez-vous m'aider? Je suppose que cela m'aiderait le plus si vous pouviez donner un exemple concret.

+0

Qu'est-ce qui n'a pas fonctionné lorsque vous avez essayé la réponse à laquelle vous étiez lié? Vous avez un exemple que nous pouvons voir? –

+0

Voici un exemple: http://jsfiddle.net/g7KJ5/ Je reçois: 'Uncaught TypeError: Impossible de lire la propriété 'previousSibling' de null' – eWolf

+0

@Tim: Ce serait vraiment génial si vous pouviez résoudre ce problème :-) – eWolf

Répondre

1

J'ai pris ça parce que j'étais intéressé. C'est énormément de code, mais c'est comme ça. Ma nouvelle version n'utilise pas saveSelection() de Rangy, mais utilise son support de gamme pour la compatibilité IE. Il est trop de code pour poster ici, donc je vais simplement créer un lien vers le jsFiddle: http://jsfiddle.net/timdown/g7KJ5/9/

+0

Merci d'avoir accepté mon problème - malheureusement, votre solution ne semble pas fonctionner correctement. Une partie de cela pourrait être causée par le retard de 500ms (est-ce vraiment nécessaire?), Mais parfois il perd juste son focus. Btw: Je vais l'utiliser pour une extension Chrome, donc la prise en charge de plusieurs navigateurs n'est pas nécessaire. – eWolf

+0

Je dois avouer que je n'étais pas vraiment content et que je ne l'avais pas testé suffisamment. Une sorte de retard est en général une bonne idée, je pense, pour éviter la lenteur en tapant. Je pourrais essayer de l'améliorer. –

+0

Jetez un oeil à la réponse que j'ai posté ci-dessous - Je l'ai résolu maintenant en utilisant une approche différente. – eWolf

0

J'ai essayé une nouvelle approche maintenant et ce que je suis venu avec:

$.fn.softlimit = function(maxChars, wrapElement, wrapAttributes) { 
    var lastHTML, that = this[0]; 

    setInterval(function() { 
     //Only trigger on change 
     if (lastHTML == that.innerHTML) return; 
     lastHTML = that.innerHTML; 

     // Save the selection 
     var savedSel = rangy.saveSelection(); 

     // Strip HTML and extract rangy markers 
     var markers = [ ], text = '', htmlPos = 0; 

     function escapeForHTML(text) { 
      return text.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('"', '&quot;'); 
     } 

     function processNode(node) { 
      if (node.nodeType == 3) 
       text += escapeForHTML(node.nodeValue); 
      else if (node.nodeName == 'SPAN' && node.id && node.id.indexOf('selectionBoundary_') === 0) 
       markers.push({ index: text.length, html: node.outerHTML }); 
      else 
       for (var i = 0; i < node.childNodes.length; ++i) 
        processNode(node.childNodes[i]); 
     } 

     processNode(that); 

     // Do formatting 
     var getOffset, markerOffset = 0; 

     if (text.length > maxChars) { 
      var startTag = '<' + wrapElement + ' ' + wrapAttributes + '>'; 
      var endTag = '</' + wrapElement + '>'; 

      text = text.substr(0, maxChars) + startTag + text.substr(maxChars) + endTag; 

      getOffset = function(index) { 
       if (index > maxChars) return startTag.length; 
       else return 0; 
      }; 
     } 
     else 
      getOffset = function() { return 0; }; 

     // Re-inject markers 
     for (var i = 0; i < markers.length; ++i) { 
      var marker = markers[i]; 
      var index = marker.index + getOffset(marker.index) + markerOffset; 

      text = text.substr(0, index) + marker.html + text.substr(index); 
      markerOffset += marker.html.length; 
     } 

     that.innerHTML = text; 

     // Restore the original selection 
     rangy.restoreSelection(savedSel); 
    }, 20); 

    return $(this); 
}; 

Merci à la baisse @ Tim indice avec les marqueurs, qui était l'indice crucial!