2008-09-26 7 views
43

Est-il possible de surligner du texte dans une zone de texte en utilisant javascript? Vous pouvez modifier l'arrière-plan d'une partie de la zone de texte ou créer une partie du texte sélectionné?Surligner du texte à l'intérieur d'une zone de texte

+0

Je suis en train d'implémenter la partie de texte trouvé en surbrillance d'une fonction de recherche et de remplacement. – alumb

+1

[Ce lien] (http://www.sitepoint.com/life-autocomplete-textboxes/) semble vous aider à démarrer. –

Répondre

15

Essayez ce morceau de code que j'ai écrit ce matin, il mettra en évidence un ensemble défini de mots:

<html> 
    <head> 
     <title></title> 
     <!-- Load jQuery --> 
     <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script> 
     <!-- The javascript xontaining the plugin and the code to init the plugin --> 
     <script type="text/javascript"> 
      $(function() { 
       // let's init the plugin, that we called "highlight". 
       // We will highlight the words "hello" and "world", 
       // and set the input area to a widht and height of 500 and 250 respectively. 
       $("#container").highlight({ 
        words: ["hello","world"], 
        width: 500, 
        height: 250 
       }); 
      }); 

      // the plugin that would do the trick 
      (function($){ 
       $.fn.extend({ 
        highlight: function() { 
         // the main class 
         var pluginClass = function() {}; 
         // init the class 
         // Bootloader 
         pluginClass.prototype.__init = function (element) { 
          try { 
           this.element = element; 
          } catch (err) { 
           this.error(err); 
          } 
         }; 
         // centralized error handler 
         pluginClass.prototype.error = function (e) { 
          // manage error and exceptions here 
          //console.info("error!",e); 
         }; 
         // Centralized routing function 
         pluginClass.prototype.execute = function (fn, options) { 
          try { 
           options = $.extend({},options); 
           if (typeof(this[fn]) == "function") { 
            var output = this[fn].apply(this, [options]); 
           } else { 
            this.error("undefined_function"); 
           } 
          } catch (err) { 
           this.error(err); 
          } 
         }; 
         // ********************** 
         // Plugin Class starts here 
         // ********************** 
         // init the component 
         pluginClass.prototype.init = function (options) { 
          try { 
           // the element's reference ($("#container")) is stored into "this.element" 
           var scope     = this; 
           this.options    = options; 

           // just find the different elements we'll need 
           this.highlighterContainer = this.element.find('#highlighterContainer'); 
           this.inputContainer   = this.element.find('#inputContainer'); 
           this.textarea    = this.inputContainer.find('textarea'); 
           this.highlighter   = this.highlighterContainer.find('#highlighter'); 

           // apply the css 
           this.element.css('position','relative'); 

           // place both the highlight container and the textarea container 
           // on the same coordonate to superpose them. 
           this.highlighterContainer.css({ 
            'position':   'absolute', 
            'left':    '0', 
            'top':    '0', 
            'border':   '1px dashed #ff0000', 
            'width':   this.options.width, 
            'height':   this.options.height, 
            'cursor':   'text' 
           }); 
           this.inputContainer.css({ 
            'position':   'absolute', 
            'left':    '0', 
            'top':    '0', 
            'border':   '1px solid #000000' 
           }); 
           // now let's make sure the highlit div and the textarea will superpose, 
           // by applying the same font size and stuffs. 
           // the highlighter must have a white text so it will be invisible 
           this.highlighter.css({ 

            'padding':   '7px', 
            'color':   '#eeeeee', 
            'background-color': '#ffffff', 
            'margin':   '0px', 
            'font-size':  '11px', 
            'font-family':  '"lucida grande",tahoma,verdana,arial,sans-serif' 
           }); 
           // the textarea must have a transparent background so we can see the highlight div behind it 
           this.textarea.css({ 
            'background-color': 'transparent', 
            'padding':   '5px', 
            'margin':   '0px', 
            'font-size':  '11px', 
            'width':   this.options.width, 
            'height':   this.options.height, 
            'font-family':  '"lucida grande",tahoma,verdana,arial,sans-serif' 
           }); 

           // apply the hooks 
           this.highlighterContainer.bind('click', function() { 
            scope.textarea.focus(); 
           }); 
           this.textarea.bind('keyup', function() { 
            // when we type in the textarea, 
            // we want the text to be processed and re-injected into the div behind it. 
            scope.applyText($(this).val()); 
           }); 
          } catch (err) { 
           this.error(err); 
          } 
          return true; 
         }; 
         pluginClass.prototype.applyText = function (text) { 
          try { 
           var scope     = this; 

           // parse the text: 
           // replace all the line braks by <br/>, and all the double spaces by the html version &nbsp; 
           text = this.replaceAll(text,'\n','<br/>'); 
           text = this.replaceAll(text,' ','&nbsp;&nbsp;'); 

           // replace the words by a highlighted version of the words 
           for (var i=0;i<this.options.words.length;i++) { 
            text = this.replaceAll(text,this.options.words[i],'<span style="background-color: #D8DFEA;">'+this.options.words[i]+'</span>'); 
           } 

           // re-inject the processed text into the div 
           this.highlighter.html(text); 

          } catch (err) { 
           this.error(err); 
          } 
          return true; 
         }; 
         // "replace all" function 
         pluginClass.prototype.replaceAll = function(txt, replace, with_this) { 
          return txt.replace(new RegExp(replace, 'g'),with_this); 
         } 

         // don't worry about this part, it's just the required code for the plugin to hadle the methods and stuffs. Not relevant here. 
         //********************** 
         // process 
         var fn; 
         var options; 
         if (arguments.length == 0) { 
          fn = "init"; 
          options = {}; 
         } else if (arguments.length == 1 && typeof(arguments[0]) == 'object') { 
          fn = "init"; 
          options = $.extend({},arguments[0]); 
         } else { 
          fn = arguments[0]; 
          options = $.extend({},arguments[1]); 
         } 

         $.each(this, function(idx, item) { 
          // if the component is not yet existing, create it. 
          if ($(item).data('highlightPlugin') == null) { 
           $(item).data('highlightPlugin', new pluginClass()); 
           $(item).data('highlightPlugin').__init($(item)); 
          } 
          $(item).data('highlightPlugin').execute(fn, options); 
         }); 
         return this; 
        } 
       }); 

      })(jQuery); 


     </script> 
    </head> 
    <body> 

     <div id="container"> 
      <div id="highlighterContainer"> 
       <div id="highlighter"> 

       </div> 
      </div> 
      <div id="inputContainer"> 
       <textarea cols="30" rows="10"> 

       </textarea> 
      </div> 
     </div> 

    </body> 
</html> 

Cela a été écrit pour un autre poste (http://facebook.stackoverflow.com/questions/7497824/comment-souligner-amis-nom-dans-facebook-statut-mise à jour-boîte-textarea/7597420 # 7597420), mais il semble être ce que vous recherchez.

+0

Cool. Est-il possible que ce script pourrait être édité à cette chaîne au lieu de seulement les mots simples pourraient être mis en évidence? Je remarque que quand je veux mettre en évidence une phrase comme "New York Yankees", ça ne marche pas? Des idées? – Lance

0

Version améliorée d'en haut, fonctionne également avec Regex et plus textarea champs:

<html> 
    <head> 
     <title></title> 
    <!-- Load jQuery --> 
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script> 
    <!-- The javascript xontaining the plugin and the code to init the plugin --> 
    <script type="text/javascript"> 
     $(function() { 
      // let's init the plugin, that we called "highlight". 
      // We will highlight the words "hello" and "world", 
      // and set the input area to a widht and height of 500 and 250 respectively. 
      $("#container0").highlight({ 
       words: [["hello","hello"],["world","world"],["(\\[b])(.+?)(\\[/b])","$1$2$3"]], 
       width: 500, 
       height: 125, 
     count:0 
      }); 
      $("#container1").highlight({ 
       words: [["hello","hello"],["world","world"],["(\\[b])(.+?)(\\[/b])","$1$2$3"]], 
       width: 500, 
       height: 125, 
     count: 1 
      }); 
     }); 

     // the plugin that would do the trick 
     (function($){ 
      $.fn.extend({ 
       highlight: function() { 
        // the main class 
        var pluginClass = function() {}; 
        // init the class 
        // Bootloader 
        pluginClass.prototype.__init = function (element) { 
         try { 
          this.element = element; 
         } catch (err) { 
          this.error(err); 
         } 
        }; 
        // centralized error handler 
        pluginClass.prototype.error = function (e) { 
         // manage error and exceptions here 
         //console.info("error!",e); 
        }; 
        // Centralized routing function 
        pluginClass.prototype.execute = function (fn, options) { 
         try { 
          options = $.extend({},options); 
          if (typeof(this[fn]) == "function") { 
           var output = this[fn].apply(this, [options]); 
          } else { 
           this.error("undefined_function"); 
          } 
         } catch (err) { 
          this.error(err); 
         } 
        }; 
        // ********************** 
        // Plugin Class starts here 
        // ********************** 
        // init the component 
        pluginClass.prototype.init = function (options) { 
         try { 
          // the element's reference ($("#container")) is stored into "this.element" 
          var scope     = this; 
          this.options    = options; 

          // just find the different elements we'll need 

          this.highlighterContainer = this.element.find('#highlighterContainer'+this.options.count); 
          this.inputContainer   = this.element.find('#inputContainer'+this.options.count); 
          this.textarea    = this.inputContainer.find('textarea'); 
          this.highlighter   = this.highlighterContainer.find('#highlighter'+this.options.count); 

          // apply the css 
          this.element.css({'position':'relative', 
       'overflow':'auto', 
       'background':'none repeat scroll 0 0 #FFFFFF', 
       'height':this.options.height+2, 
       'width':this.options.width+19, 
       'border':'1px solid' 
       }); 

          // place both the highlight container and the textarea container 
          // on the same coordonate to superpose them. 
          this.highlighterContainer.css({ 
           'position':   'absolute', 
           'left':    '0', 
           'top':    '0', 
           'border':   '1px dashed #ff0000', 
           'width':   this.options.width, 
           'height':   this.options.height, 
           'cursor':   'text', 
       'z-index':  '1' 
          }); 
          this.inputContainer.css({ 
           'position':   'absolute', 
           'left':    '0', 
           'top':    '0', 
           'border':   '0px solid #000000', 
       'z-index':  '2', 
       'background': 'none repeat scroll 0 0 transparent' 
          }); 
          // now let's make sure the highlit div and the textarea will superpose, 
          // by applying the same font size and stuffs. 
          // the highlighter must have a white text so it will be invisible 
      var isWebKit = navigator.userAgent.indexOf("WebKit") > -1, 
      isOpera = navigator.userAgent.indexOf("Opera") > -1, 
isIE /*@cc_on = true @*/, 
isIE6 = isIE && !window.XMLHttpRequest; // Despite the variable name, this means if IE lower than v7 

if (isIE || isOpera){ 
var padding = '6px 5px'; 
} 
else { 
var padding = '5px 6px'; 
} 
          this.highlighter.css({ 
           'padding':  padding, 
           'color':   '#eeeeee', 
           'background-color': '#ffffff', 
           'margin':   '0px', 
           'font-size':  '11px' , 
           'line-height':  '12px' , 
           'font-family':  '"lucida grande",tahoma,verdana,arial,sans-serif' 
          }); 

          // the textarea must have a transparent background so we can see the highlight div behind it 
          this.textarea.css({ 
           'background-color': 'transparent', 
           'padding':   '5px', 
           'margin':   '0px', 
           'width':   this.options.width, 
           'height':   this.options.height, 
           'font-size':  '11px', 
           'line-height':  '12px' , 
           'font-family':  '"lucida grande",tahoma,verdana,arial,sans-serif', 
       'overflow':  'hidden', 
           'border':   '0px solid #000000' 
          }); 

          // apply the hooks 
          this.highlighterContainer.bind('click', function() { 
           scope.textarea.focus(); 
          }); 
          this.textarea.bind('keyup', function() { 
           // when we type in the textarea, 
           // we want the text to be processed and re-injected into the div behind it. 
           scope.applyText($(this).val()); 
          }); 

      scope.applyText(this.textarea.val()); 

         } catch (err) { 
      this.error(err) 
         } 
         return true; 
        }; 
        pluginClass.prototype.applyText = function (text) { 
         try { 
          var scope     = this; 

          // parse the text: 
          // replace all the line braks by <br/>, and all the double spaces by the html version &nbsp; 
          text = this.replaceAll(text,'\n','<br/>'); 
          text = this.replaceAll(text,' ','&nbsp;&nbsp;'); 
          text = this.replaceAll(text,' ','&nbsp;'); 

          // replace the words by a highlighted version of the words 
          for (var i=0;i<this.options.words.length;i++) { 
           text = this.replaceAll(text,this.options.words[i][0],'<span style="background-color: #D8DFEA;">'+this.options.words[i][1]+'</span>'); 
           //text = this.replaceAll(text,'(\\[b])(.+?)(\\[/b])','<span style="font-weight:bold;background-color: #D8DFEA;">$1$2$3</span>'); 
          } 

          // re-inject the processed text into the div 
          this.highlighter.html(text); 
      if (this.highlighter[0].clientHeight > this.options.height) { 
       // document.getElementById("highlighter0") 
       this.textarea[0].style.height=this.highlighter[0].clientHeight +19+"px"; 
      } 
      else { 
       this.textarea[0].style.height=this.options.height; 
      } 

         } catch (err) { 
          this.error(err); 
         } 
         return true; 
        }; 
        // "replace all" function 
        pluginClass.prototype.replaceAll = function(txt, replace, with_this) { 
         return txt.replace(new RegExp(replace, 'g'),with_this); 
        } 

        // don't worry about this part, it's just the required code for the plugin to hadle the methods and stuffs. Not relevant here. 
        //********************** 
        // process 
        var fn; 
        var options; 
        if (arguments.length == 0) { 
         fn = "init"; 
         options = {}; 
        } else if (arguments.length == 1 && typeof(arguments[0]) == 'object') { 
         fn = "init"; 
         options = $.extend({},arguments[0]); 
        } else { 
         fn = arguments[0]; 
         options = $.extend({},arguments[1]); 
        } 

        $.each(this, function(idx, item) { 
         // if the component is not yet existing, create it. 
         if ($(item).data('highlightPlugin') == null) { 
          $(item).data('highlightPlugin', new pluginClass()); 
          $(item).data('highlightPlugin').__init($(item)); 
         } 
         $(item).data('highlightPlugin').execute(fn, options); 
        }); 
        return this; 
       } 
      }); 

     })(jQuery); 


    </script> 
</head> 
<body> 

    <div id="container0"> 
     <div id="highlighterContainer0"> 
      <div id="highlighter0"></div> 
     </div> 
     <div id="inputContainer0"> 
      <textarea id="text1" cols="30" rows="15">hello world</textarea> 
     </div> 
    </div> 
<h1> haus </h1> 
    <div id="container1"> 
     <div id="highlighterContainer1"> 
      <div id="highlighter1"></div> 
     </div> 
     <div id="inputContainer1"> 
      <textarea cols="30" rows="15">hipp hipp 
hurra, 
[b]ich hab es jetzt![/b]</textarea> 
     </div> 
    </div> 

</body> 

+0

Serait plus agréable d'avoir ceci dans un violon ou un sthing similaire. –

3

scénario facile je l'ai écrit pour cela: Jsfiddle

OPTIONS:

  1. Compteur de caractères optionnel.
  2. Mettez en surbrillance plusieurs motifs avec des couleurs différentes.
  3. Regex.
  4. Collecte des correspondances avec d'autres conteneurs.
  5. Style facile: polices de couleur et de visage, arrière-plans, rayon de bordure et hauteur de ligne.
  6. Ctrl + Maj pour le changement de direction.

    //include function like in the fiddle! 
    
    //CREATE ELEMENT: 
    
    create_bind_textarea_highlight({ 
        eleId:"wrap_all_highlighter", 
        width:400, 
        height:110, 
        padding:5, 
        background:'white', 
        backgroundControls:'#585858', 
        radius:5, 
        fontFamilly:'Arial', 
        fontSize:13, 
        lineHeight:18, 
        counterlettres:true, 
        counterFont:'red', 
        matchpatterns:[["(#[0-9A-Za-z]{0,})","$1"],["(@[0-9A-Za-z]{0,})","$1"]], 
        hightlightsColor:['#00d2ff','#FFBF00'], 
        objectsCopy:["copy_hashes","copy_at"] 
        //PRESS Ctrl + SHIFT for direction swip! 
        }); 
    
    //HTML EXAMPLE: 
    <div id="wrap_all_highlighter" placer='1'></div> 
    <div id='copy_hashes'></div><!--Optional--> 
    <div id='copy_at'></div><!--Optional--> 
    

Have Fun!

+0

c'est bien, mais que se passe-t-il si l'utilisateur entre le prénom et le nom – user1851420

Questions connexes