2010-11-12 28 views
12

Tengo un div que contiene una serie de etiquetas span, cada una con una cadena de texto. Me gustaría adjuntar un evento de clic de jQuery a todos los tramos para que cuando se haga clic en el texto dentro de cualquier tramo, toda la línea de texto (dom> objeto de texto interno) se seleccionará automáticamente para facilitar el arrastre/soltar o copiar/pegar la cadena de texto.Use jQuery para seleccionar automáticamente el texto dentro de una etiqueta span al hacer clic en

Por ejemplo, el contenido de mi es ...

<div id="mySpans"> 
    <span>&nbsp;This is my text&nbsp;</span> 
    <span>&nbsp;This is my text&nbsp;</span> 
</div> 

Si se hace clic en el cursor en cualquier texto dentro de un lapso, deseo seleccionar el texto dentro de ese lapso, por lo que puede ser de arrastrar/caído (sin las etiquetas de tramo, solo el texto interno del tramo) como una copia.

¿Tiene jQuery un medio fácil para hacer esto?

EDIT: Una explicación más detallada de lo que estoy tratando de lograr:

Sin la ayuda de la escritura, con el fin de copiar un bloque de texto, el usuario tiene que seleccionar manualmente arrastre un rectángulo de selección a través del texto bloquear. El texto luego se selecciona y se indica que al hacer clic en &, el evento de arrastre recogerá todo el texto seleccionado. Así que estoy tratando de crear secuencias de comandos que permitan un solo clic en el texto para seleccionar automáticamente el texto para el usuario para que no tengan que hacerlo manualmente.

+0

Creo que, por razones de seguridad, no está permitido manipular la selección de los usuarios. Eso sería bastante malo. Sería algo así como si alguien dice "Hola", le harías decir "Quiero una pizza", aceptarlo como una orden para una pizza y dejar que pague por ello ... –

+0

@Justin, tal vez, pero yo ' Simplemente estoy simplificando para el usuario seleccionar un bloque de texto en este caso. La secuencia de comandos se está utilizando como un método abreviado para permitir que un evento de clic (que inician) complete una selección (que a muchos usuarios les resulta difícil). –

+0

@Justus, sí, pero harías eso por el lado del servidor de todos modos, dejar que el cliente * vea * te joda con su orden sería el extremo inferior de la escala 'malvada' (y el extremo más alto de la 'estúpida' 'scale) ... = b –

Respuesta

16

Derecha. La respuesta corta es: no se puede.

Eso, sin embargo, no es realmente muy útil.Por lo tanto, si usted está dispuesto a aceptar un enfoque ligeramente hacky, con al menos una advertencia, se puede:

Dado el html:

<div id="wrap"> 
    <span class="copyText">This is some text to copy.</span> 
    <span>Can't copy <em>this</em> (automatically...)!</span> 
    <span class="copyText">And this is yet more text.</span> 
</div> 

Y el CSS:

span.copyText { 
    position: relative; 
    display: block; 
} 
textarea { 
    position: absolute; 
    top: 0; 
    left: 0; 
    width: 100%; 
    height: 100%; 
    border: 0 none transparent; 
    margin: 0; 
    padding: 0; 
    outline: none; 
    resize: none; 
    overflow: hidden; 
    font-family: inherit; 
    font-size: 1em; 
} 

Usted puede utilizar el siguiente jQuery:

$(document).ready(
    function() { 
     $('.copyText').click(
      function() { 
       if ($('#tmp').length) { 
        $('#tmp').remove(); 
       } 
       var clickText = $(this).text(); 
       $('<textarea id="tmp" />') 
        .appendTo($(this)) 
        .val(clickText) 
        .focus() 
        .select(); 
     return false; 
    }); 
$(':not(.copyText)').click(
    function(){ 
     $('#tmp').remove(); 
    }); 

}); 

con el requisito JS Fiddle demo, at: http://jsfiddle.net/davidThomas/ZmYBh/.

La advertencia principal es que el elemento que desea copiar no puede (con este enfoque, al menos) con una envoltura de una línea a la siguiente (menos también es display: block), sospecho que tiene algo que ver con la forma en los elementos form nativos se representan como rectángulos "sólidos", a diferencia de la mayoría de los otros elementos inline, como html que forman un rectángulo más ... "fluido" (?) cuando se envuelve).

Puede haber otros, sin embargo.

JS Fiddle demo to show that it does work with wrapping text, so long as the parent container element (span) is still display: block;.


Editado: añadir que he intentado usar input s en lugar de textarea, que, como era previsible, no pudieron trabajar de forma diferente/mejor que textarea, y también <span contenteditable>, que (de nuevo, como era previsible) no ha seleccionado la texto en absoluto, pero insertó el símbolo de intercalación al principio del texto.

suspiro. Creo que debería haber una respuesta mucho más fácil a esta pregunta, pero no puedo verla por mi vida.

+0

Gracias David. Agradezco tu respuesta –

+0

Eres absolutamente bienvenido, sé que no es exactamente lo que querías, pero espero que haya ayudado un poco, al menos ... =/ –

+0

Me ayuda, gracias –

0

Comprobar el evento select() :)

+0

select() solo está destinado a texto- elementos de entrada ... –

+0

Bueno, en el momento en que era nuevo aquí, fue como hace dos años ... Dame un descanso: PI totalmente de acuerdo contigo aunque – tbleckert

0
$("span").click(function(){ 
var mytext = $(this).text() 
}) 

pondrá el texto en una variable javascript ... pero puede ser más rápido para echar un vistazo a jQuery UI, específicamente draggable.

+0

Creo que solo quiere que el texto se destaque para que el texto se puede copiar a través del menú contextual. No estoy seguro de que quiera asignarlo a una variable de JavaScript. –

+0

@David: Sí, se copió a través del menú contextual o se arrastró/soltó al contenido. Si se selecciona texto, generalmente se puede arrastrar automáticamente. Y dado que el objetivo es el editor de contenido de WordPress, la zona de colocación ya está preparada para arrastrar/soltar. –

+0

@David: Creo que tienes la mejor comprensión de lo que estoy tratando de hacer. ¿Alguna sugerencia? –

0

intentar algo así como

$('#mySpans span').hover(function() { 
    $(this).addClass('spanhover'); 
}, function() { 
    $(this).removeClass('spanhover'); 
}); 

donde se agrega dinámicamente un "spanhover" clase que definió en su sección de CSS como

#mySpans.spanhover {background-color:yellow;} 
+0

Creo que quiere que esté disponible como una selección de texto en el menú contextual (o lo que sea) para copiar al portapapeles; No creo que esté tratando de darle estilo. –

+0

@David: pero él escribe "... el texto será ... resaltado ...". La segunda parte escondida de la pregunta, como señaló @NimChimpsky, podría hacerse con un código ui "arrastrable". – initall

+0

David es correcto. Mala elección de palabras de mi parte.En este contexto, quiero decir seleccionado, sin estilo. –

1

tbleckert está en el camino correcto. El evento .select() solo está disponible para las entradas, por lo que necesitaría hacer que su <span> se convirtiera en una entrada y luego lo estilo sin fondo, sin bordes y sin anillo de enfoque. A continuación, se puede hacer esto:

<input type="text" style="border:none; background:transparent; outline: none;" class="selectOnClick" /> 

y luego su jQuery sería algo como esto

$('input.selectOnClick').click(function(){ $(this).select(); }); 

Este es el código no probado pero se debe apuntar en la dirección correcta.

+0

Como este código reside en un complemento que reside en el editor de WordPress y está encerrado en una etiqueta de formulario principal, ¿la apariencia de los elementos de entrada alterará el evento de publicación cuando se guarde o publique una publicación? No quiero agregar ruido al envío en ese caso. –

+0

La apariencia no debería importar y el campo debería ser editable y todo eso. – jxpx777

+0

No quiero que los campos sean editables. Son de solo lectura y solo para copiar/pegar o arrastrar/soltar en el contenido. ¿JQuery tiene un método para la selección de texto en innerText de un elemento? Eso es lo que estoy buscando aquí. –

4

encontrado esta solución core-javascript que funciona bien y es libre de intrusiones: http://coderzone.org/library/Select-text-in-a-DIV-SPAN-or-table-cell_1047.htm

he tomado la libertad de cambiar el código un poco para que se acepta el elemento nodo como argumento en lugar de un elemento ID.

// Selects text inside an element node. 
function selectElementText(el) { 
    removeTextSelections(); 
    if (document.selection) { 
     var range = document.body.createTextRange(); 
     range.moveToElementText(el); 
     range.select(); 
    } 
    else if (window.getSelection) { 
     var range = document.createRange(); 
     range.selectNode(el); 
     window.getSelection().addRange(range); 
    } 
} 

// Deselects all text in the page. 
function removeTextSelections() { 
    if (document.selection) document.selection.empty(); 
    else if (window.getSelection) window.getSelection().removeAllRanges(); 
} 
1

Yo quería hacer algo similar. Mi sitio web tiene citas que quería que los usuarios pudieran copiar fácilmente. También quería agregar el nombre del autor a la cadena.

Normalmente, yo he puesto de selección de usuario a ninguna, por lo que creó una clase que se aplica mediante programación cuando sea necesario ...

.editable { 
    user-select: text; 
    -webkit-user-select: text; 
    -moz-user-select: text; 
    -ms-user-select: text; 
    -o-user-select: text; 
} 

Todas las cotizaciones están en una clase llamada "paragraph_quote". Cuando un visitante hace clic en una cita, la secuencia de seguimiento se produce:

$(".paragraph_quote").on("click", function() { 
    var addendum = " [by Author]"; 

    if (! $(this).attr("contenteditable") || $(this).html().indexOf(addendum) === -1) {  
      $(this).removeData("quote") 
      .data("quote", $(this).html()) 
      .html($(this).html() + addendum) 
      .attr("contenteditable", true) 
      .addClass("editable") 
      .focus() 
     ; 
    } 
    document.execCommand('selectAll', false, null); 
}).on("blur", function() { 
    $(this).removeClass("editable").html($(this).data("quote")); 
}); 
  1. mirada para ver si ya se han ejecutado los siguientes pasos (es decir, si el usuario está haciendo clic por segunda vez dentro de la misma párrafo). Si es la primera vez, ejecute los pasos 2 a 7. De lo contrario, solo el paso 8.

  2. Elimine cualquier dato que pueda haberse almacenado si esta no es la primera vez que se hace clic en esta cita.

  3. Almacena el HTML de la cita como datos. Esto le permite modificar el HTML de la copia (si lo desea) y luego devolverlo fácilmente a su estado original.

  4. Agregue texto adicional (por ejemplo, el nombre del autor) al HTML. No se muestra a continuación: También uso .replace() para eliminar cualquier carácter HTML especial, como espacios sin interrupciones, guiones en em, etc.

  5. Hacer que el párrafo sea editable.

  6. Agregue la clase editable.

  7. Establezca el foco en el párrafo. La clase editable asegura la apariencia del esquema de enfoque.

  8. Seleccione todo el contenido del párrafo editable. No es que este paso sea útil, incluso si ya se tomaron los otros pasos, porque hace que la selección completa se vuelva a resaltar si el usuario hace clic dentro de la selección.

  9. Cuando el usuario hace clic fuera del párrafo, eliminar la clase editable y ...

  10. Restaurar el código HTML a su estado anterior (si ha modificado tal como se indica en el paso 4, más arriba).

Cuestiones relacionadas