Co się stało z console.log w IE8?

254

Według tego postu była w fazie beta, ale nie ma jej w wydaniu?

leeand00
źródło
65
console.log Jest tam w IE8, ale consoleobiekt nie jest tworzony dopóki nie otworzysz DevTools. Dlatego wywołanie do console.logmoże spowodować błąd, na przykład, jeśli wystąpi on podczas ładowania strony, zanim będzie można otworzyć narzędzia programistyczne. Wygranej tutaj odpowiedź wyjaśnia to w sposób bardziej szczegółowy.
SDC

Odpowiedzi:

229

Jeszcze lepszym rozwiązaniem w przypadku awarii jest:


   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
źródło
71
Jest to tak niepraktyczne - jak można debugować witrynę za pomocą czegoś, co generuje alert dla każdego wywołania konsoli.log (). Co jeśli masz ponad 10 wywołań do logowania () w kodzie? Co jeśli msg jest obiektem? Odpowiedź Waltera ma znacznie większy sens jako punkt wyjścia.
Precastic
7
@Precastic: Ludzie przestaną korzystać z przeglądarki: P
Amogh Talpallikar
Zobacz mój komentarz do odpowiedzi pana Lucky'ego.
Daniel Schilling
1
dyskretną (choć niedoskonałą) alternatywną alternatywą jest ustawienie document.title. Przynajmniej nie blokuje przeglądarki alarmem modalnym.
brennanyoung
257

Plik console.log jest dostępny tylko po otwarciu Narzędzi programisty (klawisz F12, aby przełączyć go w tryb otwierania i zamykania). Zabawne jest to, że po otwarciu możesz go zamknąć, a następnie opublikować na nim za pośrednictwem połączeń na konsoli.log, a będą one widoczne po ponownym otwarciu. Myślę, że to rodzaj błędu i może zostać naprawiony, ale zobaczymy.

Prawdopodobnie użyję czegoś takiego:

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

a jeszcze prostsze:

function trace(s) {
  try { console.log(s) } catch (e) { alert(s) }
}
Pan Lucky
źródło
11
Tak czy inaczej, nie powinieneś dzwonić na konsolę.log na ślepo, ponieważ $ inne przeglądarki mogą go nie mieć i dlatego umrą z powodu błędu JavaScript. +1
Kent Fredric
8
i tak prawdopodobnie będziesz chciał wyłączyć ślady przed wydaniem;)
Kent Fredric,
2
Rozsądne jest, aby nie logować się bez otwartych narzędzi programistycznych, ale sprawienie, by rzucało wyjątek, jeśli zamiast zawieść po cichu, jest naprawdę mylącą decyzją.
ehdv
4
Chcę wskazać wadę owijania konsoli. Log taki jak ten ... nie zobaczysz już, skąd pochodzi twoje logowanie. Uważam, że czasami bardzo użyteczne wydaje się, że każda linia konsoli pochodzi dokładnie z tej samej lokalizacji w kodzie.
Martin Westin,
2
alertjest zły. Niektóre kody zachowują się inaczej, gdy używane są alerty, ponieważ dokument traci ostrość, co jeszcze bardziej utrudnia zdiagnozowanie błędów lub tworzenie błędów tam, gdzie ich wcześniej nie było. Ponadto, jeśli przypadkowo pozostawisz a console.logw kodzie produkcyjnym, jest on łagodny (zakładając, że nie wybuchnie) - po prostu cicho loguje się do konsoli. Jeśli przypadkowo pozostawisz alertw kodzie produkcyjnym, środowisko użytkownika jest zrujnowane.
Daniel Schilling
56

To jest moje zdanie na temat różnych odpowiedzi. Chciałem zobaczyć zarejestrowane wiadomości, nawet jeśli nie miałem otwartej konsoli IE podczas ich uruchamiania, więc wpycham je do console.messagestablicy, którą tworzę. Dodałem również funkcjęconsole.dump() ułatwiającą przeglądanie całego dziennika. console.clear()opróżni kolejkę komunikatów.

To rozwiązanie „obsługuje” także inne metody konsoli (które, jak sądzę, wszystkie pochodzą z interfejsu API konsoli Firebug )

Wreszcie, to rozwiązanie ma postać IIFE , więc nie zanieczyszcza globalnego zasięgu. Argument funkcji rezerwowej jest zdefiniowany na dole kodu.

Po prostu upuszczam go w moim głównym pliku JS, który znajduje się na każdej stronie, i zapominam o nim.

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

Kilka dodatkowych informacji

Linia var args = Array.prototype.slice.call(arguments);tworzy tablicę z argumentsobiektu. Jest to wymagane, ponieważ argumenty tak naprawdę nie są tablicą .

trap()jest domyślnym modułem obsługi dowolnej funkcji API. Przekazuję argumenty, aby messageuzyskać dziennik argumentów, które zostały przekazane do dowolnego wywołania API (nie tylko console.log).

Edytować

Dodałem dodatkową tablicę, console.rawktóra przechwytuje argumenty dokładnie tak, jak przekazano trap(). Uświadomiłem sobie, że args.join(' ')konwertuje obiekty na ciąg, "[object Object]"co może być czasem niepożądane. Dzięki bfontaine za sugestię .

Walter Stabosz
źródło
4
+1 To jedyne rozwiązanie, które zaczyna mieć sens. W jakim świecie nie chciałbyś widzieć wiadomości, które wyraźnie wysyłasz na konsolę!
Precastic
Świetna odpowiedź. Naprawdę podobał mi się artykuł IIFE, o którym wspominałeś, prawdopodobnie jeden z najlepszych, jakie do tej pory przeczytałem. Czy możesz wyjaśnić, jaki jest cel tych dwóch wierszy w trapfunkcji var args = Array.prototype.slice.call(arguments); var message = args.join(' ');:? Dlaczego przekazujesz te argumenty do wiadomości?
user1555863,
1
@ user1555863 Zaktualizowałem swoją odpowiedź, aby odpowiedzieć na twoje pytania, zobacz sekcję poniżej kodu.
Walter Stabosz,
1
Myślę, że drugi wiersz funkcji „console.clear ()” powinien brzmieć „console.raw.length = 0”, a nie „console.row.length = 0”.
Steve J
52

Warto zauważyć, że console.logw IE8 nie jest prawdziwą funkcją Javascript. Nie obsługuje metod applylub call.

James Wheare
źródło
3
+1 To jest mój dokładny błąd dziś rano. Próbuję zastosować argumenty do pliku console.log, a IE8 mnie nienawidzi.
Bernhard Hofmann
[żart] Microsoft mówi: „Nie jest dla nas bezpieczne, aby pozwolić nam na zastąpienie obiektu konsoli”: /
Tom Roggero,
1
Używałem: console.log=Function.prototype.bind.call(console.log,console);do obejścia tego.
mowwwalker 12.01.13
1
IE8 nie ma bind.
katspaugh
44

Zakładając, że nie przejmujesz się awarią polegającą na ostrzeżeniu, oto jeszcze bardziej zwięzły sposób obejścia wad programu Internet Explorer:

var console=console||{"log":function(){}};
Leif Wickland
źródło
+1 Ponieważ szukam kodu w anonimowej funkcji, umieszczenie konsoli w takiej zmiennej jest dla mnie najlepszym rozwiązaniem. Pomaga mi nie zakłócać żadnego innego przechwytywania konsoli w innych bibliotekach.
Codesleuth,
2
Chcesz rozpocząć rejestrowanie, gdy tylko narzędzia programistyczne zostaną otwarte. Jeśli umieścisz to rozwiązanie w długofalowym zakresie (np. Rejestruje funkcje wewnętrzne jako wywołania zwrotne), będzie ono nadal używać cichego powrotu.
Beni Cherniavsky-Paskin
+ 1 / -1 = 0: +1, ponieważ rozwiązanie powinno w większym stopniu opierać się na zapobieganiu łamaniu witryny console.logs w IE - nieużywanym do debugowania ... Jeśli chcesz debugować, po prostu naciśnij klawisz F12 i otwórz konsolę: ) -1, ponieważ przed zastąpieniem należy sprawdzić, czy konsola istnieje.
1nfiniti,
Niektóre wtyczki IE definiują console i console.log, ale jako puste obiekty, a nie funkcje.
Lilith River,
24

Naprawdę podoba mi się podejście opublikowane przez „orange80”. Jest elegancki, ponieważ możesz go ustawić raz i zapomnieć.

Inne podejścia wymagają zrobienia czegoś innego (zadzwoń do czegoś innego niż zwykły) console.log() każdym razem ), co tylko prosi o kłopoty… Wiem, że w końcu zapomnę.

Posunąłem się o krok dalej, pakując kod w funkcję narzędzia, którą możesz wywołać raz na początku swojego javascript, w dowolnym miejscu, o ile ma to miejsce przed logowaniem. (Instaluję to w routerze do obsługi danych zdarzeń mojej firmy. Pomoże to uprościć projekt nowego interfejsu administratora w różnych przeglądarkach).

/**
 * 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
źródło
1
Cieszę się, że ci się podoba :-) Używam go z dokładnie tego powodu, o którym wspomniałeś - b / c to dobre bezpieczeństwo. Zbyt łatwo jest umieścić w kodzie niektóre instrukcje „console.log”, a potem zapomnieć o ich usunięciu. Przynajmniej jeśli to zrobisz i umieścisz go u góry każdego pliku, w którym korzystasz z pliku console.log, nigdy nie zobaczysz, że witryna pęka w przeglądarkach klientów b / c, gdy zawiodą na konsoli.log. Uratowałeś mnie wcześniej! Niezłe ulepszenia, btw :-)
jpswain
1
„Zbyt łatwo jest ... zapomnieć o ich usunięciu”. Jedną z pomocnych rzeczy, które zawsze robię z tymczasowym logowaniem debugowania, jest poprzedzenie kodu pustym komentarzem, /**/console.log("...");więc łatwo jest wyszukać i zlokalizować kod tymczasowy.
Lawrence Dol
8

Jeśli otrzymujesz „niezdefiniowane” dla wszystkich wywołań pliku console.log, prawdopodobnie oznacza to, że nadal masz załadowany stary firebuglite (firebug.js). Zastąpi wszystkie prawidłowe funkcje pliku konsoli.log IE8, nawet jeśli istnieją. I tak mi się przydarzyło.

Sprawdź, czy nie ma innego kodu przesłaniającego obiekt konsoli.

użytkownik168290
źródło
5

Najlepszym rozwiązaniem dla każdej przeglądarki bez konsoli jest:

// 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
źródło
1
Ma to rażący problem polegający na tym, że obiekty lub łańcuchy rejestrowane za pomocą console.group lub console.GroupCollapsed całkowicie znikną. Jest to niepotrzebne, należy je zmapować na plik console.log, jeśli jest dostępny.
Ben,
3

Jest tyle odpowiedzi. Moim rozwiązaniem tego było:

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

Krótko mówiąc, jeśli plik console.log nie istnieje (lub w tym przypadku nie jest otwarty), zapisz dziennik w globalnej macierzy przestrzeni nazw. W ten sposób nie nękają Cię miliony alertów i nadal możesz przeglądać dzienniki przy otwartej lub zamkniętej konsoli programisty.

calcazar
źródło
2
if (window.console && 'function' === typeof window.console.log) {
    window.console.log (o);
}
Balázs Németh
źródło
Czy mówisz, że window.console.log()może być dostępny w IE8, nawet jeśli console.log()nie jest?
LarsH
Problem polega na tym typeof window.console.log === "object", że nie"function"
izochroniczny
2

Oto mój „IE proszę nie upaść”

typeof console=="undefined"&&(console={});typeof console.log=="undefined"&&(console.log=function(){});
BrunoLM
źródło
1

Znalazłem to na 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
źródło
1

Używam podejścia Waltera z góry (patrz: https://stackoverflow.com/a/14246240/3076102 )

Mieszam w rozwiązaniu, które znalazłem tutaj https://stackoverflow.com/a/7967670, aby poprawnie wyświetlać obiekty.

Oznacza to, że funkcja pułapki staje się:

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

Mam nadzieję, że to jest pomocne :-)

Raymond Elferink
źródło
0

Działa w IE8. Otwórz narzędzia programistyczne IE8, naciskając klawisz F12.

>>console.log('test')
LOG: test
Konstantin Tarkus
źródło
6
W moim przypadku jest to „niezdefiniowane”.
acme
6
Jak zauważył pan Lucky: „plik console.log jest dostępny tylko po otwarciu Narzędzi programisty (klawisz F12, aby przełączyć go w tryb otwierania i zamykania)”.
The Silencer
0

Podoba mi się ta metoda (używanie gotowej dokumentacji jquery) ... pozwala ona korzystać z konsoli nawet w ie ... tylko złapać to, że musisz przeładować stronę, jeśli otworzysz np. Narzędzia programistyczne po załadowaniu strony ...

może być łatwiejszy, biorąc pod uwagę wszystkie funkcje, ale używam tylko dziennika, więc to właśnie robię.

//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
        }})();
    }
});
użytkownik3560902
źródło
0

Oto wersja, która będzie logować się do konsoli, gdy narzędzia programistyczne są otwarte, a nie gdy są zamknięte.

(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
źródło
Dobrze, że ma ograniczony zakres, może obsługiwać przypadek, gdy narzędzia Dev8 dla IE8 są otwarte w trakcie wykonywania kodu, ale nie działa w IE8, konsola.log jest obiektem, więc nie ma applymetody.
Nishi
0

Stwórz własną konsolę w HTML .... ;-) Można to poprawić, ale możesz zacząć od:

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
źródło