Was ist mit console.log in IE8 passiert?


254

Laut diesem Beitrag war es in der Beta, aber es ist nicht in der Veröffentlichung?


65
console.log ist in IE8 vorhanden, aber das consoleObjekt wird erst erstellt, wenn Sie DevTools öffnen. Daher kann ein Aufruf von zu console.logeinem Fehler führen, z. B. wenn er beim Laden der Seite auftritt, bevor Sie die Entwickler-Tools öffnen können. Die gewinnende Antwort hier erklärt es ausführlicher.
DEZA

Antworten:


229

Noch besser für den Fallback ist dies:


   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
Dies ist so unpraktisch - wie können Sie möglicherweise eine Website mit etwas debuggen, das bei jedem Aufruf von console.log () eine Warnung auslöst? Was ist, wenn Sie mehr als 10 Aufrufe haben, um () in Ihrem Code anzumelden? Was ist, wenn msg ein Objekt ist? Walters Antwort ist als Ausgangspunkt viel sinnvoller.
Precastic

7
@ Precastic: Die Leute werden einfach aufhören, den Browser zu benutzen: P
Amogh Talpallikar

Siehe meinen Kommentar zu Mister Luckys Antwort.
Daniel Schilling

1
Ein unauffälliger (wenn auch unvollkommener) alternativer Fallback ist das Setzen von document.title. Zumindest blockiert es den Browser nicht mit einer modalen Warnung.
brennanyoung

257

console.log ist erst verfügbar, nachdem Sie die Entwicklertools geöffnet haben (F12, um sie zu öffnen und zu schließen). Das Lustige ist, dass Sie es nach dem Öffnen schließen und dann über console.log-Aufrufe veröffentlichen können. Diese werden angezeigt, wenn Sie es erneut öffnen. Ich denke, das ist eine Art Fehler und kann behoben werden, aber wir werden sehen.

Ich werde wahrscheinlich nur so etwas verwenden:

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

und noch einfacher:

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

11
In beiden Fällen sollten Sie console.log nicht blind aufrufen, da $ andere Browser es möglicherweise nicht haben und daher mit einem JavaScript-Fehler sterben. +1
Kent Fredric

8
Du wirst wahrscheinlich sowieso Spuren vor der Veröffentlichung ausschalten wollen;)
Kent Fredric

2
Es ist sinnvoll, nicht zu protokollieren, ohne dass Entwicklertools geöffnet sind, sondern eine Ausnahme auszulösen, wenn die eigentliche verwirrende Entscheidung hier nicht stillschweigend fehlschlägt.
ehdv

4
Ich möchte auf einen Nachteil beim Umschließen von console.log wie diesem hinweisen ... Sie werden nicht mehr sehen, woher Ihre Protokollierung kommt. Ich finde das manchmal sehr nützlich, und es sieht einfach falsch aus, wenn jede Konsolenzeile von genau derselben Stelle in Ihrem Code stammt.
Martin Westin

2
alertist böse Einige Codes verhalten sich anders, wenn Warnungen verwendet werden, da das Dokument den Fokus verliert, wodurch es noch schwieriger wird, Fehler zu diagnostizieren oder solche zu erstellen, bei denen es vorher keine gab. Wenn Sie versehentlich ein console.login Ihrem Produktionscode belassen, ist es harmlos (vorausgesetzt, es explodiert nicht) - es wird nur stillschweigend an der Konsole protokolliert. Wenn Sie versehentlich einen alertin Ihrem Produktionscode belassen, wird die Benutzererfahrung ruiniert.
Daniel Schilling

56

Dies ist meine Sicht auf die verschiedenen Antworten. Ich wollte die protokollierten Nachrichten tatsächlich sehen, auch wenn die IE-Konsole beim Auslösen nicht geöffnet war, und schiebe sie in ein von console.messagesmir erstelltes Array. Ich habe auch eine Funktion hinzugefügt console.dump(), um das Anzeigen des gesamten Protokolls zu erleichtern.console.clear()wird die Nachrichtenwarteschlange leeren.

Diese Lösung "behandelt" auch die anderen Konsolenmethoden (von denen ich glaube, dass sie alle von der Firebug-Konsolen-API stammen ).

Schließlich liegt diese Lösung in Form eines IIFE vor , sodass der globale Geltungsbereich nicht verschmutzt wird. Das Fallback-Funktionsargument wird am Ende des Codes definiert.

Ich lege es einfach in meine Master-JS-Datei, die auf jeder Seite enthalten ist, und vergesse es.

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

Einige zusätzliche Informationen

Die Linie var args = Array.prototype.slice.call(arguments);erstellt ein Array aus dem argumentsObjekt. Dies ist erforderlich, da Argumente nicht wirklich ein Array sind .

trap()ist ein Standardhandler für eine der API-Funktionen. Ich übergebe die Argumente an, messagedamit Sie ein Protokoll der Argumente erhalten, die an einen API-Aufruf übergeben wurden (nicht nur console.log).

Bearbeiten

Ich habe ein zusätzliches Array hinzugefügt console.raw, das die Argumente genau so erfasst, wie sie übergeben wurden trap(). Mir wurde klar, dass args.join(' ')Objekte in die Zeichenfolge konvertiert wurden, "[object Object]"was manchmal unerwünscht sein kann. Danke bfontaine für den Vorschlag .


4
+1 Dies ist die einzige Lösung, die Sinn macht. In welcher Welt würden Sie nicht wollen , um die Nachrichten zu sehen , Sie an die Konsole explizit zu senden sind!
Precastic

Gute Antwort. Der von Ihnen erwähnte IIFE-Artikel hat mir sehr gut gefallen, wahrscheinlich einer der besten, den ich bisher gelesen habe. Könnten Sie bitte näher erläutern, wozu diese beiden trapFunktionslinien dienen : var args = Array.prototype.slice.call(arguments); var message = args.join(' ');? Warum geben Sie die Argumente hierdurch an die Nachricht weiter?
Benutzer1555863

1
@ user1555863 Ich habe meine Antwort aktualisiert, um Ihre Fragen zu beantworten. Siehe Abschnitt unter dem Code.
Walter Stabosz

1
Ich denke, die zweite Zeile Ihrer Funktion "console.clear ()" sollte "console.raw.length = 0" anstelle von "console.row.length = 0" lauten.
Steve J

52

Es ist erwähnenswert, dass console.login IE8 keine echte Javascript-Funktion ist. Die Methoden applyoder callwerden nicht unterstützt .


3
+1 Dies ist mein genauer Fehler heute Morgen. Ich versuche, Argumente auf console.log anzuwenden, und IE8 hasst mich.
Bernhard Hofmann

[Witz] Microsoft sagt, "es ist unsicher für uns, uns Leute Konsolenobjekt überschreiben zu lassen": /
Tom Roggero

1
Ich habe verwendet: console.log=Function.prototype.bind.call(console.log,console);um dies zu umgehen.
Mowwwalker

1
IE8 hat nicht bind.
Katspaugh

44

Angenommen, Sie interessieren sich nicht für einen Fallback zur Warnung, dann finden Sie hier eine noch präzisere Möglichkeit, die Mängel des Internet Explorers zu umgehen:

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

+1 Da ich meinen Code in einer anonymen Funktion auslasse, ist es für mich die beste Lösung, die Konsole in eine Variable wie diese zu platzieren. Hilft mir, keine anderen Konsolenverbindungen in anderen Bibliotheken zu stören.
Codesleuth

2
Sie möchten mit der Protokollierung beginnen, sobald die Entwicklertools geöffnet wurden. Wenn Sie diese Lösung in einen langlebigen Bereich stellen (z. B. innere Funktionen als Rückrufe registrieren), wird der stille Fallback weiterhin verwendet.
Beni Cherniavsky-Paskin

+ 1 / -1 = 0: +1, da die Lösung mehr darauf basieren sollte, zu verhindern, dass console.logs eine Site im IE beschädigt - nicht zum Debuggen verwendet ... Wenn Sie debuggen möchten, drücken Sie einfach f12 und öffnen Sie die Konsole: ) -1, da Sie vor dem Überschreiben prüfen sollten, ob eine Konsole vorhanden ist.
1nfiniti

Einige IE-Plugins definieren console und console.log, jedoch als leere Objekte, nicht als Funktionen.
Lilith River

24

Ich mag den Ansatz von "orange80" sehr. Es ist elegant, weil Sie es einmal einstellen und vergessen können.

Bei den anderen Ansätzen müssen Sie etwas anderes tun (etwas anderes als einfach nennen console.log() jedes Mal ), was nur nach Ärger fragt… Ich weiß, dass ich es irgendwann vergessen würde.

Ich bin noch einen Schritt weiter gegangen, indem ich den Code in eine Dienstprogrammfunktion eingebunden habe, die Sie am Anfang Ihres Javascript einmal aufrufen können, solange es vor der Protokollierung liegt. (Ich installiere dies in dem Event Data Router-Produkt meines Unternehmens. Es wird dazu beitragen, das browserübergreifende Design der neuen Administrationsoberfläche zu vereinfachen.)

/**
 * 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
Schön, dass es dir gefällt :-) Ich benutze es genau aus dem Grund, den du erwähnt hast - b / c es ist eine gute Sicherheit. Es ist einfach viel zu einfach, einige "console.log" -Anweisungen für die Entwicklung in Ihren Code einzufügen und zu vergessen, sie später zu entfernen. Zumindest wenn Sie dies tun und es oben in jede Datei einfügen, in der Sie console.log verwenden, wird die Site niemals in den Browsern der Kunden kaputt gehen, da diese in console.log fehlschlagen. Hat mich schon mal gerettet! Schöne Verbesserungen, übrigens :-)
jpswain

1
"Es ist einfach zu einfach, ... zu vergessen, sie zu entfernen". Eine hilfreiche Sache, die ich bei der temporären Debug-Protokollierung immer mache, ist, dem Code einen leeren Kommentar voranzustellen, /**/console.log("...");damit der temporäre Code leicht gesucht und gefunden werden kann.
Lawrence Dol

8

Wenn Sie für alle Ihre console.log-Aufrufe "undefiniert" erhalten, bedeutet dies wahrscheinlich, dass noch ein alter Firebuglite geladen ist (firebug.js). Es werden alle gültigen Funktionen von IE8s console.log überschrieben, obwohl sie vorhanden sind. Das ist mir sowieso passiert.

Suchen Sie nach anderem Code, der das Konsolenobjekt überschreibt.


5

Die beste Lösung für jeden Browser ohne Konsole ist:

// 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
Dies hat das krasse Problem, dass Objekte oder Zeichenfolgen, die mit console.group oder console.GroupCollapsed protokolliert wurden, vollständig verschwinden. Dies ist nicht erforderlich. Sie sollten der Datei console.log zugeordnet werden, sofern diese verfügbar ist.
Ben

3

Es gibt so viele Antworten. Meine Lösung dafür war:

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

Kurz gesagt, wenn console.log nicht vorhanden ist (oder in diesem Fall nicht geöffnet ist), speichern Sie das Protokoll in einem globalen Namespace-Array. Auf diese Weise werden Sie nicht mit Millionen von Warnungen belästigt und können Ihre Protokolle weiterhin bei geöffneter oder geschlossener Entwicklerkonsole anzeigen.


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

Wollen Sie damit sagen, dass dies window.console.log()möglicherweise in IE8 verfügbar ist, auch wenn dies console.log()nicht der Fall ist?
LarsH

Das Problem hier ist, dass typeof window.console.log === "object"nicht"function"
Isochronous

2

Hier ist mein "IE bitte nicht abstürzen"

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

1

Ich habe das auf Github gefunden :

// 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

Ich verwende Walters Ansatz von oben (siehe: https://stackoverflow.com/a/14246240/3076102 ).

Ich mische eine Lösung ein, die ich hier gefunden habe: https://stackoverflow.com/a/7967670 , um Objekte richtig anzuzeigen.

Dies bedeutet, dass die Trap-Funktion:

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

Ich hoffe das ist hilfreich :-)


0

Es funktioniert in IE8. Öffnen Sie die Entwicklertools von IE8, indem Sie F12 drücken.

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

6
Dies gibt in meinem Fall "undefiniert" aus.
Acme

6
Wie Herr Lucky betonte: "console.log ist erst verfügbar, nachdem Sie die Entwicklertools geöffnet haben (F12, um sie zu öffnen und zu schließen)."
Der Schalldämpfer

0

Ich mag diese Methode (mit jquery's doc ready) ... Sie können die Konsole auch in verwenden, dh ... nur der Haken ist, dass Sie die Seite neu laden müssen, wenn Sie die Entwickler-Tools von ie öffnen, nachdem die Seite geladen wurde ...

Es könnte schlanker sein, wenn alle Funktionen berücksichtigt werden, aber ich verwende nur das Protokoll, also mache ich das so.

//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

Hier ist eine Version, die sich bei der Konsole anmeldet, wenn die Entwicklertools geöffnet sind und nicht, wenn sie geschlossen sind.

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

Gut, dass der Umfang begrenzt ist, könnte den Fall unterstützen, wenn IE8 DevTools während der Codeausführung geöffnet sind, aber in IE8 nicht funktioniert. Console.log ist ein Objekt, daher gibt es keine applyMethode.
Nishi

0

Machen Sie Ihre eigene Konsole in HTML .... ;-) Dies kann verbessert werden, aber Sie können beginnen mit:

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);
        }
    };
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.