without used trackid the solucionar solucion refreshing page method descargar como chrome another javascript internet-explorer

javascript - used - void(0) trackid=sp-006



El método de selección IE TextRange no funciona correctamente (4)

Tengo un problema inusual con un documento de IE con contentEditable establecido en verdadero. Al llamar a select () en un rango que está posicionado al final de un nodo de texto que precede inmediatamente a un elemento de bloque, la selección se desplaza al carácter correcto y aparece donde no debería. He enviado un error a Microsoft contra IE8. Si puedes, vota por este problema para que se solucione.

https://connect.microsoft.com/IE/feedback/ViewFeedback.aspx?FeedbackID=390995

He escrito un caso de prueba para demostrar el efecto:

<html> <body> <iframe id="editable"> <html> <body> <div id="test"> Click to the right of this line -&gt; <p id="par">Block Element</p> </div> </body> </html> </iframe> <input id="mytrigger" type="button" value="Then Click here to Save and Restore" /> <script type="text/javascript"> window.onload = function() { var iframe = document.getElementById(''editable''); var doc = iframe.contentDocument || iframe.contentWindow.document; // An IFRAME without a source points to a blank document. Here we''ll // copy the content we stored in between the IFRAME tags into that // document. It''s a hack to allow us to use only one HTML file for this // test. doc.body.innerHTML = iframe.textContent || iframe.innerHTML; // Marke the IFRAME as an editable document if (doc.body.contentEditable) { doc.body.contentEditable = true; } else { var mydoc = doc; doc.designMode = ''On''; } // A function to demonstrate the bug. var myhandler = function() { // Step 1 Get the current selection var selection = doc.selection || iframe.contentWindow.getSelection(); var range = selection.createRange ? selection.createRange() : selection.getRangeAt(0); // Step 2 Restore the selection if (range.select) { range.select(); } else { selection.removeAllRanges(); selection.addRange(range); doc.body.focus(); } } // Set up the button to perform the test code. var button = document.getElementById(''mytrigger''); if (button.addEventListener) { button.addEventListener(''click'', myhandler, false); } else { button.attachEvent(''onclick'', myhandler); } } </script> </body> </html>

El problema está expuesto en la función myhandler. Esto es todo lo que estoy haciendo, no hay Paso 3 entre guardar y restaurar la selección, y sin embargo, el cursor se mueve. No parece suceder a menos que la selección esté vacía (es decir, tengo un cursor parpadeante, pero no texto), y solo parece suceder cuando el cursor está al final de un nodo de texto que precede inmediatamente a un nodo de bloque.

Parece que el rango todavía está en la posición correcta (si llamo parentElement en el rango, devuelve el div), pero si obtengo un nuevo rango de la selección actual, el nuevo rango está dentro de la etiqueta de párrafo, y ese es su parentElement

¿Cómo soluciono esto y siempre guardo y restauro la selección en Internet Explorer?


Recientemente trabajé en un sitio que utilizaba Microsoft CMS con el "paquete MSIB +" de controles que incluía un editor WYSIWYG que se ejecutaba en Internet Explorer.

Me parece recordar algunos comentarios en el editor del lado del cliente de Javascript que estaban específicamente relacionados con este error en IE y el método Range.Select ().

Desafortunadamente, ya no estoy trabajando allí, así que no puedo acceder a los archivos de Javascript, pero ¿tal vez puedas obtenerlos de otro lado?

Buena suerte


He descubierto algunos métodos para lidiar con rangos de IE como este.

Si todo lo que quiere hacer es guardar donde está el cursor y luego restaurarlo, puede usar el método pasteHTML para insertar un tramo vacío en la posición actual del cursor, y luego usar el método moveToElementText para volver a colocarlo en esa posición de nuevo:

// Save position of cursor range.pasteHTML(''<span id="caret"></span>'') ... // Create new cursor and put it in the old position var caretSpan = iframe.contentWindow.document.getElementById("caret"); var selection = iframe.contentWindow.document.selection; newRange = selection.createRange(); newRange.moveToElementText(caretSpan);

Alternativamente, puede contar cuántos caracteres preceden a la posición actual del cursor y guardar ese número:

var selection = iframe.contentWindow.document.selection; var range = selection.createRange().duplicate(); range.moveStart(''sentence'', -1000000); var cursorPosition = range.text.length;

Para restaurar el cursor, lo establece al principio y luego lo mueve esa cantidad de caracteres:

var newRange = selection.createRange(); newRange.move(''sentence'', -1000000); newRange.move(''character'', cursorPosition);

Espero que esto ayude.


He tenido un poco de excavación y desafortunadamente no puedo ver una solución alternativa ... Aunque una cosa que noté al depurar el javascript, parece que el problema está realmente con el objeto range en vez de con el range.select() subsiguiente range.select() . Si observa los valores en el objeto rango que selection.createRange() devuelve, sí, el objeto dom primario puede ser correcto, pero la información de posicionamiento ya se está refiriendo al comienzo de la siguiente línea (es decir, offsetLeft / Top, boundingLeft / Top , etc. ya están equivocados).

Según la información aquí , aquí y aquí , creo que no tienes suerte con IE, ya que solo tienes acceso al objeto TextRange de Microsoft, que parece estar roto. Desde mi experimentación, puedes mover el rango y ubicarlo exactamente donde debería estar, pero una vez que lo haces, el objeto de rango cambia automáticamente a la siguiente línea incluso antes de que hayas intentado .select() . Por ejemplo, puede ver el problema al poner este código entre su Paso 1 y el Paso 2:

if (range.boundingWidth == 0) { //looks like its already at the start of the next line down... alert(''default position: '' + range.offsetLeft + '', '' + range.offsetTop); //lets move the start of the range one character back //(i.e. select the last char on the line) range.moveStart("character", -1); //now the range looks good (except that its width will be one char); alert(''one char back: '' + range.offsetLeft + '', '' + range.offsetTop); //calculate the true end of the line... var left = range.offsetLeft + range.boundingWidth; var top = range.offsetTop; //now we can collapse back down to 0 width range range.collapse(); //the position looks right alert(''moving to: '' + left + '', '' + top); //move there. range.moveToPoint(left, top); //oops... on the next line again... stupid IE. alert(''moved to: '' + range.offsetLeft + '', '' + range.offsetTop); }

Por lo tanto, lamentablemente no parece que haya alguna manera de garantizar que el rango esté en el lugar correcto cuando lo seleccione de nuevo.

Obviamente, existe una solución trivial a su código anterior, al cambiar el Paso 2 a esto:

// Step 2 Restore the selection if (range.select) { if (range.boundingWidth > 0) { range.select(); } } else { selection.removeAllRanges(); selection.addRange(range); doc.body.focus(); }

Pero presumiblemente, en realidad quiere hacer algo entre los pasos 1 y 2 en su actual, lo que implica mover la selección, de ahí la necesidad de volver a configurarlo. Pero solo por si acaso. :)

Entonces, lo mejor que puedo hacer es votar por el error que ha creado ... Espero que lo arreglen.


Quizás malinterprete, pero si hago clic a la derecha de esa primera línea, mi cursor ya aparece inmediatamente al comienzo de la segunda línea, por lo que no es un problema de TextRange, ¿verdad?

Agregar un tipo de documento para que la página de prueba se represente en modo estándar en lugar de en el modo peculiar, lo arregla para mí.

Y no puedo reproducir lo que hace su función myhandler, porque al hacer clic en ese botón se mueve el foco hacia el botón para que ya no pueda ver el cursor y tampoco pueda recuperarlo. Encontrar la posición del cursor en un área de contentEditable parece ser un problema completamente diferente .