lundi 2 mars 2015

How does Twitter implement its Tweet Box?


I'm trying to implement something like Twitter's tweet box, specifically:



  • Automatically highlights text in a red background when the overall length exceeds 140 characters.

  • Automatically highlights links, mentions, and hashtags in blue.


These should happen automatically aka when a user types.


By the semantic markup I'm seeing on Twitter, it looks like they're using a contentEditable div. And the DOM inside is modified whenever a mention/hashtag/link is detected, or when the length is exceeded over 140 characters:



<div aria-labelledby="tweet-box-mini-home-profile-label" id="tweet-box-mini-home-profile" class="tweet-box rich-editor notie" contenteditable="true" spellcheck="true" role="textbox" aria-multiline="true" dir="ltr" aria-autocomplete="list" aria-expanded="false" aria-owns="typeahead-dropdown-6">
<div>hello world <a class="twitter-atreply pretty-link" href="/testMention" role="presentation"><s>@</s>testMention</a> text <a href="/search?q=%23helloWorld" class="twitter-hashtag pretty-link" role="presentation"><s>#</s>helloWorld</a> text <a href="http://www.google.com" class="twitter-timeline-link" role="presentation">http://ift.tt/19KruvX; text text text text text text text text text text text text text text <em>overflow red text here</em>
</div>
</div>


What I have done so far


Currently, I'm using a contentEditable field. It triggers a function onChange/onInput that parses the text. Check if it has a username/link/hashtag via regexr and replace them with the respective tags (I'm just using a simple <i> tag to enclose username and hashtag for now). The problem I'm having is that because I'm changing/modifying the DOM of the contentEditable, the caret cursor position becomes lost. I looked at this thread Persisting the changes of range objects after selection in HTML and it works fine only if the DOM isn't changed (which it is in my case, surrounding tags/hashtags with <i> tags, links with <a> tags, and overflow with <b> tags.


Fiddle: http://ift.tt/1DypUvr


Does anyone have any alternative solutions/approaches on how to tackle this problem? Maybe I shouldn't use contentEditable? Or some way that doesn't directly modify the DOM of the contentEditable field so the caret position is maintained? Any help would be appreciated! I tried playing around with window.getSelection() and saving it before DOM change, but it always seem to reset after DOM changes are applied.





Aucun commentaire:

Enregistrer un commentaire