javascript - onmouse - Posición del cursor en píxeles en un texto de tipo de entrada(no en un área de texto)
on over javascript (7)
Usando un elemento falso invisible
Puede lograr esto mediante el uso de un elemento falso invisible absolutamente posicionado (que utiliza visibility
no se display
) que tiene todas las mismas propiedades CSS que su cuadro de texto de entrada (fuentes, bordes izquierdos y relleno izquierdo).
Este muy breve y fácil de entender JSFiddle es un punto de partida sobre cómo debería funcionar este script.
Funciona en Chrome y Firefox como es. Y parece que debería estar funcionando en IE9 + también.
Internet Explorer 8 (y abajo) necesitaría algún código adicional para obtener la posición de entrada desde el inicio del texto dentro del cuadro de texto de entrada. Incluso he agregado un medidor en la parte superior para mostrar una línea cada 10 píxeles para que pueda ver si mide correctamente o no. Tenga en cuenta que las líneas están en 1, 11, 21, ... posiciones de píxeles.
Lo que hace este ejemplo es que toma todo el texto del cuadro de texto hasta la posición de intercalación y lo coloca dentro del elemento falso y luego mide su ancho en píxeles. Esto le permite desplazarse desde la izquierda del cuadro de texto.
Cuando copia el texto en un elemento falso, también reemplaza los espacios normales por los que no se rompen, por lo que en realidad se renderizan de otra manera. Si posicionas el caret justo después del espacio, obtendrías una posición incorrecta:
var faux = $("#faux");
$("#test").on("keyup click focus", function(evt) {
// get caret offset from start
var off = this.selectionStart;
// replace spaces with non-breaking space
faux.text(this.value.substring(0, off).replace(//s/g, "/u00a0"));
});
Cuidado con las dimensiones correctas de los falsos.
- relleno
- frontera
- margen
se han eliminado para obtener el valor correcto, de lo contrario el elemento sería demasiado ancho. El cuadro del elemento tiene que terminar justo después del texto que contiene.
La posición de Caret en píxeles desde el inicio del cuadro de entrada se obtiene fácilmente desde:
faux.outerWidth();
El problema
Sin embargo, hay un problema. No estoy seguro de cómo manejar la situación cuando el texto dentro del cuadro de texto se desplaza (cuando es demasiado largo) y el cursor no está al final del texto sino en algún punto intermedio ... Si está al final, la posición del cursor siempre estará en Posibilidad máxima de posición (ancho de entrada menos dimensiones correctas - relleno, borde, margen).
¿No estoy seguro de si es posible obtener la posición de desplazamiento de texto dentro del cuadro de texto? Si puedes, entonces incluso este problema puede ser resuelto. Pero no estoy al tanto de ninguna solución a esto ...
Espero que esto ayude.
Esta pregunta ya tiene una respuesta aquí:
ACTUALIZACIÓN : duplicado de la posición del cursor o texto de Get en píxeles para el elemento de entrada .
TL; DR : utilice la biblioteca de componentes increíblemente ligera y robusta de textarea-caret-position , que ahora también es compatible con <input ype="text">
. Demostración en http://jsfiddle.net/dandv/aFPA7/
¿Hay alguna forma de saber dónde está el cursor dentro de un campo de texto HTML?
<input type=''text'' />
Me gustaría colocar en píxeles (y reposicionar) un div en función de la posición del cursor.
Nota : No quiero saber la posición en caracteres o en un
<textarea>
. Quiero saber la posición en píxeles en un elemento<input>
.
¿Qué pasa con el lienzo 2D? Tiene API para dibujar un texto de medición. Podrías usar eso. Establezca la misma fuente, tamaño de fuente y debería poder medir el ancho de la cadena desde el cuadro de texto.
$(''body'').append(''<canvas id="textCanvas" width="100px" height="100px">I/'m sorry your browser does not support the HTML5 canvas element.</canvas>'');
var canvas = document.getElementById(''textCanvas'');
var ctx = canvas.getContext(''2d'');
ctx.measureText(text);
var width = mes.width;
Utilicé este tipo de solución para adquirir el ancho de un texto para dibujarlo en WebGL. Trabajé bien, pero nunca probé lo que ocurrirá cuando el texto sea demasiado grande para el contexto del lienzo, pensé que estaría bien porque es API para medir el texto. ¡Pero sabe que deberías echarle un vistazo! :)
Al elaborar mi comentario anterior, creo que lo siguiente debería funcionar.
Para mostrar el principio, omití el formateo, por lo que el color del elemento (id = "espaciador") debe ajustarse a #FFFFFE
, quizás se #FFFFFE
algunos píxeles del espacio #FFFFFE
, etc ... pero la carretilla se moverá proporcionalmente ahora, siempre que la prueba de id y el espaciador usa la misma fuente.
Por supuesto , no sabemos la distancia en [px] tal como se nos pidió, pero podemos colocar el contenido (a carretilla en este caso) completamente en línea con el ancho de una fuente proporcional , por lo que si ese es el objetivo final (como se mencionó) en OP línea 3 ), entonces .... voi lá!
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<script type="text/javascript">
function adjust()
{
document.getElementById(''spacer'').innerHTML=document.getElementById(''test'').value;
}
</script>
<p>
<input name="test" id="test" type="text" onkeyup="adjust()" /> Test <br />
<span id="spacer"></span>^here
</p>
</body>
</html>
Actualizar:
<span id="spacer" style="color: #FFFFFF"></span>
esto hará que el espaciador sea invisible sobre un fondo blanco, pero aún no impide que el usuario resalte el texto del espaciador seleccionando el elemento span. Deja la tarea de hacer que el espaciador no sea seleccionable - aquí hay una buena solución
Heres un ejemplo de trabajo http://jsfiddle.net/gPL3f/2/
Para encontrar la posición del símbolo, conté las letras dentro de la entrada y multiplicé ese valor con el tamaño de 1 letra.
y después de eso movió el div a esa ubicación.
<html>
<head>
<style type="text/css">
body { font-size: 12px; line-height: 12px; font-family: arial;}
#box { width: 100px; height: 15px; position: absolute; top: 35px; left: 0px; background: pink;}
</style>
<script type="text/javascript" src="jquery-1.7.1.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var letter_size = 6;
$("input[type=''text'']").keyup(function(e) {
move_size = $(this).val().length * letter_size;
$(''#box'').css({''left'': move_size+''px''});
});
});
</script>
</head>
<body>
<input type="text" />
<div id="box">
/ move
</div>
</body>
<html>
ACTUALIZAR
$(document).ready(function(){
var letter_size = 6;
$("input[type=''text'']").keyup(function(e) {
$(''.hidden_for_width'').text($(this).val());
move_size = $(''.hidden_for_width'').width();
$(''#box'').css({''left'': move_size});
});
});
Se agregó un contenedor oculto en el que inserto el valor de la entrada. después de eso obtengo el ancho de ese contenedor y muevo mi DIV en consecuencia
Podría usar <span contenteditable="true"></span><input type="hidden" />
. De esa manera puede usar window.getSelection()
con getRangeAt
y getClientRects
para obtener la posición. Esto debería funcionar con la mayoría de los navegadores modernos, incluido IE9 +:
function getCaret() {
var caret = caret = {top: 0, height: 0},
sel = window.getSelection();
caret.top = 0;
caret.height = 0;
if(sel.rangeCount) {
var range = sel.getRangeAt(0);
var rects = range.getClientRects();
if (rects.length > 0) {
caret.top = rects[0].top;
caret.height = rects[0].height;
} else {
caret.top = range.startContainer.offsetTop - document.body.scrollTop;
caret.height = range.startContainer.clientHeight;
}
}
return caret;
}
(Tenga en cuenta que el proyecto del que saqué este objetivo es Mobile Safari, y usa una vista ampliable de contenido. Es posible que deba modificarlo para que se adapte a sus necesidades. Es más, a modo de demostración, cómo obtener las coordenadas X e Y).
Para IE8 e inferior, IE tiene una API propietaria para obtener la misma información.
La parte difícil es asegurarse de que su elemento solo permita texto sin formato. Específicamente con el evento pegar. Cuando el lapso pierde el foco (onblur), desea copiar el contenido en el campo oculto para que pueda publicarse.
function getCursorPosition (elem) {
var pos = 0;
if (document.selection) {
elem.focus ();
var sele = document.selection.createRange();
sele.moveStart(''character'', -elem.value.length);
pos = sele.text.length;
}
else if (elem.selectionStart || elem.selectionStart == ''0'')
pos = elem.selectionStart;
return pos;
}
getCursorPosition(document.getElementById(''textbox1''))