Qu'est-il arrivé à console.log dans IE8?

254

Selon ce post, il était en version bêta, mais ce n'est pas dans la version?

leeand00
la source
65
console.log est là dans IE8, mais l' consoleobjet est pas créé jusqu'à ce que vous DevTools ouvert. Par conséquent, un appel à console.logpeut entraîner une erreur, par exemple s'il se produit au chargement de la page avant d'avoir la possibilité d'ouvrir les outils de développement. La réponse gagnante ici l' explique plus en détail.
SDC

Réponses:

229

Encore mieux pour le repli est le suivant:


   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
la source
71
C'est tellement peu pratique - comment pourriez-vous éventuellement déboguer un site Web avec quelque chose qui déclenche une alerte pour chaque appel à console.log (). Et si vous avez plus de 10 appels pour vous connecter () à votre code. Et si msg est un objet? La réponse de Walter est beaucoup plus logique, comme point de départ.
Precastic
7
@Precastic: Les gens vont simplement cesser d'utiliser le navigateur: P
Amogh Talpallikar
Voir mon commentaire sur la réponse de Monsieur Lucky.
Daniel Schilling
1
une alternative alternative discrète (bien qu'imparfaite) est de définir document.title. Au moins, il ne verrouille pas le navigateur avec une alerte modale.
brennanyoung
257

console.log n'est disponible qu'après avoir ouvert les outils de développement (F12 pour l'activer et le fermer). Ce qui est drôle, c'est qu'après l'avoir ouvert, vous pouvez le fermer, puis le publier via des appels console.log, et ceux-ci seront visibles lorsque vous le rouvrirez. Je pense que c'est un bug en quelque sorte, et peut être corrigé, mais nous verrons.

Je vais probablement utiliser quelque chose comme ça:

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

et encore plus simple:

function trace(s) {
  try { console.log(s) } catch (e) { alert(s) }
}
Monsieur chanceux
la source
11
Dans tous les cas, vous ne devriez pas appeler console.log à l'aveuglette car $ autres-navigateurs pourraient ne pas l'avoir et donc mourir avec une erreur JavaScript. +1
Kent Fredric
8
vous voudrez probablement désactiver les traces avant la sortie de toute façon;)
Kent Fredric
2
Il est logique de ne pas se connecter sans que les outils de développement ne soient ouverts, mais de lui faire lever une exception si plutôt que d'échouer silencieusement est la vraie décision confuse ici.
ehdv
4
Je veux souligner un inconvénient à encapsuler console.log comme celui-ci ... vous ne verrez plus d'où vient votre journalisation. Je trouve cela très utile parfois au-dessus duquel il semble juste que chaque ligne de console provienne exactement du même emplacement dans votre code.
Martin Westin
2
alertest mauvais. Certains codes se comportent différemment lorsque des alertes sont utilisées, car le document perd le focus, ce qui rend les bogues encore plus difficiles à diagnostiquer ou en crée des là où il n'y en avait pas auparavant. De plus, si vous laissez accidentellement un console.logdans votre code de production, il est bénin (en supposant qu'il ne explose pas) - se connecte simplement en silence à la console. Si vous laissez accidentellement un alertdans votre code de production, l'expérience utilisateur est ruinée.
Daniel Schilling
56

C'est mon point de vue sur les différentes réponses. Je voulais réellement voir les messages enregistrés, même si je n'avais pas la console IE ouverte lorsqu'ils ont été tirés, alors je les pousse dans un console.messagestableau que je crée. J'ai également ajouté une fonction console.dump()pour faciliter la visualisation de l'ensemble du journal. console.clear()videra la file d'attente des messages.

Cette solution "gère" également les autres méthodes de la console (qui, je crois, proviennent toutes de l' API Firebug Console )

Enfin, cette solution se présente sous la forme d'une IIFE , elle ne pollue donc pas le périmètre global. L'argument de la fonction de secours est défini au bas du code.

Je viens de le déposer dans mon fichier JS maître qui est inclus sur chaque page, et je l'oublie.

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

Quelques informations supplémentaires

La ligne var args = Array.prototype.slice.call(arguments);crée un tableau à partir de l' argumentsobjet. Ceci est nécessaire car les arguments ne sont pas vraiment un tableau .

trap()est un gestionnaire par défaut pour l'une des fonctions de l'API. Je passe les arguments à messageafin que vous obteniez un journal des arguments qui ont été passés à tout appel API (pas seulement console.log).

Éditer

J'ai ajouté un tableau supplémentaire console.rawqui capture les arguments exactement tels qu'ils ont été transmis trap(). J'ai réalisé que la args.join(' ')conversion d'objets en chaîne "[object Object]"pouvait parfois être indésirable. Merci bfontaine pour la suggestion .

Walter Stabosz
la source
4
+1 C'est la seule solution qui commence à avoir un sens. Dans quel monde ne voudriez-vous pas voir les messages que vous envoyez explicitement à la console!
Precastic
Très bonne réponse. J'ai vraiment aimé l'article de l'IIFE que vous avez mentionné, probablement l'un des meilleurs que j'ai lus jusqu'à présent. Pourriez-vous expliquer quel est le but de ces deux lignes en trapfonction var args = Array.prototype.slice.call(arguments); var message = args.join(' ');:? Pourquoi passez-vous les arguments à travers cela au message?
user1555863
1
@ user1555863 J'ai mis à jour ma réponse pour répondre à vos questions, voir la section sous le code.
Walter Stabosz
1
Je pense que la deuxième ligne de votre fonction "console.clear ()" devrait lire "console.raw.length = 0", au lieu de "console.row.length = 0".
Steve J
52

Il convient de noter que console.logdans IE8 n'est pas une véritable fonction Javascript. Il ne prend pas en charge les méthodes applyor call.

James Wheare
la source
3
+1 C'est mon erreur précise ce matin. J'essaie d'appliquer des arguments à console.log et IE8 me déteste.
Bernhard Hofmann
[blague] Microsoft dit "il n'est pas sûr pour nous de laisser les gens écraser l'objet console": /
Tom Roggero
1
J'utilise: console.log=Function.prototype.bind.call(console.log,console);pour contourner cela.
mowwwalker
1
IE8 n'en a pas bind.
katspaugh
44

En supposant que vous ne vous souciez pas d'un repli d'alerte, voici un moyen encore plus concis de contourner les lacunes d'Internet Explorer:

var console=console||{"log":function(){}};
Leif Wickland
la source
+1 Puisque je délimite mon code dans une fonction anonyme, placer la console dans une variable comme celle-ci est la meilleure solution pour moi. M'aide à ne pas interférer avec tout autre accrochage de console en cours dans d'autres bibliothèques.
Codesleuth
2
Vous souhaitez démarrer la journalisation dès l'ouverture des outils de développement. Si vous placez cette solution dans une portée de longue durée (par exemple, enregistre les fonctions internes en tant que rappels), elle continuera à utiliser le repli silencieux.
Beni Cherniavsky-Paskin
+ 1 / -1 = 0: +1 car la solution devrait être davantage basée sur la prévention de console.logs de casser un site dans IE - pas utilisé pour déboguer ... Si vous voulez déboguer, appuyez simplement sur f12 et ouvrez la console: ) -1 car vous devez vérifier si la console existe avant de l'écraser.
1nfiniti
Certains plugins IE définissent console et console.log, mais comme des objets vides, pas des fonctions.
Lilith River
24

J'aime vraiment l'approche affichée par "orange80". Il est élégant car vous pouvez le régler une fois et l'oublier.

Les autres approches exigent que vous fassiez quelque chose de différent (appelez quelque chose console.log() chaque fois), ce qui ne fait que demander des ennuis… Je sais que j'oublierais finalement.

Je suis allé un peu plus loin, en enveloppant le code dans une fonction utilitaire que vous pouvez appeler une fois au début de votre javascript, n'importe où tant que c'est avant toute journalisation. (J'installe ceci dans le produit de routeur de données d'événement de mon entreprise. Cela aidera à simplifier la conception multi-navigateur de sa nouvelle interface d'administration.)

/**
 * 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
la source
1
Heureux que vous l'aimiez :-) Je l'utilise pour la raison exacte que vous mentionnez - b / c c'est une bonne sécurité. Il est tout simplement trop facile de mettre des instructions "console.log" dans votre code pour le développement et d'oublier de les supprimer plus tard. Au moins, si vous faites cela et que vous le placez en haut de chaque fichier où vous utilisez console.log, vous n'aurez jamais le site qui casse dans les navigateurs des clients car ils échouent sur console.log. M'a sauvé avant!
Belles
1
"Il est tout simplement trop facile de ... oublier de les supprimer". Une chose utile que je fais toujours avec la journalisation du débogage temporaire est le préfixe du code avec un commentaire vide, /**/console.log("...");il est donc facile de rechercher et de localiser le code temporaire.
Lawrence Dol
8

Si vous obtenez «indéfini» pour tous vos appels console.log, cela signifie probablement que vous avez toujours un ancien firebuglite chargé (firebug.js). Il remplacera toutes les fonctions valides du console.log d'IE8 même si elles existent. C'est ce qui m'est arrivé de toute façon.

Recherchez un autre code remplaçant l'objet console.

user168290
la source
5

La meilleure solution pour tout navigateur dépourvu de console est:

// 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
la source
1
Cela a le problème flagrant que les objets ou les chaînes enregistrés à l'aide de console.group ou console.GroupCollapsed disparaîtront complètement. Ce n'est pas nécessaire, ils doivent être mappés sur console.log, s'il est disponible.
Ben
3

Il y a tellement de réponses. Ma solution pour cela était:

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

En bref, si console.log n'existe pas (ou dans ce cas, n'est pas ouvert), stockez le journal dans un tableau d'espace de noms global. De cette façon, vous n'êtes pas harcelé par des millions d'alertes et vous pouvez toujours afficher vos journaux avec la console développeur ouverte ou fermée.

calcazar
la source
2
if (window.console && 'function' === typeof window.console.log) {
    window.console.log (o);
}
Balázs Németh
la source
Voulez-vous dire que cela window.console.log()pourrait être disponible dans IE8 même si ce console.log()n'est pas le cas?
LarsH
Le problème ici est que typeof window.console.log === "object", pas"function"
Isochronous
2

Voici mon "IE s'il vous plaît ne plantage pas"

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

J'ai trouvé ça sur 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
la source
1

J'utilise l'approche de Walter d'en haut (voir: https://stackoverflow.com/a/14246240/3076102 )

Je mélange une solution que j'ai trouvée ici https://stackoverflow.com/a/7967670 pour afficher correctement les objets.

Cela signifie que la fonction piège devient:

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

J'espère que ceci est utile:-)

Raymond Elferink
la source
0

Cela fonctionne dans IE8. Ouvrez les outils de développement d'IE8 en appuyant sur F12.

>>console.log('test')
LOG: test
Konstantin Tarkus
la source
6
Cela émet "indéfini" dans mon cas.
Acme
6
Comme l'a souligné Monsieur Lucky: "console.log n'est disponible qu'après avoir ouvert les outils de développement (F12 pour les ouvrir et les fermer)."
The Silencer
0

J'aime cette méthode (en utilisant la documentation de jquery prête) ... elle vous permet d'utiliser la console même dans ie ... le seul problème est que vous devez recharger la page si vous ouvrez les outils de développement de ie après le chargement de la page ...

cela pourrait être plus luisant en tenant compte de toutes les fonctions, mais je n'utilise que log donc c'est ce que je fais.

//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
        }})();
    }
});
user3560902
la source
0

Voici une version qui se connecte à la console lorsque les outils de développement sont ouverts et non lorsqu'ils sont fermés.

(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
la source
Bien qu'il soit de portée limitée, pourrait prendre en charge le cas où IE8 DevTools sont ouverts au milieu de l'exécution de code, mais cela ne fonctionne pas dans IE8, console.log est un objet, donc il n'a pas de applyméthode.
Nishi
0

Créez votre propre console en html .... ;-) Cela peut être amélioré mais vous pouvez commencer par:

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
la source