miércoles, 31 de octubre de 2012

JavaScript: Copiar y Resaltar (Copy & Highlight)

Como parte de mis disciplina de documentar funcionalidades que me sacan canas, esta vez dejo a disposición un pequeño código que ejemplifica como hacer un copiado/pegado de un elemento del DOM y a su vez dejarlo seleccionado/resaltado.

Para el copy/paste utilizo una librería popular en la web que utiliza un archivo Flash como intermediario de la operación: ZeroClipboard. Para la selección encontré un código que funciona adecuadamente en los principales browsers (IE, FF y Chrome). En el código de abajo son las funciones "getTextNodesIn" y "setSelectionRange". Cuando se carga este código en el browser, el usuario puede hacer clic en el texto y automáticamente se copia mostrando a su vez un mensaje de alerta, para después dejarlo seleccionado.

<html>
<head>
<script type="text/javascript" src="ZeroClipboard.min.js"></script>  
<script type="text/javascript">
 function getTextNodesIn(node) {
  var textNodes = [];
  if (node.nodeType == 3) {
   textNodes.push(node);
  } else {
   var children = node.childNodes;
   for (var i = 0, len = children.length; i < len; ++i) {
    textNodes.push.apply(textNodes, getTextNodesIn(children[i]));
   }
  }
  return textNodes;
 }

 function setSelectionRange(el, start, end) {
  if (document.createRange && window.getSelection) {
   var range = document.createRange();
   range.selectNodeContents(el);
   var textNodes = getTextNodesIn(el);
   var foundStart = false;
   var charCount = 0, endCharCount;

   for (var i = 0, textNode; textNode = textNodes[i++]; ) {
    endCharCount = charCount + textNode.length;
    if (!foundStart && start >= charCount
      && (start < endCharCount ||
      (start == endCharCount && i < textNodes.length))) {
     range.setStart(textNode, start - charCount);
     foundStart = true;
    }
    if (foundStart && end <= endCharCount) {
     range.setEnd(textNode, end - charCount);
     break;
    }
    charCount = endCharCount;
   }

   var sel = window.getSelection();
   sel.removeAllRanges();
   sel.addRange(range);
  } else if (document.selection && document.body.createTextRange) {
   var textRange = document.body.createTextRange();
   textRange.moveToElementText(el);
   textRange.collapse(true);
   textRange.moveEnd("character", end);
   textRange.moveStart("character", start);
   textRange.select();
  }
 }

 function highlight() {
  var element = document.getElementById("span_id");
  setSelectionRange(element, 0, element.innerHTML.length); 
  alert("copied!");
 }

</script>
</head>
<body>
 <span id="span_id">Copy Me!</span>
 <script>
  ZeroClipboard.setMoviePath( 'ZeroClipboard.swf' );
  var clip = new ZeroClipboard.Client();
  var element = document.getElementById("span_id");
  clip.setText( element.innerHTML )
  clip.glue( 'span_id' ); 
  clip.addEventListener( 'onMouseUp', highlight );
 </script>
</html>
</body>


No hay comentarios:

Publicar un comentario