internet habilitar google funciona cómo chrome activar javascript jquery firefox google-chrome

javascript - habilitar - no funciona jquery en internet explorer 11



Obtener la posición del cursor o el texto en píxeles para el elemento de entrada (4)

IE me permite crear un rango de texto en un elemento de entrada, sobre el que puedo llamar a getBoundingClientRect() y obtener la posición en píxeles de un determinado carácter o el cursor / caret. ¿Hay alguna forma de obtener la posición de un determinado personaje en píxeles en otros navegadores?

var input = $("#myInput")[0]; var pixelPosition = null; if (input.createTextRange) { var range = input.createTextRange(); range.moveStart("character", 6); pixelPosition = range.getBoundingClientRect(); } else { // Is there any way to create a range on an input''s value? }

Estoy usando jQuery, pero dudo que pueda abordar mi situación. Espero una solución JavaScript pura, si la hay, pero las respuestas de jQuery son bienvenidas.


Terminé creando una entrada simulada oculta a partir de un tramo posicionado absolutamente y con un estilo similar al de la entrada. Establecí el texto de ese intervalo en el valor de la entrada hasta el carácter cuya posición quiero encontrar. Inserto el tramo antes de la entrada y obtengo su desplazamiento:

function getInputTextPosition(input, charOffset) { var pixelPosition = null; if (input.createTextRange) { var range = input.createTextRange(); range.moveStart("character", charOffset); pixelPosition = range.getBoundingClientRect(); } else { var text = input.value.substr(0, charOffset).replace(/ $/, "/xa0"); var sizer = $("#sizer").insertBefore(input).text(text); pixelPosition = sizer.offset(); pixelPosition.left += sizer.width(); if (!text) sizer.text("."); // for computing height. An empty span returns 0 pixelPosition.bottom = pixelPosition.top + sizer.height(); } return pixelPosition }

El css para mi sizer span:

#sizer { position: absolute; display: inline-block; visibility: hidden; margin: 3px; /* simulate padding and border without affecting height and width */ font-family: "segoe ui", Verdana, Arial, Sans-Serif; font-size: 12px; }


Actualización de 2016: una solución más moderna basada en HTML5 sería utilizar la propiedad contenteditable .

<div contenteditable="true"> <!-- behaves as input --> Block of regular text, and <span id=''interest''>text of interest</span> </div>

Ahora podemos encontrar la posición del tramo usando jquery offset() . Y, por supuesto, las etiquetas <span> se pueden insertar por adelantado o dinámicamente.


Actualización de mayo de 2014: la increíblemente ligera y robusta biblioteca de componentes textarea-caret-position ahora también admite <input type="text"> , lo que hace que todas las demás respuestas queden obsoletas.

Una demostración está disponible en jsfiddle.net/dandv/aFPA7

Gracias a Rob W por la inspiración hacia el soporte RTL.


Manifestación
He escrito una función que se comporta como se espera. Un panel de demostración muy detallado se puede encontrar aquí: Fiddle: http://jsfiddle.net/56Rep/5/
La interfaz en la demo es autoexplicativa.

La funcionalidad solicitada en la pregunta se implementaría en mi función de la siguiente manera:
var pixelPosition = getTextBoundingRect(input, 6)

Dependencias de funciones
Actualizado : la función es JavaScript puro, y no depende de ningún complemento ni marco.
La función asume que el método getBoundingClientRect existe. Los rangos de texto se utilizan cuando son compatibles. De lo contrario, la funcionalidad se logra utilizando mi función lógica.

Lógica de funciones
El código en sí contiene varios comentarios. Esta parte va en un detalle más profundo.

  1. Se crea un contenedor <div> temporal .
  2. Se crean 1 - 3 elementos <span> . Cada intervalo contiene una parte del valor de la entrada (compensa de 0 a selectionStart , selectionStart to selectionEnd , selectionEnd al final de la cadena, solo el segundo span es significativo).
  3. Varias propiedades de estilo significativas del elemento de entrada se copian en estas <div> y <span> . Sólo se copian las propiedades de estilo significativas. Por ejemplo, el color no se copia, porque no afecta a las compensaciones de un personaje de ninguna manera. # 1
  4. El <div> se coloca en la posición exacta del nodo de texto (valor de entrada). Se tienen en cuenta los bordes y los rellenos para asegurarse de que el <div> temporal esté correctamente posicionado.
  5. Se crea una variable, que contiene el valor de retorno de div.getBoundingClientRect() .
  6. El <div> temporal se elimina, a menos que la debug parámetro se establezca en verdadero.
  7. La función devuelve el objeto ClientRect . Para obtener más información sobre este objeto, consulte div.getBoundingClientRect() . La http://jsfiddle.net/56Rep/5/ también muestra una lista de propiedades: top , left , right , bottom , height y width .

# 1 : getBoundingClientRect() (y algunas propiedades menores) se usa para determinar la posición del elemento de entrada. Luego, se agregan el relleno y el ancho del borde, para obtener la posición real de un nodo de texto.

Problemas conocidos
El único caso de inconsistencia se encontró cuando getComputedStyle devolvió un valor incorrecto para font-family de font-family : cuando una página no ha definido una propiedad de la font-family , el estilo de computadora devuelve un valor incorrecto (incluso Firebug está experimentando este problema; entorno: Linux, Firefox 3.6.23, fuente "Sans Serif").

Como se ve en la demostración, el posicionamiento a veces está ligeramente desviado (casi cero, siempre menor a 1 píxel).

Las restricciones técnicas impiden que el script obtenga el desplazamiento exacto de un fragmento de texto cuando se ha movido el contenido, por ejemplo, cuando el primer carácter visible en un campo de entrada no es igual al carácter del primer valor.

Código

// @author Rob W http://.com/users/938089/rob-w // @name getTextBoundingRect // @param input Required HTMLElement with `value` attribute // @param selectionStart Optional number: Start offset. Default 0 // @param selectionEnd Optional number: End offset. Default selectionStart // @param debug Optional boolean. If true, the created test layer // will not be removed. function getTextBoundingRect(input, selectionStart, selectionEnd, debug) { // Basic parameter validation if(!input || !(''value'' in input)) return input; if(typeof selectionStart == "string") selectionStart = parseFloat(selectionStart); if(typeof selectionStart != "number" || isNaN(selectionStart)) { selectionStart = 0; } if(selectionStart < 0) selectionStart = 0; else selectionStart = Math.min(input.value.length, selectionStart); if(typeof selectionEnd == "string") selectionEnd = parseFloat(selectionEnd); if(typeof selectionEnd != "number" || isNaN(selectionEnd) || selectionEnd < selectionStart) { selectionEnd = selectionStart; } if (selectionEnd < 0) selectionEnd = 0; else selectionEnd = Math.min(input.value.length, selectionEnd); // If available (thus IE), use the createTextRange method if (typeof input.createTextRange == "function") { var range = input.createTextRange(); range.collapse(true); range.moveStart(''character'', selectionStart); range.moveEnd(''character'', selectionEnd - selectionStart); return range.getBoundingClientRect(); } // createTextRange is not supported, create a fake text range var offset = getInputOffset(), topPos = offset.top, leftPos = offset.left, width = getInputCSS(''width'', true), height = getInputCSS(''height'', true); // Styles to simulate a node in an input field var cssDefaultStyles = "white-space:pre;padding:0;margin:0;", listOfModifiers = [''direction'', ''font-family'', ''font-size'', ''font-size-adjust'', ''font-variant'', ''font-weight'', ''font-style'', ''letter-spacing'', ''line-height'', ''text-align'', ''text-indent'', ''text-transform'', ''word-wrap'', ''word-spacing'']; topPos += getInputCSS(''padding-top'', true); topPos += getInputCSS(''border-top-width'', true); leftPos += getInputCSS(''padding-left'', true); leftPos += getInputCSS(''border-left-width'', true); leftPos += 1; //Seems to be necessary for (var i=0; i<listOfModifiers.length; i++) { var property = listOfModifiers[i]; cssDefaultStyles += property + '':'' + getInputCSS(property) +'';''; } // End of CSS variable checks var text = input.value, textLen = text.length, fakeClone = document.createElement("div"); if(selectionStart > 0) appendPart(0, selectionStart); var fakeRange = appendPart(selectionStart, selectionEnd); if(textLen > selectionEnd) appendPart(selectionEnd, textLen); // Styles to inherit the font styles of the element fakeClone.style.cssText = cssDefaultStyles; // Styles to position the text node at the desired position fakeClone.style.position = "absolute"; fakeClone.style.top = topPos + "px"; fakeClone.style.left = leftPos + "px"; fakeClone.style.width = width + "px"; fakeClone.style.height = height + "px"; document.body.appendChild(fakeClone); var returnValue = fakeRange.getBoundingClientRect(); //Get rect if (!debug) fakeClone.parentNode.removeChild(fakeClone); //Remove temp return returnValue; // Local functions for readability of the previous code function appendPart(start, end){ var span = document.createElement("span"); span.style.cssText = cssDefaultStyles; //Force styles to prevent unexpected results span.textContent = text.substring(start, end); fakeClone.appendChild(span); return span; } // Computing offset position function getInputOffset(){ var body = document.body, win = document.defaultView, docElem = document.documentElement, box = document.createElement(''div''); box.style.paddingLeft = box.style.width = "1px"; body.appendChild(box); var isBoxModel = box.offsetWidth == 2; body.removeChild(box); box = input.getBoundingClientRect(); var clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0, scrollTop = win.pageYOffset || isBoxModel && docElem.scrollTop || body.scrollTop, scrollLeft = win.pageXOffset || isBoxModel && docElem.scrollLeft || body.scrollLeft; return { top : box.top + scrollTop - clientTop, left: box.left + scrollLeft - clientLeft}; } function getInputCSS(prop, isnumber){ var val = document.defaultView.getComputedStyle(input, null).getPropertyValue(prop); return isnumber ? parseFloat(val) : val; } }