ค้นหาว่าคอนโซล Chrome เปิดอยู่หรือไม่


143

ฉันใช้สคริปต์เล็กน้อยนี้เพื่อค้นหาว่า Firebug เปิดอยู่หรือไม่:

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

และมันใช้งานได้ดี ตอนนี้ฉันกำลังค้นหาครึ่งชั่วโมงเพื่อค้นหาวิธีการตรวจสอบว่าคอนโซลนักพัฒนาเว็บในตัวของ Google Chrome เปิดอยู่หรือไม่ แต่ฉันไม่พบคำใบ้ใด ๆ

นี้:

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

ไม่ทำงาน

แก้ไข:

ดังนั้นจึงดูเหมือนว่าเป็นไปไม่ได้ที่จะตรวจพบว่าคอนโซล Chrome เปิดอยู่หรือไม่ แต่มี " แฮ็ค " ที่ใช้งานได้กับข้อเสียบางอย่าง:

  • จะไม่ทำงานเมื่อไม่มีการปลดคอนโซล
  • จะไม่ทำงานเมื่อเปิดคอนโซลเมื่อโหลดหน้าเว็บ

ดังนั้นฉันจะเลือกคำตอบที่ไม่ได้ลงนามตอนนี้ แต่ถ้ามีคนที่ 1 มาพร้อมกับความคิดที่ยอดเยี่ยมเขาก็ยังยินดีที่จะตอบและฉันเปลี่ยนคำตอบที่เลือก! ขอบคุณ!



วิธีแก้ปัญหาในคำตอบดูเหมือนว่าจะทำงานได้ก็ต่อเมื่อคอนโซลเชื่อมต่อ นอกจากนี้มันจะไม่ทำงานหากคอนโซลเปิดอยู่แล้วเมื่อโหลดหน้าเว็บขณะที่สคริปต์ Firebug ไม่มีปัญหานี้และดูเหมือนว่าจะทำงานได้ตลอดเวลา แต่ตอนนี้ฉันสามารถอยู่กับมันได้แล้ว! ขอบคุณมาก @pimvdb !! ฉันจะเปิดคำถามต่อไปเพื่อหาวิธีที่คล้ายกับสคริปต์ Firebug ซึ่งใช้ได้เสมอ
r0skar

ฉันพยายามทำสิ่งต่าง ๆ เช่นการโยนข้อผิดพลาดและดูว่า.messageมีการดึงข้อมูลหรือไม่(ซึ่งเกิดขึ้นเมื่อดีบักเกอร์เปิดเพราะคุณเห็นข้อความ) แต่น่าเสียดายที่สิ่งนี้เกิดขึ้นเมื่อไม่ได้เปิดดีบัก ฉันอยากจะรู้เรื่องแฮ็คนี้ถ้ามันมีอยู่ ...
pimvdb

4
@ Spudley มันไม่เกี่ยวข้องกับคำถามที่ว่าทำไมฉันต้องการมันและฉันไม่ต้องการที่จะเริ่มอธิบาย ฉันรู้ว่าไม่มีวิธีที่จะป้องกันไม่ให้ผู้ใช้ดีบัก แต่นั่นไม่ใช่สิ่งที่ฉันพยายามทำ ฉันแค่พยายามหาวิธีที่จะรู้ว่าคอนโซลเปิดอยู่หรือไม่
นั่นคือ

1
วิธี JFYI console.profiles ถูกลบออกจาก console API เมื่อเร็ว ๆ นี้src.chromium.org/viewvc/blink?view=revision&revision=151136
loislo

คำตอบ:


98

requestAnimationFrame (ปลายปี 2019)

ออกจากคำตอบก่อนหน้านี้ที่นี่เพื่อบริบททางประวัติศาสตร์ ปัจจุบันแนวทางของ Muhammad Umerทำงานบน Chrome 78 ด้วยความได้เปรียบที่เพิ่มขึ้นจากการตรวจจับเหตุการณ์ทั้งใกล้และเปิด

ฟังก์ชั่น toString (2019)

ให้เครดิตกับความคิดเห็นของOvercl9ckในคำตอบนี้ แทนที่ regex /./ด้วยวัตถุฟังก์ชั่นที่ว่างเปล่ายังคงทำงาน

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

regex toString (2017-2018)

เนื่องจากผู้ถามดั้งเดิมดูเหมือนจะไม่อยู่อีกต่อไปแล้วและนี่ยังเป็นคำตอบที่ได้รับการยอมรับเพิ่มโซลูชันนี้เพื่อการมองเห็น เครดิตไปที่แอ Hildebrand 's ความคิดเห็นเกี่ยวกับ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

console.profiles (2013)

อัปเดต: console.profilesถูกลบออกจาก Chrome แล้ว โซลูชันนี้ใช้งานไม่ได้อีกต่อไป

ขอบคุณPaul Irish ที่ชี้ให้เห็นวิธีแก้ปัญหานี้จากDiscover DevToolsโดยใช้ profiler:

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');
  }
}


1
รับ TypeError: ไม่สามารถอ่าน 'ความยาว' ของคุณสมบัติที่ไม่ได้กำหนดใน isInspectOpen ()
sandeep

2
มีวิธีใหม่ที่ดีที่สุด (เครดิต: @zswang) ใหม่: stackoverflow.com/questions/7798748//
Vicky Chijwani

3
วิธีการแก้ปัญหาของ 'toString (2017)' ไม่สามารถใช้งานได้ในโครเมี่ยม
Richard Chan

2
toString ดูเหมือนว่าได้รับการแก้ไขในโครเมียม แก้ไข จริงๆแล้วมันใช้งานได้ถ้าคุณใช้function() {}regex แทน
Overcl9ck

1
@ Overcl9ck โซลูชันของคุณใช้งานได้จนถึงการอัปเดต Chrome 77 ล่าสุด คุณช่วยชี้เราในทิศทางที่ถูกต้องสำหรับการแก้ปัญหาได้หรือไม่?
Agustin Haller

118

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


เมื่อพิมพ์เครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ "องค์ประกอบ" ของ Chrome จะได้รับรหัส

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);

3
คำตอบที่ดี สิ่งหนึ่งที่จะเพิ่ม ... MDN กล่าวว่า__defineGetter__เลิกใช้แล้วดังนั้นฉันเปลี่ยนเป็นObject.defineProperty(element, 'id', {get:function() {checkStatus='on';}});... ยังทำงานอยู่
denikov

5
นอกจากนี้คอนโซลจะ 'อ่าน' องค์ประกอบทันทีที่เปิดคอนโซลดังนั้นคุณสามารถพิมพ์ได้เพียงครั้งเดียวและรอฟังก์ชั่นในตัวเรียกใช้เพื่อดำเนินการแทนการตั้งค่าsetInterval
xpy

8
จากการค้นพบครั้งนี้ฉันสามารถค้นหาวิธีที่ล่วงล้ำน้อยลง DevTools เรียก toString () บนฟังก์ชั่นเมื่อพิมพ์ไปยังคอนโซล ดังนั้นหนึ่งสามารถพิมพ์วัตถุฟังก์ชั่นที่กำหนดเองด้วย toString () วิธีการแทนที่กลับสตริงที่ว่างเปล่า นอกจากนี้คุณสามารถใช้สตริงการจัดรูปแบบคอนโซล% c และกำหนดสี: โปร่งใสเพื่อให้แน่ใจว่าข้อความที่พิมพ์อาจพิมพ์ออกมามองไม่เห็น ฉันใช้เทคนิคนี้ที่นี่: github.com/binaryage/cljs-devtools/blob/…
Antonin Hildebrand

3
ปี 2560 ที่นี่ Chrome ยังคงเขียนสิ่งต่าง ๆ ในคอนโซลโดยที่คุณไม่ต้องเปิด และการแฮ็คของคุณจะไม่ทำงานอีกต่อไป
vothaison

2
ทดสอบกับ firefox ไม่ทำงานกับ Inspection Element (Q) และ Inspect Element ด้วย firebug
Asif Ashraf

28

แฮ็คที่เชื่อถือได้มาก

โดยทั่วไปตั้งค่า getter บนคุณสมบัติและล็อกอินในคอนโซล เห็นได้ชัดว่าสิ่งที่ได้รับการเข้าถึงก็ต่อเมื่อเปิดคอนโซล

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

var checkStatus;

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);
  document.querySelector('#devtool-status').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>


Chrome รุ่น 79 ✅
ตำนาน

4
อะไรthrow new Error("Dev tools checker");หา? เพราะมันใช้งานไม่ได้
ตำนาน

สิ่งนี้ดูเหมือนจะเป็นสแปมคอนโซล (เมื่อเปิด) ซึ่งผมถือว่าจะเริ่มต้นที่จะกินเป็นจำนวนมากของหน่วยความจำหลังจากไม่กี่วัน :)
pythonator

วิธีเดียวที่ทำงานตั้งแต่ปี 2020.7
laike9m

24

ฉันสร้าง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 ที่เปิดอยู่ของคุณเชื่อมต่อไม่สามารถตรวจพบหน้าต่างแยกต่างหาก
มิ ธ ริล

น่าเศร้าที่มันหยุดทำงานกับ Chrome github.com/sindresorhus/devtools-detect/issues/40
laike9m

15

ฉันพบวิธีที่จะบอกว่า Chrome Console เปิดอยู่หรือไม่ มันยังคงเป็นแฮ็ก แต่มันแม่นยำกว่าและจะทำงานได้ในสภาพอากาศที่คอนโซลถูกปลดออกหรือไม่

โดยทั่วไปการเรียกใช้รหัสนี้โดยปิดคอนโซลใช้เวลาประมาณ ~ 100 microseconds และในขณะที่เปิดคอนโซลจะใช้เวลาประมาณสองเท่าของ 200 microseconds

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

(1 มิลลิวินาที = 1,000 ไมโครวินาที)

ผมเคยเขียนเพิ่มเติมเกี่ยวกับมันนี่

สาธิตที่นี่


ปรับปรุง:

@zswang พบทางออกที่ดีที่สุดในปัจจุบัน - ลองดูคำตอบของเขา


1
มันเป็นทางออกที่ผิดมาก Google it -> "Race Hazard" คอมพิวเตอร์ช้าหรือเร็วกว่าและ ... ?
18C

1
"Race Hazard" ไม่เกี่ยวข้องที่นี่ มักจะมีความเชื่องช้าเมื่อเปิดคอนโซล
guya

1
ความเชื่องช้าสัมพัทธ์ แต่ไม่เสมอ 100 หรือ 200ms ดังนั้นการแข่งขันที่เป็นอันตราย Btw หากคุณจะเล่นเกมในเวลาเดียวกัน "การแก้ปัญหา" นี้จะส่งคืนผลลัพธ์เชิงบวกที่ผิดพลาด
18C

8

หากเป้าหมายของคุณคือการติดขัดเครื่องมือสำหรับนักพัฒนาลองใช้สิ่งนี้ (ฉันพบรุ่นที่ซับซ้อนกว่าในที่ที่โค้ด JS นั้นยุ่งเหยิงมันน่ารำคาญมาก):

setTimeout(function() {while (true) {eval("debugger");}}, 0);

ผู้ใช้สามารถใน Chrome ปิดการใช้งานฟังดีบักเกอร์
Jack Giffin

3

มีวิธีที่ยุ่งยากในการตรวจสอบส่วนขยายที่ได้รับอนุญาตด้วย 'แท็บ':

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){ ... })

3

ฉันเขียนโพสต์บล็อกเกี่ยวกับสิ่งนี้: http://nepjua.org/check-if-browser-console-is-open/

สามารถตรวจจับได้ว่าเชื่อมต่ออยู่หรือปลดออกจากตำแหน่ง

function isConsoleOpen() {  
  var startTime = new Date();
  debugger;
  var endTime = new Date();

  return endTime - startTime > 100;
}

$(function() {
  $(window).resize(function() {
    if(isConsoleOpen()) {
        alert("You're one sneaky dude, aren't you ?")
    }
  });
});

3
ไม่เป็นไร แต่มันจะค้างหน้าและจะไม่มีข้อความปรากฏจนกว่าผู้ใช้จะคลิกปุ่มดำเนินการต่อ มันจะล่วงล้ำอย่างมากสำหรับผู้ใช้
guya

2
ถัดไปโซลูชัน "Race Hazard" ผิดมาก BTW คำสั่ง "debugger" สามารถปิดใช้งานได้
18C


2

เครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ Chrome เป็นเพียงส่วนหนึ่งของไลบรารี WebCore ของ WebKit ดังนั้นคำถามนี้ใช้กับ Safari, Chrome และผู้บริโภค WebCore อื่น ๆ

หากมีวิธีการแก้ปัญหาอยู่นั้นจะขึ้นอยู่กับความแตกต่างใน DOM เมื่อผู้ตรวจสอบเว็บ WebKit เปิดและปิด น่าเสียดายนี่เป็นปัญหาไก่และไข่ชนิดหนึ่งเนื่องจากเราไม่สามารถใช้ผู้ตรวจการเพื่อสังเกต DOM เมื่อผู้ตรวจสอบถูกปิด

สิ่งที่คุณสามารถทำได้คือเขียน JavaScript เล็กน้อยเพื่อถ่ายโอนต้นไม้ DOM ทั้งหมด จากนั้นเรียกใช้หนึ่งครั้งเมื่อเปิดการตรวจสอบและหนึ่งครั้งเมื่อปิดการตรวจสอบ ความแตกต่างใน DOM อาจเป็นผลข้างเคียงของตัวตรวจสอบเว็บและเราอาจใช้เพื่อทดสอบว่าผู้ใช้กำลังตรวจสอบหรือไม่

นี้การเชื่อมโยงเป็นจุดเริ่มต้นที่ดีสำหรับการทุ่มตลาด DOM สคริปต์ แต่คุณจะต้องการที่จะถ่ายโอนข้อมูลทั้งหมดวัตถุไม่ได้เป็นเพียงDOMWindowdocument

ปรับปรุง:

ดูเหมือนว่าจะมีวิธีการทำเช่นนี้ในขณะนี้ ตรวจสอบChrome Inspector Detector


Chrome Inspector Detector ไม่สามารถใช้งานกับ google chrome ได้อีกต่อไปตามที่ผู้พัฒนาระบุไว้
Angelo

1

นอกจากนี้คุณสามารถลองนี้: 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);
});

1
ทำงานได้ไม่ดี หากผู้ใช้อยู่บนอุปกรณ์พกพาผู้ใช้จะหมุนอุปกรณ์เป็น 90 องศาจากนั้นหน้าจอจะปรับขนาด
Jack Giffin

ใช้งานได้กับ chrome และ ff ไม่ใช่เช่นหรือ edge ตั้งแต่ 4/5/2019
SolidSnake

1

วิธีของ Muhammad Umer นั้นเหมาะกับฉันและฉันใช้ React ดังนั้นฉันจึงตัดสินใจทำ hooks:

const useConsoleOpen = () => {
  const [consoleOpen, setConsoleOpen] = useState(true)

  useEffect(() => {
    var checkStatus;

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

    requestAnimationFrame(function check() {
      checkStatus = false;
      console.dir(element); //Don't delete this line!
      setConsoleOpen(checkStatus)
      requestAnimationFrame(check);
    });
  }, []);

  return consoleOpen
}

หมายเหตุ: เมื่อฉันยุ่งกับมันมันไม่ทำงานเป็นเวลานานและฉันไม่สามารถหาสาเหตุได้ ฉันลบไปแล้วconsole.dir(element);ซึ่งสำคัญต่อการทำงานของมัน ฉันลบการกระทำคอนโซลที่ไม่ใช่คำอธิบายส่วนใหญ่เนื่องจากพวกเขาเพิ่งใช้พื้นที่และไม่จำเป็นต้องใช้ฟังก์ชั่นดังนั้นจึงเป็นเหตุผลว่าทำไมมันไม่ทำงานสำหรับฉัน

วิธีใช้:

import React from 'react'

const App = () => {
  const consoleOpen = useConsoleOpen()

  return (
    <div className="App">
      <h1>{"Console is " + (consoleOpen ? "Open" : "Closed")}</h1>
    </div>
  );
}

ฉันหวังว่านี่จะช่วยให้ทุกคนใช้ React หากใครต้องการที่จะขยายในเรื่องนี้ฉันต้องการที่จะสามารถหยุดวงวนไม่สิ้นสุดในบางจุด (เนื่องจากฉันไม่ได้ใช้สิ่งนี้ในทุกองค์ประกอบ) และเพื่อหาวิธีที่จะทำให้คอนโซลสะอาด


0

หากคุณเป็นนักพัฒนาซอฟต์แวร์ที่กำลังทำสิ่งต่าง ๆ ในระหว่างการพัฒนา ลองใช้ส่วนขยาย Chrome นี้ ช่วยให้คุณตรวจพบเมื่อ Chrome Devtoos เปิดหรือปิด

https://chrome.google.com/webstore/detail/devtools-status-detector/pmbbjdhohceladenbdjjoejcanjijoaa?authuser=1

ส่วนขยายนี้ช่วยให้นักพัฒนา Javascript ตรวจพบเมื่อ Chrome Devtools เปิดหรือปิดในหน้าปัจจุบัน เมื่อ Chrome Devtools ปิด / เปิดส่วนขยายจะเพิ่มเหตุการณ์ชื่อ 'devtoolsStatusChanged' บนองค์ประกอบ window.document

นี่คือตัวอย่างโค้ด:

 function addEventListener(el, eventName, handler) {
    if (el.addEventListener) {
        el.addEventListener(eventName, handler);
    } else {
        el.attachEvent('on' + eventName,
            function() {
                handler.call(el);
            });
    }
}


// Add an event listener.
addEventListener(document, 'devtoolsStatusChanged', function(e) {
    if (e.detail === 'OPENED') {
        // Your code when Devtools opens
    } else {
        // Your code when Devtools Closed
    }
});

0

คำตอบบางส่วนที่นี่จะหยุดทำงานใน 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);

});

0

สำหรับ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>

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.