查看 Chrome 控制台是否打开

IT技术 javascript google-chrome firebug google-chrome-devtools
2021-02-03 15:12:46

我正在使用这个小脚本来确定 Firebug 是否打开:

if (window.console && window.console.firebug) {
    //is open
};

它运作良好。现在找了半个小时想办法检测谷歌浏览器内置的web开发者控制台是否打开,但是没有找到任何提示。

这:

if (window.console && window.console.chrome) {
    //is open
};

不起作用。

编辑:

所以似乎无法检测Chrome控制台是否打开。但是有一个“黑客”有效,但有一些缺点:

  • 控制台未停靠时将无法工作
  • 在页面加载时打开控制台时将不起作用

所以,我现在要选择 Unsigned 的答案,但是如果有人提出了一个绝妙的主意,欢迎他仍然回答,我会更改所选的答案!谢谢!

6个回答

Chrome 65+ (2018)

    r = /./
    r.toString = function () {
        document.title = '1'
    }
    console.log('%c', r);

演示:https ://jsbin.com/cecuzeb/edit?output(2018-03-16 更新)

包:https : //github.com/zswang/jdetects


当打印“Element”Chrome 开发者工具时会得到它的 id

    var checkStatus;
    
    var element = document.createElement('any');
    element.__defineGetter__('id', function() {
        checkStatus = 'on';
    });
    
    setInterval(function() {
        checkStatus = 'off';
        console.log(element);
        console.clear();
    }, 1000);

另一个版本(来自评论)

var element = new Image();
Object.defineProperty(element, 'id', {
  get: function () {
    /* TODO */
    alert('囧');
  }
});
console.log('%cHello', element);

打印一个正则变量:

    var r = /./;
    r.toString = function() {
      document.title = 'on';
    };
    console.log(r);

基于这一发现,我找到了侵入性较小的方法。DevTools 在将函数打印到控制台时调用 toString() 函数。因此,可以使用 toString() 方法覆盖返回空字符串来打印自定义函数对象。此外,您可以使用控制台格式化字符串 %c 并设置 color:transparent 以确保可能打印的文本打印为不可见。我在这里使用了这种技术:github.com/binaryage/cljs-devtools/blob/...
2021-03-16 15:12:46
此外,控制台将在控制台打开后立即“读取”元素,因此您只需打印一次并等待 getter 中的函数执行而不是设置 setInterval
2021-03-24 15:12:46
很好的答案。要添加的一件事... MDN 说__defineGetter__已弃用,所以我改为Object.defineProperty(element, 'id', {get:function() {checkStatus='on';}});...仍在工作。
2021-03-27 15:12:46
2017 年在这里。Chrome 仍然会在您不打开它的情况下将内容写入控制台。你的黑客不再起作用了。
2021-04-05 15:12:46
在 firefox 上测试不适用于Inspection Element(Q) 和Inspect Element with firebug
2021-04-05 15:12:46

requestAnimationFrame(2019 年末)

将这些先前的答案留在这里以了解历史背景。目前Muhammad Umer 的方法适用于 Chrome 78,具有检测关闭和打开事件的额外优势。

函数 toString (2019)

感谢Overcl9ck对这个答案的评论。/./用空函数对象替换正则表达式仍然有效。

var devtools = function() {};
devtools.toString = function() {
  if (!this.opened) {
    alert("Opened");
  }
  this.opened = true;
}

console.log('%c', devtools);
// devtools.opened will become true if/when the console is opened

正则表达式 toString (2017-2018)

由于最初的提问者似乎不再存在并且这仍然是公认的答案,因此添加此解决方案以提高可见性。幸得安东宁·希尔德布兰德评论zswang s'的答案此解决方案利用了toString()除非控制台打开,否则不会在记录的对象上调用的事实

var devtools = /./;
devtools.toString = function() {
  if (!this.opened) {
    alert("Opened");
  }
  this.opened = true;
}

console.log('%c', devtools);
// devtools.opened will become true if/when the console is opened

控制台.profiles (2013)

更新: console.profiles已从 Chrome 中删除。此解决方案不再有效。

感谢Paul Irish使用探查器Discover DevTools指出这个解决方案

function isInspectOpen() {
  console.profile();
  console.profileEnd();
  if (console.clear) {
    console.clear();
  }
  return console.profiles.length > 0;
}
function showIfInspectIsOpen() {
  alert(isInspectOpen());
}
<button onClick="showIfInspectIsOpen()">Is it open?</button>

window.innerHeight (2011)

这个其他选项可以在页面加载检测到打开的停靠检查器,但无法检测到未停靠的检查器,或者检查器是否在页面加载时已经打开。还有一些潜在的误报。

window.onresize = function() {
  if ((window.outerHeight - window.innerHeight) > 100) {
    alert('Docked inspector was opened');
  }
}

toString 似乎已在 chrome 中修复。编辑。实际上,如果您使用 afunction() {}而不是正则表达式,它会起作用
2021-03-11 15:12:46
获取类型错误:无法读取 isInspectOpen() 中未定义的属性“长度”
2021-03-25 15:12:46
有一种新的最佳方式(来源:@zswang):stackoverflow.com/questions/7798748/...
2021-04-02 15:12:46
@Overcl9ck 您的解决方案一直有效,直到最新的 Chrome 77 更新。您能否为我们指出解决方法的正确方向?
2021-04-07 15:12:46
'toString (2017)' 的解决方案在 chrome 中不起作用
2021-04-10 15:12:46

非常可靠的黑客

基本上在属性上设置一个 getter 并将其记录在控制台中。显然,只有在控制台打开时才能访问该内容。

https://jsfiddle.net/gcdfs3oo/44/

var checkStatus;
var indicator = document.querySelector('#devtool-status');

var element = new Image();
Object.defineProperty(element, 'id', {
  get: function() {
    checkStatus='on';
    throw new Error("Dev tools checker");
  }
});

requestAnimationFrame(function check() {
  checkStatus = 'off';
  console.dir(element);
  indicator.className  = checkStatus;
  requestAnimationFrame(check);
});
.on{
  color:limegreen;
}

.off{
  color:red;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.1/css/all.css" integrity="sha256-DVK12s61Wqwmj3XI0zZ9MFFmnNH8puF/eRHTB4ftKwk=" crossorigin="anonymous" />

<p>
  <ul>
    <li>
      dev toolbar open: icon is <span class="on">green</span>
    </li>
    <li>
      dev toolbar closed: icon is <span class="off">red</span>
    </li>
  </ul>
</p>
<div id="devtool-status"><i class="fas fa-7x fa-power-off"></i></div>
<br/>
<p><b>Now press F12 to see if this works for your browser!</b></p>

有什么throw new Error("Dev tools checker");用?因为没有它它也能工作。
2021-03-15 15:12:46
这不再适用于 chrome 90(稳定)
2021-03-22 15:12:46
这似乎是向控制台发送垃圾邮件(打开时)?我认为几天后会开始消耗大量内存:)
2021-04-08 15:12:46
巧妙!这种方法可以与像被颠覆console.log = function() {}console.dir = function() {}
2021-04-10 15:12:46
Chrome Canary 89.0.4373.0 不再有效 ❎
2021-04-10 15:12:46

我创建了devtools-detect来检测 DevTools 何时打开:

console.log('is DevTools open?', window.devtools.open);

您还可以收听事件:

window.addEventListener('devtoolschange', function (e) {
    console.log('is DevTools open?', e.detail.open);
});

当 DevTools 未停靠时,它不起作用。但是,适用于 Chrome/Safari/Firefox DevTools 和 Firebug。

@barbushin 我认为您打开的 devtool 已停靠,它无法检测到单独的窗口。
2021-03-23 15:12:46
可悲的是它停止为 Chrome 工作github.com/sindresorhus/devtools-detect/issues/40
2021-04-03 15:12:46

我找到了一种方法来判断 Chrome 控制台是否已打开。它仍然是一个黑客,但它更准确,并且可以在控制台未停靠或未停靠的情况下工作。

基本上,在关闭控制台的情况下运行此代码大约需要 100 微秒,而在打开控制台时,大约需要两倍的时间,大约 200 微秒。

console.log(1);
console.clear();

(1 毫秒 = 1000 微秒)

我在这里写了更多关于它的内容

演示在这里


更新:

@zswang 找到了当前的最佳解决方案 - 查看他的答案

这是非常错误的解决方案。谷歌它 - >“种族危险”。较慢或较快的计算机和...?
2021-03-13 15:12:46
“种族危害”与此无关。打开控制台时总是相对缓慢。
2021-03-17 15:12:46
相对缓慢,但并不总是 100 或 200 毫秒。因此种族风险。顺便提一句。如果您将同时玩游戏,则此“解决方案”将返回误报结果。
2021-04-10 15:12:46