How does Twitter implement its Tweet Box?

后端 未结 3 1337
轮回少年
轮回少年 2020-12-30 07:59

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

  • Automatically highlights text in a red background when the overall length exceeds 1
3条回答
  •  独厮守ぢ
    2020-12-30 08:45

    What I did is kind of a hack but works quite well as a workaround solution.

    I've got a simple textarea (not contenteditable because of what's next, I'll explain below) and a div which is absolute positioned behind the textarea. Using javascript, I copy the content from the textarea to the div while splitting it at 140 chars and putting all extra characters inside an tag.

    Well, it's a little bit more complicated because twitter algorithm to compute a tweet length is different (links doesn't count as their real value, because of t.co url shortening). The exact method can be found as part of the official twitter/twitter-txt repository.

    Step-by-step code.

    Wrap a simple textarea into a div to simplify the css:

    CSS is just making the textarea and the div right above each other and highlight the text.

    .tweet-composer {
      position: relative;
      z-index: 1;
    }
    
    .js-keeper-editor,
    .js-keeper-placeholder-back {
      background: transparent;
      border: 1px solid #eee;
      font-family: Helvetica, Arial, sans-serif;
      font-size: 14px; /* Same font for both. */
      margin: auto;
      min-height: 200px;
      outline: none;
      padding: 10px;
      width: 100%;
    }
    
    .js-keeper-placeholder-back {
      bottom: 0;
      color: transparent;
      left: 0;
      position: absolute;
      top: 0;
      white-space: pre-wrap;
      width: 100%;
      word-wrap: break-word;
      z-index: -1;
    }
    
    .js-keeper-placeholder-back em {
      background: #fcc !important;
    }
    

    Now the fun part, this is implemented using jQuery but that's not the important thing.

    if (0 > remainingLength) {
      // Split value if greater than 
      var allowedValuePart = currentValue.slice(0, realLength),
          refusedValuePart = currentValue.slice(realLength)
      ;
    
      // Fill the hidden div.
      $placeholderBacker.html(allowedValuePart + '' + refusedValuePart + '');
    } else {
      $placeholderBacker.html('');
    }
    

    Add some event handler on change, and te common document ready and you're done. See the codepen link below.

    Note that the div placed behind can be created using js too, when loading the page:

    // Create a pseudo-element that will be hidden behind the placeholder.
    var $placeholderBacker = $('
    '); $placeholderBacker.insertAfter($textarea);

    Full example

    See working example over here: http://codepen.io/hussard/pen/EZvaBZ

提交回复
热议问题