2010-05-07 35 views
13

Necesito implementar la tarea que es una característica bastante común para RichTextEditors - tome HTML desde el portapapeles. ¿Alguien puede ayudar con la guía sobre cómo resolver esta tarea?Obtener html desde el portapapeles en javascript

Tiene que ser multiplataforma (IE, FF, Chrome, Opera). acabo de empezar desde este código:

<script type="text/javascript"> 
    $('.historyText').live('input paste', function(e) { 

     var paste = e.clipboardData && e.clipboardData.getData ? 
     e.clipboardData.getData('text/plain') :    // Standard 
     window.clipboardData && window.clipboardData.getData ? 
     window.clipboardData.getData('Text') :     // MS 
     false; 

     alert(paste); 
    });</script> 

Tanto window.clipboardData y e.clipboardData son nulos (Chrome, Firefox).

Actualización: el usuario desea pegar el contenido del artículo desde otras ventanas del navegador, y necesito obtener etiquetas html.

+0

Ver este post [JavaScript obtener los datos del portapapeles al evento paste (navegador Cruz)] (http://stackoverflow.com/questions/2176861/javascript-get-clipboard-data-on-paste- event-cross-browser) –

+0

Posible duplicado de [JavaScript obtener datos del portapapeles en el evento de pegar (Navegador cruzado)] (https://stackoverflow.com/questions/2176861/javascript-get-clipboard-data-on-paste-event- cross-browser) – jgauffin

Respuesta

7

No podrá obtener datos del portapapeles utilizando solo JavaScript, que es la forma en que debería ser. Las versiones actuales vías de TinyMCE y CKEditor hacer esto es como sigue:

  1. detectar un evento Ctrl-V/SHIFT-ins utilizando un controlador de eventos de pulsación de tecla
  2. En ese controlador, guardar la selección del usuario actual, añadir una div elemento fuera de pantalla (digamos a la izquierda -1000px) en el documento, mueva el cursor para estar dentro de ese div, así redirigiendo efectivamente la pasta
  3. Establezca un temporizador muy breve (digamos 1 milisegundo) en el controlador de eventos para llamar a otro función que recupera el contenido HTML del div y hace el procesamiento requerido, elimina el div del documento, restaura la selección del usuario e inserta el HTML procesado.

Tenga en cuenta que esto solo funcionará para los eventos de pegado del teclado y no se pega desde el menú de contexto o edición. Para cuando se activa el evento de pegado, es demasiado tarde para redirigir el cursor al div (en algunos navegadores, al menos).

+0

Tim, tiene sentido, pero no puedo hacer el proceso que llamó "redirect paste" - Solo puedo obtener texto sin formato, no html. Necesito permitir la copia de artículos html desde el navegador para chatear. "Pasta" básica acaba de pasar la versión de texto sin etiquetas HTML – st78

+0

Hola Tim, por 'div' Supongo que querías decir, 'contenteditable div', ¿verdad? – SexyBeast

+0

@Cupidvogel: Sí, u otro elemento. Parece un trabajo de copiar y pegar por mí. –

2

En Chrome, accedo clipboardData a través del evento utilizando este código:

$(document).bind('paste', function(e) { 
    var clipboardData = e.originalEvent.clipboardData; 
}); 
14

De hecho, me he hecho mucho trabajo en esto, y acaba de escribir un nice blog post describir cómo lo hicimos en detalle Lucidchart (como un descargo de responsabilidad, trabajo en Lucidchart). Tenemos a JSFiddle que muestra copiar y pegar (probado en Firefox, Safari, Chrome e IE9 +).

El resumen de la respuesta es que deberá obtener el código HTML durante el evento de pegado del sistema. En la mayoría de los navegadores (no-IE), esto se puede hacer con algo tan simple como la siguiente:

document.addEventListener('paste', function(e) { 
    var html = e.clipboardData.getData('text/html'); 
    // Whatever you want to do with the html 
} 

El problema es cuando se desea conseguir HTML en IE. Por alguna razón, IE no hace accesibles los datos del portapapeles text/html a través de javascript. Lo que tienes que hacer es dejar que el navegador pegue en un div satisfactorio y luego obtener el html después de que el evento pegar haya terminado.

<div id="ie-clipboard-contenteditable" class="hidden" contenteditable="true"></div> 
var ieClipboardDiv = $('#ie-clipboard-contenteditable'); 

var focusIeClipboardDiv = function() { 
    ieClipboardDiv.focus(); 
    var range = document.createRange(); 
    range.selectNodeContents((ieClipboardDiv.get(0))); 
    var selection = window.getSelection(); 
    selection.removeAllRanges(); 
    selection.addRange(range); 
}; 

document.addEventListener('beforepaste', function() { 
    if (hiddenInput.is(':focus')) { 
    focusIeClipboardDiv(); 
    } 
}, true); 

document.addEventListener('paste', function(e) { 
    ieClipboardDiv.empty(); 
    setTimeout(function() { 
    var html = ieClipboardDiv.html(); 
    // Do whatever you want with the html 
    ieClipboardDiv.empty(); 
    // Return focus here 
    }, 0); 
} 
+0

Buena explicación – EasyBB

+0

¡Gracias, esto fue muy útil! Tenga en cuenta que en IE 10 y 11, todo el material extra de selección en 'focusIeClipboardDiv' parece ser innecesario. Además, ¿por qué hay un 'ieClipboardDiv.empty()' adicional en el oyente de pegar antes de 'setTimeout'? – Raman

+0

Sospecho que el material extra de selección en 'focusIeClipboardDiv' es para la operación de copia correspondiente, no para pegar. – Raman

Cuestiones relacionadas