¿Qué pasó con console.log en IE8?

254

Según esta publicación , estaba en la versión beta, pero no está en el lanzamiento.

leeand00
fuente
65
console.log está ahí en IE8, pero el consoleobjeto no se crea hasta que abra DevTools. Por lo tanto, una llamada a console.logpuede provocar un error, por ejemplo, si ocurre en la carga de la página antes de que tenga la oportunidad de abrir las herramientas de desarrollo. La respuesta ganadora aquí lo explica con más detalle.
SDC

Respuestas:

229

Aún mejor para el retroceso es este:


   var alertFallback = true;
   if (typeof console === "undefined" || typeof console.log === "undefined") {
     console = {};
     if (alertFallback) {
         console.log = function(msg) {
              alert(msg);
         };
     } else {
         console.log = function() {};
     }
   }

jpswain
fuente
71
Esto es muy poco práctico: ¿cómo podría depurar un sitio web con algo que arroje una alerta por cada llamada a console.log (). ¿Qué sucede si tiene más de 10 llamadas para iniciar sesión () en su código? ¿Qué pasa si msg es un objeto? La respuesta de Walter tiene mucho más sentido, como punto de partida.
Precastic
77
@Precastic: La gente simplemente dejará de usar el navegador: P
Amogh Talpallikar
Vea mi comentario sobre la respuesta del señor Lucky.
Daniel Schilling
1
Una alternativa alternativa discreta (aunque imperfecta) es establecer document.title. Al menos no bloquea el navegador con una alerta modal.
brennanyoung
257

console.log solo está disponible después de haber abierto las Herramientas para desarrolladores (F12 para alternar entre abrir y cerrar). Lo curioso es que después de abrirlo, puede cerrarlo y luego publicarlo a través de las llamadas de console.log, y eso se verá cuando lo vuelva a abrir. Estoy pensando que es un tipo de error, y puede ser solucionado, pero ya veremos.

Probablemente usaré algo como esto:

function trace(s) {
  if ('console' in self && 'log' in console) console.log(s)
  // the line below you might want to comment out, so it dies silent
  // but nice for seeing when the console is available or not.
  else alert(s)
}

e incluso más simple:

function trace(s) {
  try { console.log(s) } catch (e) { alert(s) }
}
Señor suerte
fuente
11
De cualquier manera, no debería llamar a console.log a ciegas porque $ other-browsers podría no tenerlo y, por lo tanto, morir con un error de JavaScript. +1
Kent Fredric
8
probablemente querrás desactivar los rastros antes de liberarlos de todos modos;)
Kent Fredric
2
Tiene sentido no iniciar sesión sin que las herramientas de desarrollador estén abiertas, pero hacer que arroje una excepción si en lugar de fallar en silencio es la decisión realmente confusa aquí.
ehdv el
44
Quiero señalar una desventaja de envolver console.log como este ... ya no verá de dónde proviene su registro. Me parece muy útil, a veces, además de lo cual parece incorrecto tener todas las líneas de consola que se originan en la misma ubicación exacta en su código.
Martin Westin el
2
alertes malvado Algunos códigos se comportan de manera diferente cuando se usan alertas porque el documento pierde el foco, lo que hace que los errores sean aún más difíciles de diagnosticar o crea otros donde no los había antes. Además, si accidentalmente deja un console.logen su código de producción, es benigno (suponiendo que no explote), solo inicia sesión silenciosamente en la consola. Si accidentalmente deja un alerten su código de producción, la experiencia del usuario se arruina.
Daniel Schilling
56

Esta es mi opinión sobre las diversas respuestas. En realidad, quería ver los mensajes registrados, incluso si no tenía la consola IE abierta cuando fueron disparados, así que los inserto en una console.messagesmatriz que creo. También agregué una función console.dump()para facilitar la visualización de todo el registro. console.clear()vaciará la cola de mensajes.

Esta solución también "maneja" los otros métodos de la consola (que creo que todos se originan en la API de la consola Firebug )

Finalmente, esta solución tiene la forma de un IIFE , por lo que no contamina el alcance global. El argumento de la función alternativa se define en la parte inferior del código.

Simplemente lo dejo en mi archivo JS maestro que se incluye en cada página, y me olvido de eso.

(function (fallback) {    

    fallback = fallback || function () { };

    // function to trap most of the console functions from the FireBug Console API. 
    var trap = function () {
        // create an Array from the arguments Object           
        var args = Array.prototype.slice.call(arguments);
        // console.raw captures the raw args, without converting toString
        console.raw.push(args);
        var message = args.join(' ');
        console.messages.push(message);
        fallback(message);
    };

    // redefine console
    if (typeof console === 'undefined') {
        console = {
            messages: [],
            raw: [],
            dump: function() { return console.messages.join('\n'); },
            log: trap,
            debug: trap,
            info: trap,
            warn: trap,
            error: trap,
            assert: trap,
            clear: function() { 
                  console.messages.length = 0; 
                  console.raw.length = 0 ;
            },
            dir: trap,
            dirxml: trap,
            trace: trap,
            group: trap,
            groupCollapsed: trap,
            groupEnd: trap,
            time: trap,
            timeEnd: trap,
            timeStamp: trap,
            profile: trap,
            profileEnd: trap,
            count: trap,
            exception: trap,
            table: trap
        };
    }

})(null); // to define a fallback function, replace null with the name of the function (ex: alert)

Alguna información extra

La línea var args = Array.prototype.slice.call(arguments);crea una matriz a partir del argumentsobjeto. Esto es necesario porque los argumentos no son realmente una matriz .

trap()es un controlador predeterminado para cualquiera de las funciones de la API. Paso los argumentos a messagepara que obtenga un registro de los argumentos que se pasaron a cualquier llamada API (no solo console.log).

Editar

Agregué una matriz adicional console.rawque captura los argumentos exactamente como se les pasó trap(). Me di cuenta de que args.join(' ')estaba convirtiendo objetos en la cadena "[object Object]"que a veces puede ser indeseable. Gracias bfontaine por la sugerencia .

Walter Stabosz
fuente
44
+1 Esta es la única solución que comienza a tener sentido. ¡En qué mundo no querría ver los mensajes que está enviando explícitamente a la consola!
Precastic
Gran respuesta. Realmente me gustó el artículo de IIFE que has mencionado, probablemente uno de los mejores que he leído hasta ahora. ¿Podría explicar cuál es el propósito de estas dos líneas en trapfunción var args = Array.prototype.slice.call(arguments); var message = args.join(' ');:? ¿Por qué pasas los argumentos a través de esto al mensaje?
user1555863
1
@ user1555863 He actualizado mi respuesta para responder a sus preguntas, consulte la sección debajo del código.
Walter Stabosz
1
Creo que la segunda línea de la función "console.clear ()" debería leer "console.raw.length = 0", en lugar de "console.row.length = 0".
Steve J
52

Vale la pena señalar que console.logen IE8 no es una verdadera función de Javascript. No es compatible con los métodos applyo call.

James Wheare
fuente
3
+1 Este es mi error preciso esta mañana. Estoy tratando de aplicar argumentos a console.log e IE8 me está odiando.
Bernhard Hofmann
[broma] Microsoft dice "no es seguro para nosotros dejar que las personas sobrescriban el objeto de la consola": /
Tom Roggero
1
He estado usando: console.log=Function.prototype.bind.call(console.log,console);para evitar esto.
mowwwalker
1
IE8 no tiene bind.
katspaugh 01 de
44

Suponiendo que no le importa una alternativa para alertar, esta es una forma aún más concisa de solucionar las deficiencias de Internet Explorer:

var console=console||{"log":function(){}};
Leif Wickland
fuente
+1 Como estoy explorando mi código en una función anónima, colocar la consola en una variable como esta es la mejor solución para mí. Me ayuda a no interferir con ningún otro enganche de consola en otras bibliotecas.
Codesleuth
2
Desea comenzar a iniciar sesión tan pronto como se hayan abierto las herramientas de desarrollador. Si coloca esta solución en un ámbito de larga duración (por ejemplo, registra funciones internas como devoluciones de llamada), seguirá utilizando el respaldo silencioso.
Beni Cherniavsky-Paskin
+ 1 / -1 = 0: +1 porque la solución debería basarse más en evitar que console.logs rompa un sitio en IE, no se usa para depurar ... Si desea depurar, simplemente presione f12 y abra la consola: ) -1 porque debería verificar si la consola existe antes de sobrescribirla.
1nfiniti
Algunos complementos de IE definen console y console.log, pero como objetos vacíos, no como funciones.
Lilith River
24

Me gusta mucho el enfoque publicado por "orange80". Es elegante porque puedes configurarlo una vez y olvidarlo.

Los otros enfoques requieren que hagas algo diferente (llamar a algo diferente de lo normal console.log()cada vez), lo cual es solo pedir problemas ... Sé que eventualmente lo olvidaré.

He ido un paso más allá, envolviendo el código en una función de utilidad a la que puede llamar una vez al comienzo de su javascript, en cualquier lugar, siempre que sea antes de cualquier registro. (Estoy instalando esto en el producto de enrutador de datos de eventos de mi empresa. Ayudará a simplificar el diseño entre navegadores de su nueva interfaz de administración).

/**
 * Call once at beginning to ensure your app can safely call console.log() and
 * console.dir(), even on browsers that don't support it.  You may not get useful
 * logging on those browers, but at least you won't generate errors.
 * 
 * @param  alertFallback - if 'true', all logs become alerts, if necessary. 
 *   (not usually suitable for production)
 */
function fixConsole(alertFallback)
{    
    if (typeof console === "undefined")
    {
        console = {}; // define it if it doesn't exist already
    }
    if (typeof console.log === "undefined") 
    {
        if (alertFallback) { console.log = function(msg) { alert(msg); }; } 
        else { console.log = function() {}; }
    }
    if (typeof console.dir === "undefined") 
    {
        if (alertFallback) 
        { 
            // THIS COULD BE IMPROVED… maybe list all the object properties?
            console.dir = function(obj) { alert("DIR: "+obj); }; 
        }
        else { console.dir = function() {}; }
    }
}
Chris Janicki
fuente
1
Me alegro de que te guste :-) Lo uso por la razón exacta que mencionas: b / c es una buena seguridad. Es demasiado fácil poner algunas declaraciones "console.log" en su código para el desarrollo y olvidarse de eliminarlas más tarde. Al menos si haces esto y lo pones en la parte superior de cada archivo donde utilizas console.log, nunca tendrás el sitio roto en los navegadores de los clientes porque fallan en console.log. ¡Me salvó antes! Buenas mejoras, por cierto :-)
jpswain
1
"Es demasiado fácil ... olvidar eliminarlos". Una cosa útil que siempre hago con el registro de depuración temporal es prefijar el código con un comentario vacío, /**/console.log("...");por lo que es fácil buscar y localizar el código temporal.
Lawrence Dol
8

Si obtiene "indefinido" a todas sus llamadas de console.log, eso probablemente significa que todavía tiene una vieja firebuglite cargada (firebug.js). Anulará todas las funciones válidas de console.log de IE8 aunque existan. Esto es lo que me pasó de todos modos.

Busque otro código que anule el objeto de la consola.

usuario168290
fuente
5

La mejor solución para cualquier navegador que carece de consola es:

// Avoid `console` errors in browsers that lack a console.
(function() {
    var method;
    var noop = function () {};
    var methods = [
        'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error',
        'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log',
        'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd',
        'timeStamp', 'trace', 'warn'
    ];
    var length = methods.length;
    var console = (window.console = window.console || {});

    while (length--) {
        method = methods[length];

        // Only stub undefined methods.
        if (!console[method]) {
            console[method] = noop;
        }
    }
}());
Vinícius Moraes
fuente
1
Esto tiene el problema evidente de que los objetos o cadenas registrados usando console.group o console.GroupCollapsed desaparecerán por completo. Esto es innecesario, deben asignarse a console.log, si está disponible.
Ben
3

Hay tantas respuestas Mi solución para esto fue:

globalNamespace.globalArray = new Array();
if (typeof console === "undefined" || typeof console.log === "undefined") {
    console = {};
    console.log = function(message) {globalNamespace.globalArray.push(message)};   
}

En resumen, si console.log no existe (o en este caso, no está abierto), almacene el registro en una matriz de espacio de nombres global. De esta manera, no te molestan millones de alertas y aún puedes ver tus registros con la consola de desarrollador abierta o cerrada.

calcazar
fuente
2
if (window.console && 'function' === typeof window.console.log) {
    window.console.log (o);
}
Balázs Németh
fuente
¿Estás diciendo que window.console.log()podría estar disponible en IE8 incluso cuando console.log()no lo está?
LarsH
El problema aquí es que typeof window.console.log === "object", no"function"
isócrono el
2

Aquí está mi "IE, por favor no se cuelgue"

typeof console=="undefined"&&(console={});typeof console.log=="undefined"&&(console.log=function(){});
BrunoLM
fuente
1

Encontré esto en github :

// usage: log('inside coolFunc', this, arguments);
// paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
window.log = function f() {
    log.history = log.history || [];
    log.history.push(arguments);
    if (this.console) {
        var args = arguments,
            newarr;
        args.callee = args.callee.caller;
        newarr = [].slice.call(args);
        if (typeof console.log === 'object') log.apply.call(console.log, console, newarr);
        else console.log.apply(console, newarr);
    }
};

// make it safe to use console.log always
(function(a) {
    function b() {}
    for (var c = "assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,markTimeline,profile,profileEnd,time,timeEnd,trace,warn".split(","), d; !! (d = c.pop());) {
        a[d] = a[d] || b;
    }
})(function() {
    try {
        console.log();
        return window.console;
    } catch(a) {
        return (window.console = {});
    }
} ());
Sam Jones
fuente
1

Estoy usando el enfoque de Walter desde arriba (ver: https://stackoverflow.com/a/14246240/3076102 )

Mezclo una solución que encontré aquí https://stackoverflow.com/a/7967670 para mostrar correctamente los objetos.

Esto significa que la función de trampa se convierte en:

function trap(){
    if(debugging){
        // create an Array from the arguments Object           
        var args = Array.prototype.slice.call(arguments);
        // console.raw captures the raw args, without converting toString
        console.raw.push(args);
        var index;
        for (index = 0; index < args.length; ++index) {
            //fix for objects
            if(typeof args[index] === 'object'){ 
                args[index] = JSON.stringify(args[index],null,'\t').replace(/\n/g,'<br>').replace(/\t/g,'&nbsp;&nbsp;&nbsp;');
            }
        }
        var message = args.join(' ');
        console.messages.push(message);
        // instead of a fallback function we use the next few lines to output logs
        // at the bottom of the page with jQuery
        if($){
            if($('#_console_log').length == 0) $('body').append($('<div />').attr('id', '_console_log'));
            $('#_console_log').append(message).append($('<br />'));
        }
    }
} 

Espero que esto sea útil:-)

Raymond Elferink
fuente
0

Funciona en IE8. Abra las Herramientas de desarrollo de IE8 presionando F12.

>>console.log('test')
LOG: test
Konstantin Tarkus
fuente
66
Esto emite "indefinido" en mi caso.
acme
66
Como señaló el señor Lucky: "console.log solo está disponible después de haber abierto las Herramientas para desarrolladores (F12 para alternar entre abrir y cerrar)".
The Silencer
0

Me gusta este método (usando jquery's doc ready) ... te permite usar la consola incluso en ie ... solo captura es que necesitas volver a cargar la página si abres las herramientas de desarrollo de ie después de que se carga la página ...

podría ser más sofisticado teniendo en cuenta todas las funciones, pero solo uso log, así que esto es lo que hago.

//one last double check against stray console.logs
$(document).ready(function (){
    try {
        console.log('testing for console in itcutils');
    } catch (e) {
        window.console = new (function (){ this.log = function (val) {
            //do nothing
        }})();
    }
});
usuario3560902
fuente
0

Aquí hay una versión que se registrará en la consola cuando las herramientas de desarrollador estén abiertas y no cuando estén cerradas.

(function(window) {

   var console = {};
   console.log = function() {
      if (window.console && (typeof window.console.log === 'function' || typeof window.console.log === 'object')) {
         window.console.log.apply(window, arguments);
      }
   }

   // Rest of your application here

})(window)
George Reith
fuente
Es bueno que tenga un alcance limitado, podría admitir el caso cuando las DevTools de IE8 están abiertas en medio de la ejecución del código, pero no funciona en IE8, console.log es un objeto, por lo que no tiene ningún applymétodo.
Nishi
0

Haga su propia consola en html .... ;-) Esto puede imprimirse pero puede comenzar con:

if (typeof console == "undefined" || typeof console.log === "undefined") {
    var oDiv=document.createElement("div");
    var attr = document.createAttribute('id'); attr.value = 'html-console';
    oDiv.setAttributeNode(attr);


    var style= document.createAttribute('style');
    style.value = "overflow: auto; color: red; position: fixed; bottom:0; background-color: black; height: 200px; width: 100%; filter: alpha(opacity=80);";
    oDiv.setAttributeNode(style);

    var t = document.createElement("h3");
    var tcontent = document.createTextNode('console');
    t.appendChild(tcontent);
    oDiv.appendChild(t);

    document.body.appendChild(oDiv);
    var htmlConsole = document.getElementById('html-console');
    window.console = {
        log: function(message) {
            var p = document.createElement("p");
            var content = document.createTextNode(message.toString());
            p.appendChild(content);
            htmlConsole.appendChild(p);
        }
    };
}
Alexandre Assouad
fuente