Respostas:
Ainda melhor para o fallback é o seguinte:
var alertFallback = true;
if (typeof console === "undefined" || typeof console.log === "undefined") {
console = {};
if (alertFallback) {
console.log = function(msg) {
alert(msg);
};
} else {
console.log = function() {};
}
}
O console.log estará disponível somente depois que você abrir as Ferramentas do desenvolvedor (F12 para alternar entre abrir e fechar). O engraçado é que, depois de abri-lo, você pode fechá-lo e ainda publicá-lo através das chamadas console.log, e elas serão vistas quando você o reabrir. Estou pensando que isso é um tipo de bug e pode ser corrigido, mas veremos.
Provavelmente vou usar algo assim:
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 ainda mais simples:
function trace(s) {
try { console.log(s) } catch (e) { alert(s) }
}
alert
é mau. Alguns códigos se comportam de maneira diferente quando os alertas são usados porque o documento perde o foco, tornando os bugs ainda mais difíceis de diagnosticar ou criando aqueles que não existiam antes. Além disso, se você acidentalmente deixar um console.log
no seu código de produção, é benigno (supondo que ele não exploda) - apenas registra silenciosamente no console. Se você acidentalmente deixar um alert
no seu código de produção, a experiência do usuário será arruinada.
Esta é a minha opinião sobre as várias respostas. Eu realmente queria ver as mensagens registradas, mesmo que não tivesse o console do IE aberto quando elas foram acionadas, então as empurro para uma console.messages
matriz criada por mim. Também adicionei uma função console.dump()
para facilitar a visualização de todo o log. console.clear()
esvaziará a fila de mensagens.
Essas soluções também "manipulam" os outros métodos do console (que eu acredito que todos se originam da API do Firebug Console )
Finalmente, essa solução está na forma de um IIFE , portanto, não polui o escopo global. O argumento da função de fallback é definido na parte inferior do código.
Eu apenas o solto no meu arquivo JS principal, que está incluído em todas as páginas, e esqueço.
(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)
A linha var args = Array.prototype.slice.call(arguments);
cria uma matriz do arguments
objeto. Isso é necessário porque os argumentos não são realmente uma matriz .
trap()
é um manipulador padrão para qualquer uma das funções da API. Eu passo os argumentos para message
que você obtenha um log dos argumentos que foram passados para qualquer chamada de API (não apenas console.log
).
Eu adicionei uma matriz extra console.raw
que captura os argumentos exatamente como passados trap()
. Eu percebi que args.join(' ')
estava convertendo objetos para a string "[object Object]"
que às vezes pode ser indesejável. Obrigado bfontaine pela sugestão .
trap
função var args = Array.prototype.slice.call(arguments); var message = args.join(' ');
:? Por que você passa os argumentos através disso para a mensagem?
Vale ressaltar que console.log
no IE8 não é uma verdadeira função Javascript. Não suporta os métodos apply
ou call
.
console.log=Function.prototype.bind.call(console.log,console);
para contornar isso.
bind
.
Supondo que você não se preocupe com um substituto para alertar, aqui está uma maneira ainda mais concisa de solucionar as deficiências do Internet Explorer:
var console=console||{"log":function(){}};
Eu realmente gosto da abordagem postada por "orange80". É elegante porque você pode configurá-lo uma vez e esquecê-lo.
As outras abordagens exigem que você faça algo diferente (sempre chame algo diferente do normal console.log()
), o que está apenas pedindo problemas ... Eu sei que acabaria esquecendo.
Eu dei um passo adiante, envolvendo o código em uma função de utilitário que você pode chamar uma vez no início do seu javascript, em qualquer lugar, desde que esteja antes de qualquer log. (Estou instalando isso no produto roteador de dados de eventos da minha empresa. Isso ajudará a simplificar o design entre navegadores de sua nova interface de administração.)
/**
* 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() {}; }
}
}
/**/console.log("...");
para facilitar a pesquisa e a localização do código temporário.
Se você ficar "indefinido" em todas as chamadas do console.log, isso provavelmente significa que você ainda tem um firebuglite antigo carregado (firebug.js). Ele substituirá todas as funções válidas do console.log do IE8, mesmo que elas existam. Foi o que aconteceu comigo de qualquer maneira.
Verifique se há outro código substituindo o objeto do console.
A melhor solução para qualquer navegador sem 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;
}
}
}());
Existem tantas respostas. Minha solução para isso foi:
globalNamespace.globalArray = new Array();
if (typeof console === "undefined" || typeof console.log === "undefined") {
console = {};
console.log = function(message) {globalNamespace.globalArray.push(message)};
}
Em resumo, se console.log não existir (ou, nesse caso, não estiver aberto), armazene o log em um espaço de nomes global Array. Dessa forma, você não será incomodado com milhões de alertas e ainda poderá visualizar seus logs com o console do desenvolvedor aberto ou fechado.
Encontrei isso no 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 = {});
}
} ());
Estou usando a abordagem de Walter de cima (consulte: https://stackoverflow.com/a/14246240/3076102 )
Eu misturo uma solução que encontrei aqui https://stackoverflow.com/a/7967670 para mostrar corretamente os objetos.
Isso significa que a função de interceptação se torna:
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,' ');
}
}
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 />'));
}
}
}
Espero que isto seja útil:-)
Funciona no IE8. Abra as Ferramentas de desenvolvedor do IE8 pressionando F12.
>>console.log('test')
LOG: test
Eu gosto deste método (usando o documento do jquery pronto) ... ele permite que você use o console, mesmo no ie ... só é necessário recarregar a página se você abrir as ferramentas de desenvolvimento do ie, após o carregamento da página ...
poderia ser mais lento, contabilizando todas as funções, mas eu só uso log, então é isso que faço.
//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
}})();
}
});
Aqui está uma versão que fará logon no console quando as ferramentas do desenvolvedor estiverem abertas e não quando estiverem fechadas.
(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)
apply
método.
Crie seu próprio console em html .... ;-) Isso pode ser melhorado, mas você pode começar com:
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);
}
};
}
console.log
é lá em IE8, mas oconsole
objeto não é criado até que você DevTools abertos. Portanto, uma chamada paraconsole.log
pode resultar em um erro, por exemplo, se ocorrer no carregamento da página antes que você tenha a chance de abrir as ferramentas de desenvolvimento. A resposta vencedora aqui explica mais detalhadamente.