Подумайте о рабочих процессах как близоруких элементах программирования.
Рабочий процесс не может видеть за пределами того, что сразу доступно в области. Таким образом, вложенные функции не работают с одним рабочим процессом, потому что не могут их видеть.
Исправление состоит в том, чтобы встраивать рабочие процессы вместе с вложенными функциями. Например:
workflow workflow1
{
function func1
{
"in func1"
workflow workflow2
{
function func2
{
"in func2"
}
func2
}
"in workflow2"
workflow2
}
"in workflow1"
func1
}
workflow1
Затем он видит вложенные функции:
in workflow1
in func1
in workflow2
in func2
Подробнее об этом здесь
Некоторые ответы здесь перестанут работать в Chrome 65. Вот альтернатива временной атаки , которая довольно надежно работает в Chrome, и ее гораздо труднее смягчить, чем метод toString()
. К сожалению, в Firefox это не так надежно.
addEventListener("load", () => {
var baseline_measurements = [];
var measurements = 20;
var warmup_runs = 3;
const status = document.documentElement.appendChild(document.createTextNode("DevTools are closed"));
const junk = document.documentElement.insertBefore(document.createElement("div"), document.body);
junk.style.display = "none";
const junk_filler = new Array(1000).join("junk");
const fill_junk = () => {
var i = 10000;
while (i--) {
junk.appendChild(document.createTextNode(junk_filler));
}
};
const measure = () => {
if (measurements) {
const baseline_start = performance.now();
fill_junk();
baseline_measurements.push(performance.now() - baseline_start);
junk.textContent = "";
measurements--;
setTimeout(measure, 0);
} else {
baseline_measurements = baseline_measurements.slice(warmup_runs); // exclude unoptimized runs
const baseline = baseline_measurements.reduce((sum, el) => sum + el, 0) / baseline_measurements.length;
setInterval(() => {
const start = performance.now();
fill_junk();
const time = performance.now() - start;
// in actual usage you would also check document.hasFocus()
// as background tabs are throttled and get false positives
status.data = "DevTools are " + (time > 1.77 * baseline ? "open" : "closed");
junk.textContent = "";
}, 1000);
}
};
setTimeout(measure, 300);
});
Я нашел новый метод:
var b=new Blob()
Object.defineProperty(b,'size',{get(){
alert('The devtool was opened!')
}})
setTimeout(function(){console.log(b)},3000)
Также вы можете попробовать это: https://github.com/sindresorhus/devtools-detect
// check if it's open
console.log('is DevTools open?', window.devtools.open);
// check it's orientation, null if not open
console.log('and DevTools orientation?', window.devtools.orientation);
// get notified when it's opened/closed or orientation changes
window.addEventListener('devtoolschange', function (e) {
console.log('is DevTools open?', e.detail.open);
console.log('and DevTools orientation?', e.detail.orientation);
});
Существует хитрый способ проверить его на наличие расширений с разрешением «вкладки»:
chrome.tabs.query({url:'chrome-devtools://*/*'}, function(tabs){
if (tabs.length > 0){
//devtools is open
}
});
Также вы можете проверить, открылся ли он для вашей страницы:
chrome.tabs.query({
url: 'chrome-devtools://*/*',
title: '*example.com/your/page*'
}, function(tabs){ ... })
Я нашел способ узнать, открыта ли консоль Chrome или нет. Это все еще хак, но он более точен и будет работать, когда консоль отстыкована или нет.
В основном выполнение этого кода с закрытой консолью занимает около ~ 100 микросекунд, а когда консоль открыта, она занимает примерно вдвое больше ~ 200 микросекунд.
console.log(1);
console.clear();
(1 миллисекунда = 1000 микросекунд)
Я написал больше об этом здесь .
Демо-версия здесь .
Обновление:
@zswang нашел наилучшее на данный момент решение - посмотрите его ответ
Что касается Chrome/77.0.3865.75 версия 2019 не работы. toString сразу вызывает без открытия Инспектора.
const resultEl = document.getElementById('result')
const detector = function () {}
detector.toString = function () {
resultEl.innerText = 'Triggered'
}
console.log('%c', detector)
<div id="result">Not detected</div>