How to create hyperlinks linked to javascript functions in Chrome's console.log?

20,244

Solution 1

The Google Chrome console, like many other browser's developer tools consoles, automatically parses any URL into a link to that exact page. This is the only way of obtaining such URLs, and, unfortunately, you cannot actually log "custom URLs".

This means that the following logs will be turned into a clickable link automatically:

console.log('http://example.com');
console.log('www.example.com');
console.log('ftp://mysite.com');
console.log('chrome://history')
console.log('chrome-extension://abcdefg...');

but, on the contrary, the following ones won't:

console.log('example.com');
console.log('<a href="http://www.example.com">Link</a>');
console.log('javascript:doSomething(someValue);');

Solution 2

It's been four years since OP asked this, but they can accomplish their stated goal as follows:

Create a getter that has a side-effect. (The side effect can be to directly animate your thing.)

class YourThing {        
    get __doAnythingYouWant() {
        // ...like console.log('my thing:', this);
    }
}

Alternatively:

var yourObject = {
    get __doAnythingYouWant() {
        // ...like an animation in DOM... this.myDomElement.style...
    }
};

How to use it:

console.log(yourObject);
> {
      get __doAnythingYouWant: (...)  <-- click here!
  }
> "you clicked the dots!"

The downside is you can only invoke the getter once. You could maybe get around this by deleting it and redefining it from within itself, with every invocation. You could make that less hackish by creating some kind of getter-defining function with Object.defineProperties, and some wrapper that takes a regular function and returns a function that does what it normally does, then redefines the getter. Clicking on it once was good enough for me, but if you wanted to you'd do it like this:

function addDebuggerButton(obj, f) {
    var buttonName = `__${f.name}`;
    Object.defineProperty(obj, buttonName, {
        get: function() {
            f.apply(this, arguments);
            delete this[buttonName];
            addDebuggerButton(obj, f);
        },
        configurable: true
    });

    return obj;
}

It's important to set the configurable property, which just lets you redefine it after defining it. It works:

addDebuggerButton({a:1,b:2}, function myButton() {
    this.c = Math.random();
    console.log('you pressed the button!', this);
});
> {a: 1, b: 2}
      a: 1
      b: 2
      __myButton: (...)       <-- click here!
      get __myButton: ƒ ()
      __proto__: Object
> you pressed the button! {a: 1, b: 2, c: 0.27574428165568676}
                              a: 1
                              b: 2
                              c: 0.27574428165568676
                              __myButton: (...)      <-- click here again
                              get __myButton: ƒ ()
                              __proto__: Object
> you pressed the button! {a: 1, b: 2, c: 0.43171172657344337}

You can modify this as appropriate to work with classes. You could even add a hidden state to this by adding a default parameter to the addDebuggerButton function (so your button could say "you pressed the button 3 times!").


The other horribly hackish way to do this is to write a url like http://127.0.0.1:9999/myLocalWebserver/horribleWorkaround?{"metadata":"etc"}. The URL would be interpreted by your local webserver you're testing your app out of, and would initiate some kind of push mechanism (or queue onto a poll mechanism), that would propagate to the webpage live.

... Of course, it would probably be more elegant to compile Chromium yourself with a custom patch...


The third way, since chrome-extension:// urls are allowed, is perhaps to write an extension that converts certain clicks into javascript. There may perhaps be security implications (to be safe, you would not let this run except on whitelisted pages, but even then there are security implications I have not thought of since I'm not entirely familiar with that area).

Share:
20,244
chamberlainpi
Author by

chamberlainpi

Flash / AS3 / Starling veteran, currently self-employed working with various web development tools and technologies such as Haxe, Brunch.io, NPM, NodeJS, CreateJS, PixiJS, HTML5, jQuery, Ajax, JavaScript, CSS, LESS, PHP, XML, JSON. My preferred IDEs are FlashDevelop (for AS3 and Haxe dev) and IntelliJ Ultimate / Webstorm. I also have some experience with Wordpress and run a blog with tutorials covering some of the above technologies.

Updated on September 08, 2020

Comments

  • chamberlainpi
    chamberlainpi almost 4 years

    I'm trying to write entries to the console that would contain links to trigger javascript functions upon clicking on them:

    console.log("javascript:alert('Hello World');");
    console.log("<a href=\"javascript:alert('Hello World');\"/>test</a>");
    console.log("[DisplayObject 'Hello World' <a href=\"javascript:alert('Hello World');\">reveal</a>]");
    

    All these attempts fail.

    screenshot

    Is there any way to print it similarly to an "http://..." link, like so...

    example

    ... only, have the text linked to a javascript statement or function instead?

    The reason I'm doing this is to be able to quickly reveal which items on the screen are tied to a specific log entry (example: Making a CreateJS sprite scale-up when the log entry is clicked on).