geeky stuff: como sublinhar algumas palavras numa página

Uma funcionalidade muito interessante que o GMail tem é, quando fazemos uma pesquisa, sublinhar depois no mail a palavra que procuramos. Em principio isto deverá permitir que o utilizar direccione mais rapidamente a sua atenção para o pedaço de texto que realmente interessa.

(rever os artigos “F-Shaped Pattern For Reading Web Content” e “Top Ten Mistakes in Web Design” de Jakob Nielsen)

Como a aplicação que estou a desenvolver é, a nivel de conceito pelo menos, um motor de pesquisa achei que fazia todo o sentido usar algo do género. O meu cenário é o seguinte, tenho uma página onde vou pondo uns filtros e a dado momento quero ver o resultado da pesquisa por esses filtros. Na página que mostra esse resultado estou quero então, de alguma forma, destacar as palavras que usei como filtro.

Como estou a usar intensamente o jQuery (que como já disseram “Puts the Fun Back into Browser Scripting“) procurei um plugin que já fizesse isso. Encontrei alguns e estou a usar o “Higlighting jQuery plugin” que faz quase tudo o que queria.

Tive que fazer 3 alterações:

  • o código original tinha um if inicial com código diferente para IE e para os outros browsers mas por alguma razão no IE a função não se limitava ao contexto definido na chamada da função (por exemplo um div) e fazia o highlight da palavra em todo o documento. Optei pela solução radical de comentar esse código e usar só a parte para os outros browsers mas que funciona também em IE;
  • o código original seleccionava todas as instâncias da string que nós indicassemos, por exemplo se dissesse para fazer o highlight de palavra “joão” essa função ia seleccionar quer a palavra joão quer todas as outras variações sobre essa palavra. como não era esse o meu objectivo acrescentei um novo parâmetro chamado “exactValue” para destacar só as palavras que fossem exactamente iguais à palavra indicada;
  • finalmente esta função obrigava à existência de uma css classe chamada highlight e tinha esse nome hard-coded. como não me dava muito jeito acrescentei um novo parâmetro opcional com o nome da classe que queremos usar.

O código final que estou a utilizar e que enviei ao autor original é o seguinte:

/*

highlight v2

Highlights arbitrary terms.



MIT license.

Johann Burkard



*/

$(function() {
/* jQuery.highlight = document.body.createTextRange ? */
jQuery.highlight =
/*
 (Complicated) version for Mozilla and Opera using span tags.
*/
  function(node, te, exactValue, className) {
   var pos, skip, spannode, middlebit, endbit, middleclone;
   if (className == undefined) className = 'highlight';
   if (exactValue == undefined) exactValue = false;
   skip = 0;
   if (node.nodeType == 3) {
    pos = node.data.toUpperCase().indexOf(te.toUpperCase());
    if ((pos >= 0) &&
		(exactValue ?  $.trim(node.data.toUpperCase()) == $.trim(te.toUpperCase()) : true) ) {
     spannode = document.createElement('span');
     spannode.className = className;
     middlebit = node.splitText(pos);
     endbit = middlebit.splitText(te.length);
     middleclone = middlebit.cloneNode(true);
     spannode.appendChild(middleclone);
     middlebit.parentNode.replaceChild(spannode, middlebit);
     skip = 1;
    }
   }
   else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) {
    for (var i = 0; i < node.childNodes.length; ++i) {
     i += $.highlight(node.childNodes[i], te, exactValue, className);
    }
   }
   return skip;
  }

 ;
});

jQuery.fn.removeHighlight = function(className) {
 if (className == undefined) className = 'highlight';
 this.find("span." + className).each(function() {
  with (this.parentNode) {
   replaceChild(this.firstChild, this);
   normalize();
  }
 });
 return this;
};

por Vitor Silva



Leave a Reply