JavaScript:将console.log输出到HTML

86
我想把console.log输出写到一个
层中。


例如:

document.write(console.log(5+1)); //Incorrect, random example

有人能给我提供解决我的问题的方案吗?

谢谢。

编辑:

我的意思是,例如:

console.log("hi");

它在屏幕上显示输出"hi"。

注意:例子:http://labs.codecademy.com/#:workspace


console.logdocument.write 都是副作用,它们不返回任何值。 - elclanrs
那么无法将 console.log 的输出打印到屏幕上吗? - leonneo
1
控制台输出意味着什么?输出是 6,对吗?你可以使用 document.write(5+1) 来评估这个表达式。 - elclanrs
1
我想要将 console.log 的输出打印到屏幕上。 - leonneo
我指的是问题中给出的示例。 - leonneo
显示剩余3条评论
7个回答

124

您可以覆盖默认实现的console.log()

(function () {
    var old = console.log;
    var logger = document.getElementById('log');
    console.log = function (message) {
        if (typeof message == 'object') {
            logger.innerHTML += (JSON && JSON.stringify ? JSON.stringify(message) : message) + '<br />';
        } else {
            logger.innerHTML += message + '<br />';
        }
    }
})();

演示: Fiddle


String(message)?为什么不直接用 message - zerkms
@Nitin的答案更好,因为它处理了对象:https://dev59.com/pWIj5IYBdhLWcg3wcEuI#35449256 - Ryan
3
除了继续使用默认的console.log功能之外,还需要在新的console.log函数的结尾处添加'old(message);'。 - Will Kru
你能展示一下如何像在console.log中一样为上述函数的输出添加颜色吗?谢谢! - Hugo Barbosa
尝试像这样格式化您的字符串化:JSON.stringify(message,undefined,4),而不仅仅是普通的JSON.stringify(message)-以后您会感谢我的。 - Joe Johnston
console.log("name is:",name); ??? - Rameez Rami

36

稍作改进 @arun-p-johny 的答案:

在 HTML 中,

<pre id="log"></pre>
在js中,
(function () {
    var old = console.log;
    var logger = document.getElementById('log');
    console.log = function () {
      for (var i = 0; i < arguments.length; i++) {
        if (typeof arguments[i] == 'object') {
            logger.innerHTML += (JSON && JSON.stringify ? JSON.stringify(arguments[i], undefined, 2) : arguments[i]) + '<br />';
        } else {
            logger.innerHTML += arguments[i] + '<br />';
        }
      }
    }
})();

开始使用:

console.log('How', true, new Date());

3
为保留原有的 console.log 功能,需要在新的控制台日志函数末尾添加 old(...arguments);。记得使用扩展运算符! - Tim
4
old.apply(console, arguments); 的作用是保留原有的参数,也可以起到相同的效果。 - Tim
2
我有点困惑,我对Javascript还很陌生,这个函数的结构是什么?第一个括号是干嘛用的?最后一对括号又是什么意思? - AdrianL
1
@DaPole 它被包裹在一个自执行匿名函数中。 - Chords

19

有点晚了,但我进一步完善了@Hristiyan Dodov的答案

所有控制台方法现在都被重新连接,并且在文本溢出的情况下,包括一个可选的自动滚动到底部功能。颜色现在基于日志记录方法而不是参数。

rewireLoggingToElement(
    () => document.getElementById("log"),
    () => document.getElementById("log-container"), true);

function rewireLoggingToElement(eleLocator, eleOverflowLocator, autoScroll) {
    fixLoggingFunc('log');
    fixLoggingFunc('debug');
    fixLoggingFunc('warn');
    fixLoggingFunc('error');
    fixLoggingFunc('info');

    function fixLoggingFunc(name) {
        console['old' + name] = console[name];
        console[name] = function(...arguments) {
            const output = produceOutput(name, arguments);
            const eleLog = eleLocator();

            if (autoScroll) {
                const eleContainerLog = eleOverflowLocator();
                const isScrolledToBottom = eleContainerLog.scrollHeight - eleContainerLog.clientHeight <= eleContainerLog.scrollTop + 1;
                eleLog.innerHTML += output + "<br>";
                if (isScrolledToBottom) {
                    eleContainerLog.scrollTop = eleContainerLog.scrollHeight - eleContainerLog.clientHeight;
                }
            } else {
                eleLog.innerHTML += output + "<br>";
            }

            console['old' + name].apply(undefined, arguments);
        };
    }

    function produceOutput(name, args) {
        return args.reduce((output, arg) => {
            return output +
                "<span class=\"log-" + (typeof arg) + " log-" + name + "\">" +
                    (typeof arg === "object" && (JSON || {}).stringify ? JSON.stringify(arg) : arg) +
                "</span>&nbsp;";
        }, '');
    }
}


setInterval(() => {
  const method = (['log', 'debug', 'warn', 'error', 'info'][Math.floor(Math.random() * 5)]);
  console[method](method, 'logging something...');
}, 200);
#log-container { overflow: auto; height: 150px; }

.log-warn { color: orange }
.log-error { color: red }
.log-info { color: skyblue }
.log-log { color: silver }

.log-warn, .log-error { font-weight: bold; }
<div id="log-container">
  <pre id="log"></pre>
</div>


1
Botteman,似乎在安卓的Chrome 68上无法工作! - r.zarei
1
现在的问题是,我如何轻松地添加console.time和console.timeEnd? - Gareth Compton
这段代码是什么意思? rewireLoggingToElement( () => document.getElementById("log"), () => document.getElementById("log-container"), true);为什么要将箭头函数传递给该函数?虽然它是有效的JavaScript,但对我来说似乎很陌生。 - Gaetano Piazzolla
我无论如何都无法将正在进行的更新内容写入“log-container”。我在循环内运行具有async: falseajax调用的嵌套循环,其中有许多console.log调用,但输出只在我的循环完成处理后才会更新。(我的动画也遇到了同样的问题,它只在我的循环完成后才播放。)我尝试在ajaxsuccess: function( result ) {中添加一个调用,但无法使其正常工作。感谢您的帮助。 - MeSo2
PS. 我刚刚注意到,在循环过程中如果我改变窗口大小,那么log-container会出现零散的写入。所以也许我只需要加入一些暂停来更新,以便有机会赶上循环。不确定如何实现... - MeSo2
显示剩余3条评论

18

我稍晚地提供了 Arun P Johny 的答案 更高级的版本。他的解决方案无法处理多个 console.log() 参数,也无法访问原始函数。

这是我的版本:

(function (logger) {
    console.old = console.log;
    console.log = function () {
        var output = "", arg, i;

        for (i = 0; i < arguments.length; i++) {
            arg = arguments[i];
            output += "<span class=\"log-" + (typeof arg) + "\">";

            if (
                typeof arg === "object" &&
                typeof JSON === "object" &&
                typeof JSON.stringify === "function"
            ) {
                output += JSON.stringify(arg);   
            } else {
                output += arg;   
            }

            output += "</span>&nbsp;";
        }

        logger.innerHTML += output + "<br>";
        console.old.apply(undefined, arguments);
    };
})(document.getElementById("logger"));

// Testing
console.log("Hi!", {a:3, b:6}, 42, true);
console.log("Multiple", "arguments", "here");
console.log(null, undefined);
console.old("Eyy, that's the old and boring one.");
body {background: #333;}
.log-boolean,
.log-undefined {color: magenta;}
.log-object,
.log-string {color: orange;}
.log-number {color: cyan;}
<pre id="logger"></pre>

我进一步添加了一个类来为每个日志着色,这些日志与Chrome控制台中看到的所有参数一样。您还可以通过console.old()访问旧日志。

以下是上面脚本的压缩版本,供您内嵌使用:

<script>
    !function(o){console.old=console.log,console.log=function(){var n,e,t="";for(e=0;e<arguments.length;e++)t+='<span class="log-'+typeof(n=arguments[e])+'">',"object"==typeof n&&"object"==typeof JSON&&"function"==typeof JSON.stringify?t+=JSON.stringify(n):t+=n,t+="</span>&nbsp;";o.innerHTML+=t+"<br>",console.old.apply(void 0,arguments)}}
    (document.body);
</script>

将括号中的document.body替换为您想要登录的任何元素。

将这个解决方案进一步扩展。现在包括溢出时的自动滚动,并重新连接所有控制台方法,而不仅仅是.log() - Benny Bottema
我知道这是一个旧的话题,但我刚刚开始在移动应用中使用它。一个问题:如何显示生成日志的文件和行? - Mat
我认为你做不到。你根本无法获得那些信息。如果这是一个应用程序,你应该寻找其他调试选项,比如USB调试。 - dodov
再多做一点,加上清晰的控制台!;-) - vwvan

7
创建一个输出
<div id="output"></div>

使用JavaScript向其写入内容
var output = document.getElementById("output");
output.innerHTML = "hello world";

如果您希望处理更复杂的输出值,可以使用 JSON.stringify
var myObj = {foo: "bar"};
output.innerHTML = JSON.stringify(myObj);

2

这篇文章对我帮助很大,经过几次迭代,以下就是我们现在使用的方法。

这个想法是将日志消息和错误信息发布到HTML中,例如如果您需要调试JS并且无法访问控制台。

您需要将 'console.log' 更改为 'logThis',因为不建议更改本机功能。

您将获得:

  • 一个简单明了的 'logThis' 函数,可以显示每行字符串和对象以及当前日期和时间
  • 一个置顶窗口(只在需要时显示)。
  • 可嵌入 '.catch' 中查看来自承诺的相关错误。
  • 不更改默认 console.log 行为
  • 消息也会出现在控制台中。

function logThis(message) {
  // if we pass an Error object, message.stack will have all the details, otherwise give us a string
  if (typeof message === 'object') {
    message = message.stack || objToString(message);
  }

  console.log(message);

  // create the message line with current time
  var today = new Date();
  var date = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate();
  var time = today.getHours() + ':' + today.getMinutes() + ':' + today.getSeconds();
  var dateTime = date + ' ' + time + ' ';

  //insert line
  document.getElementById('logger').insertAdjacentHTML('afterbegin', dateTime + message + '<br>');
}

function objToString(obj) {
  var str = 'Object: ';
  for (var p in obj) {
    if (obj.hasOwnProperty(p)) {
      str += p + '::' + obj[p] + ',\n';
    }
  }
  return str;
}

const object1 = {
  a: 'somestring',
  b: 42,
  c: false
};

logThis(object1)
logThis('And all the roads we have to walk are winding, And all the lights that lead us there are blinding')
#logWindow {
  overflow: auto;
  position: absolute;
  width: 90%;
  height: 90%;
  top: 5%;
  left: 5%;
  right: 5%;
  bottom: 5%;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 20;
}
<div id="logWindow">
  <pre id="logger"></pre>
</div>

感谢这个答案,JSON.stringify()对此无效。


1

请复制并粘贴以下代码

console.log = (...e) => {for(var i=0;i<e.length;i++){document.getElementById("log").innerHTML += (typeof(e[i]) == "object" ? JSON.stringify(e[i]):e[i]) + "<br />"}};

console.log = (...e) => {for(var i=0;i<e.length;i++){document.getElementById("log").innerHTML += (typeof(e[i]) == "object" ? JSON.stringify(e[i]):e[i]) + "<br />"}};

console.log("Hello world",{objectWorks:true},["Array works?","Yes"])
<div id="log"></div>

如果您想要使用默认的 "console.log",只需将 "console.log" 更改为 "var CustomNameOfLog"。或者,只需复制并粘贴下面的代码。
var CustomNameOfLog = (...e) => {for(var i=0;i<e.length;i++){document.getElementById("log").innerHTML += (typeof(e[i]) == "object" ? JSON.stringify(e[i]):e[i]) + "<br />"}};

var customNameOfLog = (...e) => {for(var i=0;i<e.length;i++){document.getElementById("log").innerHTML += (typeof(e[i]) == "object" ? JSON.stringify(e[i]):e[i]) + "<br />"}};

customNameOfLog("Hello world",{objectWorks:true},["Array works?","Yes"])
<div id="log"></div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接