2011-12-01 12 views
56

Estoy usando codemirror 2 y funciona bien, excepto que el valor establecido del editor no se carga en el editor hasta que haga clic en el editor y se enfoca.El editor Codemirror no está cargando contenido hasta que hace clic en

Quiero que el editor muestre el contenido en sí mismo sin tener que hacer clic en él. ¿Algunas ideas?

Todas las demostraciones de codemirror funcionan como se esperaba, así que pensé que tal vez el área de texto no estaba enfocado, así que lo intenté también.

$("#editor").focus(); 
var editor = CodeMirror.fromTextArea(document.getElementById("editor"), { 
        mode: "text/html", 
        height: "197px", 
        lineNumbers: true 
       }); 
+2

También tengo este problema, donde cargo un editor CodeMirror en una ventana emergente modal. ¿Has encontrado una solución sobre cómo enfocar al editor? Gracias. –

Respuesta

31

Debe llamar a refresh() después de setValue(). Sin embargo, debe utilizar setTimeout para posponer la actualización() para después CodeMirror/Browser ha actualizado el diseño de acuerdo con el nuevo contenido:

this.codeMirrorInstance.setValue(content); 
var that = this; 
setTimeout(function() { 
    that.codeMirrorInstance.refresh(); 
},1); 

Funciona bien para mí. Encontré la respuesta en here.

+1

Tuve el mismo problema con las pestañas de jQuery UI, y me ayuda. – greenif

0

Intente llamar al foco en el elemento DOM en lugar del objeto jQuery.

var editor=$('#editor'); 
editor[0].focus(); 
// or 
document.getElementById('editor').focus(); 
+0

Gracias por la respuesta, voy a intentar eso. – Karl

23

espero que usted (o una secuencia de comandos que ha cargado) se está metiendo con el DOM de una manera tal que el editor está oculta o no en una posición extraña cuando se creó. Se requerirá una llamada a su método refresh() después de que se haga visible.

+0

Gracias por la respuesta, voy a probar eso también. – Karl

+2

En mi implementación, el objeto padre comenzó 'display: none;' que causó este problema, ¡esta respuesta resolvió el problema fácilmente! Gracias, @Marijn! – Soleil

+0

Esto resolvió también mi caso con el elemento padre siendo GWT TabLayoutPanel o DisclosurePanel que alternan la visualización de sus hijos. Lo arreglé usando listener en estos paneles principales y pospuse una actualización de código duplicado al mostrarlo. – jolivier

0

Me acabo de topar con una versión de este problema esta noche.

Varias otras publicaciones consideran que la visibilidad de los padres de la tabla de texto es importante, si está oculta, puede encontrarse con este problema.

En mi situación, la forma en sí y el entorno inmediato estaban bien, pero mi problema era el administrador de la vista Backbone en la cadena de representación.

Mi elemento de vista no se coloca en el DOM hasta que la vista se haya renderizado por completo, por lo que supongo que un elemento que no está en el DOM se considera oculto o simplemente no se maneja.

Para conseguir alrededor de él que añade una fase de postproducción (pseudocódigo):

view.render(); 
$('body').html(view.el); 
view.postRender(); 

En postRender la vista puede hacer lo que se necesita saber que todo el contenido es ahora visible en la pantalla, esto es donde Moví el CodeMirror y funcionó bien.

Esto también puede ser una manera de explicar por qué uno puede tener problemas con cosas como ventanas emergentes, ya que en algunos casos pueden intentar construir todo el contenido antes de mostrarlo.

Espero que ayude a alguien.

Toby

1

Otra solución más (que también me di cuenta es que el editor debe ser visible para crear correctamente) es adjuntar temporalmente el elemento principal al elemento del cuerpo durante la construcción, luego volver a conectar una vez completado.

De esta manera, no necesita entrometerse con elementos, o preocuparse por la visibilidad en las jerarquías existentes que su editor podría estar enterrado.

En mi caso, por processr.com, que tienen múltiples, elementos de edición de código anidados, todos los cuales necesitan ser creados sobre la marcha y cuando el usuario hace cambios, así que haga lo siguiente:

this.$elements.appendTo('body'); 
for (var i = 0; i < data.length; i++) 
{ 
    this.addElement(data[i]); 
} 
this.$elements.appendTo(this.$view); 

Se funciona muy bien, y no ha habido ningún parpadeo visible ni nada de eso hasta el momento.

+0

Buena solución. gracias – rgomesf

5

Algo funcionó para mí.

$(document).ready(function(){ 
       var editor = CodeMirror.fromTextArea(document.getElementById("code2"), { 
        //lineNumbers: true, 
         readOnly: true, 
         autofocus: true, 
        matchBrackets: true, 
        styleActiveLine: true 
       }); 
       setTimeout(function() { 
        editor.refresh(); 
        }, 100); 

     }); 
0
<div class="tabbable-line"> 
    <ul class="nav nav-tabs"> 
     <li class="active"> 
      <a href="#tabXml1" data-toggle="tab" aria-expanded="true">Xml 1</a> 
     </li> 
     <li class=""> 
      <a href="#tabXml2" id="xmlTab2Header" data-toggle="tab" aria-expanded="true">Xml 2</a> 
     </li> 
    </ul> 
    <div class="tab-content"> 
     <div class="tab-pane active" id="tabXml1"> 
      <textarea id="txtXml1" /> 
     </div> 
     <div class="tab-pane" id="tabXml2"> 
      <textarea id="txtXml2" /> 
     </div> 
    </div> 
</div> 

<link rel="stylesheet" href="~/Content/codemirror.min.css"> 
<style type="text/css"> 
    .CodeMirror { 
     border: 1px solid #eee; 
     max-width: 100%; 
     height: 400px; 
    } 
</style> 

<script src="~/Scripts/codemirror.min.js"></script> 
<script src="~/Scripts/codemirror.xml.min.js"></script> 
<script> 
     $(document).ready(function() { 
      var cmXml1; 
      var cmXml2; 
      cmXml1 = CodeMirror.fromTextArea(document.getElementById("txtXml1"), { 
       mode: "xml", 
       lineNumbers: true 
      }); 
      cmXml2 = CodeMirror.fromTextArea(document.getElementById("txtXml2"), { 
       mode: "xml", 
       lineNumbers: true 
      }); 
      // Refresh code mirror element when tab header is clicked. 
      $("#xmlTab2Header").click(function() { 
       setTimeout(function() { 
        cmXml2.refresh(); 
       }, 10); 
      }); 
     }); 
</script> 
1

Algo que funcionó para mí! :)

 var sh = setInterval(function() { 
     agentConfigEditor.refresh(); 
     }, 500); 

     setTimeout(function(){ 
     clearInterval(sh); 
     },2000) 
2

La versión 5.14.2 de codemirror aborda esto completamente con un complemento. Vea this answer para más detalles.

4

Resulta que estoy usando CodeMirror dentro de una pestaña de arranque. Sospeché que las pestañas de arranque eran lo que impedía que apareciera hasta que se hizo clic. Lo arreglé simplemente llamando al método refresh() en exposición.

var cmInstance = CodeMirror.fromTextArea(document.getElementById('cm'), { 
    lineNumbers: true, 
    lineWrapping: true, 
    indentUnit: 4, 
    mode: 'css' 
}); 

// to fix code mirror not showing up until clicked 
$(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function() { 
    this.refresh(); 
}.bind(cmInstance)); 
8

Por si acaso, y para todos los que no lee la documentación con suficiente cuidado (como yo), pero se tropieza con esto. Hay un autorefresh addon solo por eso.

Necesita agregar autorefresh.js en su archivo. Ahora puede usarlo así.

var editor =CodeMirror.fromTextArea(document.getElementById("id_commentsHint"), { 
    mode: "javascript", 
    autoRefresh:true, 
    lineNumbers: false, 
    lineWrapping: true, 

}); 

funciona como un encanto.

+0

Esto funcionó para mí. Usar 'setTimeout' con un tiempo real dentro es impredecible y eso fue lo único que me funcionó hasta ahora. Esta solución es mucho más robusta. – brandaemon

+0

Esto solo funciona para mí cuando tengo un setValue único(). Sin embargo, si deseo establecer el valor varias veces, aún tengo que enfocar manualmente el editor CodeMirror. – phpheini

+0

@phpheini También tengo el mismo problema. ¿Has descubierto una forma de lidiar con esto? – prismaticorb

Cuestiones relacionadas