Що сталося з console.log в IE8?


254

Відповідно до цієї публікації це було в бета-версії, але це не у випуску?


65
console.log є в IE8, але consoleоб'єкт не створюється, поки ви не відкриєте DevTools. Тому заклик до console.logможе призвести до помилки, наприклад, якщо це відбувається при завантаженні сторінки, перш ніж у вас є шанс відкрити інструменти розробки. Перемоги відповідь тут пояснює це більш докладно.
SDC

Відповіді:


229

Ще краще для резервного:


   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
Це настільки непрактично - як ви могли налагодити веб-сайт тим, що передає сповіщення про кожен виклик console.log (). Що робити, якщо у вашому коді є 10+ дзвінків, щоб увійти (). Що робити, якщо msg є об’єктом? Відповідь Вальтера має набагато більше сенсу, як відправна точка.
Передбачливий

7
@Precastic: Люди просто перестануть користуватися браузером: P
Amogh Talpallikar

Дивіться мій коментар до відповіді містера Лакі.
Даніель Шиллінг

1
ненав’язливою (хоча і недосконалою) альтернативною альтернативою є встановлення document.title. Принаймні, він не блокує браузер модальним попередженням.
brennanyoung

257

console.log доступний лише після того, як ви відкрили Інструменти для розробників (F12, щоб увімкнути його відкритим і закритим). Найсмішніше, що після того, як ви відкрили його, ви можете його закрити, а потім все ще опублікувати на ньому через дзвінки console.log, і вони будуть помічені, коли ви його знову відкриєте. Я думаю, що це якась помилка, і може бути виправлена, але ми побачимо.

Я, мабуть, просто використаю щось подібне:

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

і навіть простіше:

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

11
Так чи інакше, ви не повинні сліпо викликати console.log, оскільки у інших $-браузерів його немає, і, отже, померти з помилкою JavaScript. +1
Кент Фредрік

8
ви, мабуть, хочете вимкнути сліди перед тим, як все-таки звільнитись;)
Кент Фредрік

2
Тут є сенс не входити в систему, не відкриваючи інструменти для розробників, але змусити це викинути виняток, якщо замість того, щоб мовчати безвідмовно, справжнє заплутане рішення.
ehdv

4
Я хочу вказати на мінус обгортання console.log, як це ... ви більше не побачите, звідки беруться ваші журнали. Я вважаю, що дуже корисно іноді, напроти чого, просто виглядає неправильно, щоб кожна консольна лінія походила з того самого місця у вашому коді.
Мартін Вестін

2
alertє зло. Деякі коди поводяться по-різному, коли використовуються сповіщення, оскільки документ втрачає фокус, що робить помилки ще складніше діагностувати або створювати ті, де раніше не було. Крім того, якщо ви випадково залишите console.logсвій код у виробничому коді, він є доброякісним (якщо припустити, що він не підірветься) - просто мовчки ввійде до консолі. Якщо ви випадково залишите alertсвій код у виробництві, користувацький досвід знищується.
Даніель Шиллінг

56

Це мій погляд на різні відповіді. Я хотів насправді побачити зареєстровані повідомлення, навіть якщо у мене не було відкрито консолі IE, коли вони були випущені, тому я натискаю їх на console.messagesмасив, який я створюю. Я також додав функцію console.dump()для полегшення перегляду всього журналу. console.clear()буде порожньою чергою повідомлень.

Це рішення також "обробляє" інші методи консолі (які, на мою думку, походять з API консолі Firebug )

Нарешті, це рішення має форму IIFE , тому не забруднює глобальну сферу застосування. Аргумент резервної функції визначається внизу коду.

Я просто опускаю його у свій головний JS-файл, який міститься на кожній сторінці, і забуваю про нього.

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

Деякі додаткові відомості

Рядок var args = Array.prototype.slice.call(arguments);створює масив з argumentsоб’єкта. Це потрібно, тому що аргументи насправді не є масивом .

trap()є обробником за замовчуванням для будь-якої з функцій API. Я передаю аргументи messageтаким чином, щоб ви отримали журнал аргументів, переданих на будь-який виклик API (не тільки console.log).

Редагувати

Я додав додатковий масив, console.rawякий фіксує аргументи точно так, як передано trap(). Я зрозумів, що args.join(' ')це перетворення об'єктів на рядок, "[object Object]"що іноді може бути небажаним. Дякую bfontaine за пропозицію .


4
+1 Це єдине рішення, яке починає мати сенс. У якому світі ви б не хотіли бачити повідомлення, які ви явно надсилаєте на консоль!
Передбачливий

Чудова відповідь. Дуже сподобалася стаття IIFE, яку ви згадали, мабуть, одна з найкращих, яку я читав до цих пір. Чи можете ви, будь ласка, пояснити, яка мета цих двох рядків у trapфункції var args = Array.prototype.slice.call(arguments); var message = args.join(' ');:? Чому ви передаєте аргументи через це в повідомлення?
користувач1555863

1
@ user1555863 Я оновив свою відповідь, щоб відповісти на ваші запитання, дивіться розділ під кодом.
Вальтер Стабош

1
Я думаю, що другий рядок функції "console.clear ()" повинен читати "console.raw.length = 0", а не "console.row.length = 0".
Стів Дж

52

Варто зазначити, що console.logв IE8 не є справжньою функцією Javascript. Він не підтримує applyабо callметоди.


3
+1 Це моя точна помилка сьогодні вранці. Я намагаюся застосувати аргументи до console.log, і IE8 мене ненавидить.
Бернхард Хофманн

[жарт] Microsoft каже, що "це небезпечно для нас, щоб люди перезаписували консольний об'єкт": /
Том Роггеро

1
Я використовував: console.log=Function.prototype.bind.call(console.log,console);щоб обійти це.
mowwwalker

1
IE8 не має bind.
katspaugh

44

Якщо припустити, що вам не байдуже резервне сповіщення, ось ще більш стислий спосіб вирішити недоліки Internet Explorer:

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

+1 Оскільки я розбираю свій код в анонімній функції, розміщення консолі в змінну, як це, є найкращим рішенням для мене. Допомагає мені не заважати будь-якому іншому підключенню консолі, що відбувається в інших бібліотеках.
Codesleuth

2
Ви хочете почати вести журнал, як тільки інструменти для розробників були відкриті. Якщо ви поставите це рішення в довготривалу область (наприклад, реєструє внутрішні функції як зворотні дзвінки), воно продовжуватиме використовувати беззвучне резервне копіювання.
Бені Чернявський-Паскін

+ 1 / -1 = 0: +1, тому що рішення повинно базуватися на тому, щоб не допустити порушення console.logs сайту в IE - не використовується для налагодження ... Якщо ви хочете налагоджувати, просто натисніть f12 та відкрийте консоль: ) -1, тому що ви повинні перевірити, чи існує консоль, перш ніж її перезаписати.
1nfiniti

Деякі плагіни IE визначають console та console.log, але як порожні об'єкти, а не функції.
Річка Ліліт

24

Мені дуже подобається підхід, опублікований "orange80". Це елегантно, тому що ви можете його встановити один раз і забути.

Інші підходи вимагають від вас зробити щось інше (називати щось інше, ніж просто console.log() кожен раз ), що просто просить клопоту ... Я знаю, що врешті-решт забуду.

Я зробив це на крок далі, увімкнувши код у функцію утиліти, яку ви можете зателефонувати один раз на початку вашого javascript, де завгодно, доки це не відбудеться перед будь-яким журналом реєстрації. (Я встановлюю це в продукт маршрутизатора даних моєї компанії. Це допоможе спростити дизайн крос-браузера нового інтерфейсу адміністратора.)

/**
 * 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
Радий, що вам це подобається :-) Я використовую його саме з тієї причини, яку ви згадали - це / це хороша безпека. Це просто занадто просто помістити деякі "console.log" заяви у свій код для розробки та забути їх видалити пізніше. Принаймні, якщо ви це зробите і помістите його вгорі кожного файлу, де ви використовуєте console.log, у вас ніколи не буде зламатися сайт у браузерах клієнтів, оскільки вони не працюють на console.log. Врятували мене раніше! Приємні покращення, btw :-)
jpswain

1
"Це просто занадто просто ... забути їх видалити". Одна корисна річ, яку я завжди роблю під час тимчасового введення помилок, - це префікс коду з порожнім коментарем, /**/console.log("...");тому легко знайти та знайти тимчасовий код.
Лоуренс Дол

8

Якщо ви отримаєте "невизначений" для всіх ваших викликів console.log, це, ймовірно, означає, що ви все ще маєте старий файл firebuglite (firebug.js). Він замінить усі дійсні функції console.log IE8, навіть якщо вони існують. Це все одно зі мною трапилось.

Перевірте інший код, що перевищує об'єкт консолі.


5

Найкраще рішення для будь-якого браузера, якому не вистачає консолі, є:

// 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
У цьому виникає яскрава проблема, що об'єкти або рядки, записані за допомогою console.group або console.GroupCollapsed, повністю зникнуть. Це непотрібно, вони повинні бути відображені в console.log, якщо він доступний.
Бен

3

Відповідей дуже багато. Моє рішення для цього було:

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

Якщо коротко, якщо console.log не існує (або в цьому випадку не відкрито), тоді зберігайте журнал у глобальному масиві просторів імен. Таким чином, ви не загрожуєте мільйонами сповіщень, і ви все одно можете переглядати свої журнали, відкриваючи або закриваючи консоль розробника.


2
якщо (window.console && 'function' === typeof window.console.log) {
    window.console.log (o);
}

Ви хочете сказати, що це window.console.log()може бути доступне в IE8 навіть тоді, коли console.log()його немає?
LarsH

Проблема тут полягає в тому typeof window.console.log === "object", що ні"function"
Ізохронний

2

Ось мій "IE, будь ласка, не збої"

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

1

Я знайшов це на 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

Я використовую підхід Вальтера зверху (див. Https://stackoverflow.com/a/14246240/3076102 )

Я змішую рішення, яке я знайшов тут https://stackoverflow.com/a/7967670, щоб правильно показати об’єкти.

Це означає, що функція пастки стає:

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

Я сподіваюся, що це корисно :-)


0

Він працює в IE8. Відкрийте Інструменти для розробників IE8, натиснувши F12.

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

6
Це в моєму випадку "невизначено".
акме

6
Як зазначив Містер Лакі: "console.log доступний лише після того, як ви відкрили Інструменти для розробників (F12, щоб увімкнути його відкритим і закритим)".
Безшумник

0

Мені подобається цей метод (з використанням док-файлу jquery готовий) ... він дозволяє використовувати консоль навіть у т. Е. ... єдиним уловом є те, що вам потрібно перезавантажити сторінку, якщо ви відкриєте інструменти розробки, тобто розроблені сторінки ...

це може бути меншим за рахунок врахування всіх функцій, але я використовую лише журнал, тому це я роблю.

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

Ось версія, яка входитиме до консолі, коли інструменти розробника відкриті, а не коли вони закриті.

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

Добре, що він обмежений за обсягом, може підтримувати випадок, коли IE8 DevTools відкритий посеред виконання коду, але він не працює в IE8, console.log є об'єктом, тому він не має applyметоду.
Ніші

0

Створіть власну консоль у html .... ;-) Це може бути додано, але ви можете почати з:

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);
        }
    };
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.