Cosa è successo a console.log in IE8?


254

Secondo questo post era in beta, ma non è in versione?


65
console.log è presente in IE8, ma l' consoleoggetto non viene creato finché non si apre DevTools. Pertanto, una chiamata a console.logpuò comportare un errore, ad esempio se si verifica al caricamento della pagina prima di avere la possibilità di aprire gli strumenti di sviluppo. La risposta vincente qui lo spiega in modo più dettagliato.
DSC

Risposte:


229

Ancora meglio per il fallback è questo:


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


71
Questo è così poco pratico: come è possibile eseguire il debug di un sito Web con qualcosa che genera un avviso per ogni chiamata a console.log (). Che cosa succede se hai più di 10 chiamate per accedere () al tuo codice. Cosa succede se msg è un oggetto? La risposta di Walter ha molto più senso, come punto di partenza.
Precastic

7
@Precastic: le persone smetteranno di usare il browser: P
Amogh Talpallikar

Vedi il mio commento sulla risposta di Mister Lucky.
Daniel Schilling,

1
un fallback alternativo discreto (sebbene imperfetto) è quello di impostare document.title. Almeno non blocca il browser con un avviso modale.
Brennanyoung,

257

console.log è disponibile solo dopo aver aperto gli Strumenti per sviluppatori (F12 per aprirlo e chiuderlo). La cosa divertente è che dopo averlo aperto, puoi chiuderlo, quindi inviarlo tramite chiamate console.log e questi verranno visualizzati quando lo riapri. Sto pensando che sia un tipo di errore, e potrebbe essere risolto, ma vedremo.

Probabilmente userò solo qualcosa del genere:

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 ancora più semplice:

function trace(s) {
  try { console.log(s) } catch (e) { alert(s) }
}

11
In ogni caso non dovresti chiamare console.log alla cieca perché $ other-browser potrebbe non averlo e quindi morire con un errore JavaScript. +1
Kent Fredric,

8
probabilmente vorrai comunque disattivare le tracce prima della pubblicazione;)
Kent Fredric,

2
Ha senso non accedere senza gli strumenti di sviluppo aperti, ma farne un'eccezione se invece di fallire in silenzio è la vera decisione confusa qui.
ehdv,

4
Voglio sottolineare un aspetto negativo nel wrapping console.log in questo modo ... non vedrai più da dove proviene la tua registrazione. Trovo che sia molto utile a volte in cima al quale sembra sbagliato avere ogni riga di console originata dalla stessa identica posizione nel codice.
Martin Westin,

2
alertè malvagio. Alcuni codici si comportano in modo diverso quando vengono utilizzati gli avvisi perché il documento perde lo stato attivo, rendendo i bug ancora più difficili da diagnosticare o creando quelli che prima non esistevano. Inoltre, se si lascia accidentalmente un console.lognel proprio codice di produzione, è benigno (supponendo che non esploda) - accede silenziosamente alla console. Se si lascia accidentalmente un alertnel codice di produzione, l'esperienza dell'utente viene rovinata.
Daniel Schilling,

56

Questa è la mia opinione sulle varie risposte. Volevo davvero vedere i messaggi registrati, anche se non avevo la console IE aperta quando venivano licenziati, quindi li spingo in un console.messagesarray che creo. Ho anche aggiunto una funzione console.dump()per facilitare la visualizzazione dell'intero registro. console.clear()svuota la coda dei messaggi.

Questa soluzione "gestisce" anche gli altri metodi della console (che credo provengano tutti dall'API della console Firebug )

Infine, questa soluzione è sotto forma di IIFE , quindi non inquina l'ambito globale. L'argomento della funzione di fallback è definito nella parte inferiore del codice.

Lo lascio cadere nel mio file JS principale che è incluso in ogni pagina e me ne dimentico.

(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)

Alcune informazioni extra

La linea var args = Array.prototype.slice.call(arguments);crea una matrice dall'oggetto arguments. Ciò è necessario perché gli argomenti non sono realmente una matrice .

trap()è un gestore predefinito per una qualsiasi delle funzioni API. Passo gli argomenti in messagemodo da ottenere un registro degli argomenti che sono stati passati a qualsiasi chiamata API (non solo console.log).

modificare

Ho aggiunto un array extra console.rawche cattura gli argomenti esattamente come passati trap(). Mi sono reso conto che args.join(' ')stava convertendo oggetti nella stringa "[object Object]"che a volte potrebbe essere indesiderabile. Grazie bfontaine per il suggerimento .


4
+1 Questa è l'unica soluzione che inizia a dare un senso. In quale mondo non vorresti vedere i messaggi che stai inviando esplicitamente alla console!
Precastic

Bella risposta. Mi è piaciuto molto l'articolo IIFE che hai citato, probabilmente uno dei migliori che abbia letto finora. Potresti per favore elaborare qual è lo scopo di queste due linee in trapfunzione var args = Array.prototype.slice.call(arguments); var message = args.join(' ');:? Perché passi gli argomenti attraverso questo al messaggio?
user1555863

1
@ user1555863 Ho aggiornato la mia risposta per rispondere alle tue domande, vedi la sezione sotto il codice.
Walter Stabosz,

1
Penso che la seconda riga della funzione "console.clear ()" dovrebbe leggere "console.raw.length = 0", anziché "console.row.length = 0".
Steve J,

52

Vale la pena notare che console.login IE8 non è una vera funzione Javascript. Non supporta i metodi applyo call.


3
+1 Questo è il mio errore preciso questa mattina. Sto cercando di applicare argomenti a console.log e IE8 mi sta odiando.
Bernhard Hofmann

[scherzo] Microsoft dice "non è sicuro per noi farci sovrascrivere oggetto console": /
Tom Roggero

1
Ho usato: console.log=Function.prototype.bind.call(console.log,console);per aggirare questo.
falciatrice

1
IE8 non ha bind.
katspaugh,

44

Supponendo che non ti interessi un fallback per avvisare, ecco un modo ancora più conciso per ovviare alle carenze di Internet Explorer:

var console=console||{"log":function(){}};

+1 Dal momento che sto scoping il mio codice in una funzione anonima, posizionare la console in una variabile come questa è la soluzione migliore per me. Mi aiuta a non interferire con qualsiasi altra console collegata in altre librerie.
Codesleuth,

2
Si desidera avviare la registrazione non appena sono stati aperti gli strumenti di sviluppo. Se si inserisce questa soluzione in un ambito di lunga durata (ad es. Registra le funzioni interne come callback), continuerà a utilizzare il fallback silenzioso.
Beni Cherniavsky-Paskin,

+ 1 / -1 = 0: +1 perché la soluzione dovrebbe essere più basata sull'impedire a console.logs di interrompere un sito in IE - non utilizzato per il debug ... Se si desidera eseguire il debug, basta premere F12 e aprire la console: ) -1 perché dovresti verificare se la console esiste prima di sovrascriverla.
1nfiniti

Alcuni plugin IE definiscono console e console.log, ma come oggetti vuoti, non funzioni.
Lilith River,

24

Mi piace molto l'approccio pubblicato da "orange80". È elegante perché puoi impostarlo una volta e dimenticarlo.

Gli altri approcci richiedono che tu faccia qualcosa di diverso (chiama console.log()ogni volta qualcosa di diverso dal semplice ), che è solo per chiedere problemi ... So che alla fine dimenticherei.

Ho fatto un ulteriore passo avanti, avvolgendo il codice in una funzione di utilità che puoi chiamare una volta all'inizio del tuo javascript, ovunque fintanto che è prima di qualsiasi registrazione. (Lo sto installando nel prodotto del router di dati degli eventi della mia azienda. Aiuterà a semplificare la progettazione cross-browser della sua nuova interfaccia di amministrazione.)

/**
 * 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() {}; }
    }
}

1
Sono contento che ti piaccia :-) Lo uso per il motivo esatto che dici - b / c è una buona sicurezza. È semplicemente troppo facile inserire alcune istruzioni "console.log" nel codice per lo sviluppo e dimenticare di rimuoverle in seguito. Almeno se lo fai e lo metti in cima a ogni file in cui usi console.log, non avrai mai il sito che si rompe nei browser dei clienti a causa di errori su console.log. Mi hai salvato prima! Bei miglioramenti, a proposito :-)
jpswain l'

1
"È semplicemente troppo facile ... dimenticare di rimuoverli". Una cosa utile che faccio sempre con la registrazione temporanea del debug è il prefisso del codice con un commento vuoto, /**/console.log("...");quindi è facile cercare e individuare il codice temporaneo.
Lawrence Dol,

8

Se ottieni "undefined" per tutte le tue chiamate console.log, probabilmente significa che hai ancora un vecchio firebuglite caricato (firebug.js). Sostituirà tutte le funzioni valide di console.log di IE8 anche se esistono. Questo è quello che mi è successo comunque.

Verificare la presenza di altro codice che sovrascrive l'oggetto console.


5

La migliore soluzione per qualsiasi browser privo di console è:

// 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;
        }
    }
}());

1
Questo ha il problema evidente che oggetti o stringhe registrati usando console.group o console.GroupCollapsed scompariranno completamente. Questo non è necessario, dovrebbero essere mappati su console.log, se disponibile.
Ben

3

Ci sono così tante risposte. La mia soluzione per questo era:

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

In breve, se console.log non esiste (o in questo caso non è aperto), archiviare il registro in una matrice di spazi dei nomi globale. In questo modo, non sei infastidito da milioni di avvisi e puoi comunque visualizzare i tuoi registri con la console per sviluppatori aperta o chiusa.


2
if (window.console && 'function' === typeof window.console.log) {
    window.console.log (o);
}

Stai dicendo che window.console.log()potrebbe essere disponibile in IE8 anche quando console.log()non lo è?
LarsH

Il problema qui è che typeof window.console.log === "object"non"function"
Isochronous

2

Ecco il mio "IE, per favore, non andare in crash"

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

1

Ho trovato questo su 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 = {});
    }
} ());

1

Sto usando l'approccio di Walter dall'alto (vedi: https://stackoverflow.com/a/14246240/3076102 )

Mescolo una soluzione che ho trovato qui https://stackoverflow.com/a/7967670 per mostrare correttamente gli oggetti.

Ciò significa che la funzione trap diventa:

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 />'));
        }
    }
} 

Spero che questo sia utile:-)


0

Funziona in IE8. Apri gli strumenti di sviluppo di IE8 premendo F12.

>>console.log('test')
LOG: test

6
Questo problema "indefinito" nel mio caso.
Acme

6
Come ha sottolineato Mister Lucky: "console.log è disponibile solo dopo aver aperto gli Strumenti di sviluppo (F12 per aprirlo e chiuderlo)".
Il silenziatore,

0

Mi piace questo metodo (usando pronto il documento di jquery) ... ti permette di usare la console anche in ie ... l'unico problema è che devi ricaricare la pagina se apri gli strumenti di sviluppo di ie dopo il caricamento della pagina ...

potrebbe essere più semplice tenendo conto di tutte le funzioni, ma utilizzo solo il registro, quindi è quello che faccio.

//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
        }})();
    }
});

0

Ecco una versione che accederà alla console quando gli strumenti di sviluppo sono aperti e non quando sono chiusi.

(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)

Bene che ha un ambito limitato, potrebbe supportare il caso in cui IE8 DevTools è aperto nel mezzo dell'esecuzione del codice, ma non funziona in IE8, console.log è un oggetto, quindi non ha alcun applymetodo.
Nishi,

0

Crea la tua console in html .... ;-) Questo può essere impresso ma puoi iniziare 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);
        }
    };
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.