使用css样式和任意参数自定义console.log

时间:2014-11-07 10:08:11

标签: javascript console.log

我已经检查了google dev工具的控制台(https://developer.chrome.com/devtools/docs/console),并且知道'%c'可以将CSS样式规则应用于输出字符串。

这是我的问题:
我想写一个功能redLog(msg, regExp),例如redLog('Page1, Page2', /\d/g)输出与console.log('Page%c1%c, Page%c2%c', 'color:red', 'color:black', 'color:red', 'color:black')相同的文字和样式,但任意css string('color:red', 'color:black', 'color:red', 'color:black')会让我感到困扰。
我最近的代码片段如下所示(这是我用英语发布问题的第一次体验,我不确定我的问题已经让你们清楚了。):

// redLog('Page1, Page2', /\d/g)
// function as console.log('Page%c1%c, Page%c2%c', 'color:red', 'color:black', 'color:red', 'color:black')

// msg: the output string
// regExp: when any characters match the regExp, red it
function redLog(msg, regExp) {
  var cssStr = '';

  if (msg && regExp) {
    msg = msg.replace(regExp, '%c$&%c'); // '$&' inserts the matched substring.
    console.log(msg); // i cannot determine the cssStr
  }
  else {
    console.log(msg);
  }
}

5 个答案:

答案 0 :(得分:3)

您的问题非常复杂,因为console.log需要为邮件中的每个%c添加一个css字符串参数。但是,既然你动态地这样做了,你就不能硬编码console.log的参数,导致问题的原因是你需要用一组参数调用console.log。对于此问题,可以使用.apply方法:

console.log.apply(console, args);

但是要使用它,你需要为参数设置一个数组:

var args = [msg];

并用所需数量的css样式填充它,这有点复杂,因为你需要在消息中找到%c的所有外观并在两个(或更多,如果你想要的话)css样式之间切换:

var helpString = msg;
var toggleNextString = false;
while (helpString.indexOf("%c") != -1) {
    if (!toggleNextString) args.push(cssStrNew);
    else args.push(cssStrStandard);
    toggleNextString = !toggleNextString;
    helpString = helpString.substr(helpString.indexOf("%c") + 2);
}

注意:我使用两个字符串作为标准log css和红色。

将所有这些放在一起,函数看起来像这样:

function redLog(msg, regExp) {
    var cssStrNew = 'color: red;';
    var cssStrStandard = 'color: black';

    if (msg && regExp) {
        msg = msg.replace(regExp, '%c$&%c');
        var args = [msg];
        var helpString = msg;
        var toggleNextString = false;
        while (helpString.indexOf("%c") != -1) {
            if (!toggleNextString) args.push(cssStrNew);
            else args.push(cssStrStandard);
            toggleNextString = !toggleNextString;
            helpString = helpString.substr(helpString.indexOf("%c") + 2);
        }
        console.log.apply(console, args);
    } else {
        msg = "%c" + msg
        console.log(msg, cssStrNew);
    }
}

这是有效的fiddle

重要提示:%c并非在所有浏览器中都有效(对于Firefox,您可以使用Firebug)(afaik)

答案 1 :(得分:0)

试试这个,尽管你仍然需要在regExp上工作。这只是一个提示(如何用颜色显示您的消息),您的问题更复杂,有点凌乱。您试图在函数中添加几个参数,您应该尝试使用1参数颜色并创建一个数组。在功能内部,您可以根据需要正确组织它。

EDIT2。结果是Page 1 ,Page%c2,其中(%c2不想在这里变粗)粗体代表蓝色。据我所知,%c没有结束括号,所以你需要用逗号(,) - >来爆炸参数1。分配给表格和午餐console.log foreach元素在数组中。

if (msg && regExp) {
    msg = msg.replace(regExp, '%c$&'); // '$&' inserts the matched substring.

    console.log(""+msg+"", cssStr);
  }

  function redLog(msg, regExp) {
      var cssStr = 'color: blue; font-size: x-large';

      if (msg && regExp) {
        msg = msg.replace(regExp, '%c$&%c'); // '$&' inserts the matched substring.

        console.log("%c"+msg+"", cssStr);
      }
      else {
        console.log(msg);
      }
    }
     redLog('Page1, Page2', /\d/g);

答案 2 :(得分:0)

对于每个%c,都需要有一种风格。在您的情况下,如果您只想要突出显示数字,那么您也可以通过将高亮颜色和普通颜色作为参数来使您的函数变得通用:

function colorLog(string, regexp, style, normalStyle) {
    var msg = string.replace(regexp, function (s) {
        return "%c" + s + "%c"
    });
    var css = [msg];
    var occurances = string.match(regexp).length;
    while (css.length < occurances * 2) css = css.concat([style, normalStyle]);
    console.log.apply(console, css);
}

然后你这样称呼它:

colorLog('Page-1, 23rd-Page, Page-3', /\d+/g, 'color:blue', 'color:black');

我们的想法是用字符串创建一个数组并使用apply将其展平。您可以通过仅传递颜色名称并在函数内创建样式字符串来进一步简化调用。

只需进行微小的更改,即可使用不同颜色的多行。

演示:http://jsfiddle.net/abhitalks/ydLmtm3a/4/

答案 3 :(得分:0)

非常感谢@Markai和@abhitalks,&#34; console.log.apply(console,args)&#34;确实是我问题的关键。 以下是我对Markai启发的解决方案。

&#13;
&#13;
function colorLog(str, regExp, style, normalStyle) {
  if (str && regExp) {
    var css = [],
        i = 1, // css[0] is reserved for msg
        msg = str.replace(regExp, function (m) {
          css[i++] = style;
          css[i++] = normalStyle;
          return '%c' + m + '%c';
        });

    css[0] = msg;

    console.log.apply(console, css);
  }
  else {
    console.log(str);
  }
}

function redLog(str, regExp) {
  colorLog(str, regExp, 'color:red', 'color:black');
}

redLog('Page-1, 23rd-Page, Page-3', /\d+/g);
&#13;
&#13;
&#13;

答案 4 :(得分:0)

С甚至更短:

string='';//random string for painting
//color classifier - 6 types of non-breaking space:
for(let i=120;i--;) string+=`${'\u180E\u200B\u200C\u200D\u2060\uFEFF'[6*Math.random()^0]}${'+-0'[3*Math.random()^0]}`;

css = [string];//preparing an array for spread
//we are returning the replaced string in css[0], using as the second argument .replace() a arrow function (which writes to a global variables):
css[0] = css[0].replace(/(\u180E[\+\-0])|(\u200B[\+\-0])|(\u200C[\+\-0])|(\u200D[\+\-0])|(\u2060[\+\-0])|(\uFEFF[\+\-0])/g, (match, $1, $2, $3, $4, $5, $6) => {
    if ($1) {css.push('color: blue;')}
    if ($2) {css.push('color: red;')}
    if ($3) {css.push('color: green;')}
    if ($4) {css.push('color: yellow;')}
    if ($5) {css.push('color: magenta;')}
    if ($6) {css.push('color: cyan;')}
return`%c${match}`});//so that neighboring '%c' do not overlap
console.log(...css);

这里我们不使用标志和显式循环。我们仅使用一个功能。您可以在一行上为全局变量css [](如“ switch ... case”)编写多项选择指令:

css.push(`color: ${'blue red green yellow magenta cyan'.split(' ')[Math.log2(+('0b'+[$6, $5, $4, $3, $2, $1].map(e=>+!!e).join('')))]};`);

–在正则表达式捕获在位字段处转换的组的第一步数组中,进一步找到log 2 field ),它是颜色数组中的位置在RPN。因此该函数的长度为5行,不计入包含'random()'的前两行进行测试(您也可以使用递归在一行上进行写:

css = [(s=>(f = (i, recursion =_=>(s+=`${'\u180E\u200B\u200C\u200D\u2060\uFEFF'[6*Math.random()^0]}${'+-0'[3*Math.random()^0]}`, f(--i)))=>!i? s :recursion())(120))('')];

)。

因此,理论上我们最多可以使用6个! = 720色,即您需要&h100 3 / 6! = 23302组,用于深度为24位的标准调色板。

在此页面上通过浏览器

打开控制台并运行:

(a => (a.type = 'text/javascript', a.id = 'demo_console', a.innerHTML = 
`const css = [(s=>(f = (i, recursion =_=>(s+=\`$\{'\u180E\u200B\u200C\u200D\u2060\uFEFF'[6*Math.random()^0]}$\{'+-0'[3*Math.random()^0]}\`, f(--i)))=>!i? s :recursion())(120))('')];
css[0] = css[0].replace(/(\u180E[\+\-0])|(\u200B[\+\-0])|(\u200C[\+\-0])|(\u200D[\+\-0])|(\u2060[\+\-0])|(\uFEFF[\+\-0])/g, (match, $1, $2, $3, $4, $5, $6)=>\{
	css.push(\`color: $\{'blue red green yellow magenta cyan'.split(' ')[Math.log2(+('0b'+[$6, $5, $4, $3, $2, $1].map(e=>+!!e).join('')))]};\`);
return\`%c$\{match}\`});
console.log(...css);`
))(document.getElementsByTagName('head')[0].appendChild(document.createElement('script')))