22

I got a problem when using console.log in Google Chrome. Suddenly when I was outputting a element like $(this) it was display like:

[<div>, context: <div>]

or

[jQuery.fn.jQuery.init[1]]

in the console. ( Both came from the same row: console.log($(this)) )

This problem arose yesterday from nowhere. There ain't a problem with the code. I logged the exact same thing on an other computer and there it is being displayed like:

[<div class='element'></div>, ...]

Update: the new Chrome version changes the output of console.log()

Does anyone know how I can get back to the original settings of Google Chrome console?

aksu
  • 5,221
  • 5
  • 24
  • 39
hgerdin
  • 637
  • 2
  • 8
  • 24
  • 7
    I would recommend that you improve your acceppt rate and consider that even if there is no perfect answer each user that gave an answer is trying to help and has put time and effort into their answer with the only benefit of getting points for an upvote or an accepted answer. – surfmuggle Nov 11 '12 at 18:13
  • 1
    Please star https://code.google.com/p/chromium/issues/detail?id=162570 – NVI Nov 25 '12 at 22:18

8 Answers8

15

To answer the question:

  • Does anyone know how I can get back to the original settings of Google chrome console?

There are no settings to get the former output of console.log(). You can either:

  • downgrade the browser (use an older version of chrome or chromium based alternatives)
  • overwrite console.log() by adding your own function log()
  • use outerHTML in some cases or upgrade to chrome 25.0.1323.1 (dev channel) where console.log($(#Selector)[0]); returns outHMTL again (see below).

Chrome 23/24: Output of console.log() changed sometimes

According to user916276 the output of console.log(jQuery-Object) has changed:

// output of console.log($jQuerObject) 
[<div class='element'></div>, ...] // in chrome <= 23
[<div>, context: <div>]            // in chrome 24

User brentonstrine made me aware of the fact that my context.outerHTML does not always work.

I updated my code with a new example. It seems that the existence of jqObject.context.outerHTML depends how you pass the jQuery-Object to the function. I tested it with chrome dev channel (25.0.1323.1) and two chromium based versions (21, 22).

console.log($(this)); // old chrome versions 
// new chrome version >23
// if you pass this to the function see my getThis(_this) function
console.log($(this).context.outerHTML); 
// if you use a jQuery selector
console.log($(this)[0]);   // at least in chrome build 25.0.1323.1

To avoid misunderstandings. This answer is about the changed behaviour of writing a jQuery object to the inbuild console of the recent google chrome browsers (version 24, 25).

Chrome source code

I took a look into the chrome source code changes at the Console.cpp and in the timeline view to find out about the changes in the WebInspector. I could not find the exact change that is responsible for the changed behaviour of console.log(). I assume that it has to do with changes to ConsoleView.js, 2, 3. If anyone would like to initiate that console.log() returns the same output as in Chrome 21, 22 he could file a bug. This two bugs could be used as a template to place the change request.

Community
  • 1
  • 1
surfmuggle
  • 5,527
  • 7
  • 48
  • 77
  • Yes I know, but $(this) shall not be displayed as I described above. $(this) shall contain an array of elements, not "context" and so on. If I outputs $(this) it shall be display as [
    ] not [
    , context:
    ].
    – hgerdin Nov 07 '12 at 10:47
  • I updated the question. There´s no issue with to code, just the way chrome console displays it. As I mentioned above it worked yesterday and I works no if I'm using safari, or chrome on an other computer. Something has happened to the console in chrome. – hgerdin Nov 07 '12 at 11:01
  • I'm using the latest version of chrome. – hgerdin Nov 07 '12 at 11:02
  • Have you installed or updated any extensions lately? http://stackoverflow.com/questions/3240523/console-log-messages-not-showing-up-in-chromes-javascript-console – surfmuggle Nov 07 '12 at 11:11
  • The latest stable build. I got firebug lite and addblocker installed. – hgerdin Nov 07 '12 at 11:22
  • The cause of the problem is the latest version of Google Chrome that diplays $(this) like [
    , context:
    ] instead of [
    , ...]. I prefer the old one...
    – hgerdin Nov 07 '12 at 12:16
  • Must be something with WebKit source, I use Luakit. This really sucks, this new input is absolutelly useless. Men I am so pissed! this renders webkit useless for any web development. – Macario Nov 15 '12 at 22:54
  • 1
    @threeFourOneSixOneThree that is weird. I'm on 24, and it still doesn't work. – brentonstrine Nov 16 '12 at 19:49
  • @brentonstrine you found something i can not explain yet. i will update my answer above shortly. – surfmuggle Nov 16 '12 at 21:03
  • 1
    I'm surprised this continues to be a problem in chrome. – alvincrespo Jan 25 '13 at 02:22
11

console.log.apply(console, $(this));

brentonstrine
  • 21,694
  • 25
  • 74
  • 120
  • Or to make a function out of it: var domLog = function($obj){ console.log.apply(console,$obj); } domLog( $("div.anything") ); – brentonstrine Nov 27 '12 at 22:29
  • 1
    brentonstrine's comment above doesn't quite work because of the way comments lose their line breaks. Try: `var domLog = function($obj){ console.log.apply(console,$obj); }; domLog( $("div") );` – Bruno Bronosky Mar 28 '13 at 23:00
6

The output is correct as $(this) refers to jQuery selection object, not the underlying DOM object(s).

If you wish to output the raw DOM element(s), you can try the following:

 console.log( $( this ).get(0) ) 
 // Or just 
 console.log( this )

Or you can also do:

 console.log( $( this ).html() )  
kaiser
  • 21,817
  • 17
  • 90
  • 110
Mikko Ohtamaa
  • 82,057
  • 50
  • 264
  • 435
  • 2
    Yeah but in previous version it logged `[
    , ...]` :P
    – Esailija Nov 07 '12 at 10:48
  • 1
    Still not nice, previously in addition to having an array of dom objects, you could open them and close them. – Macario Nov 15 '12 at 23:07
  • 2
    I don't really believe in this. The output is completely different. `console.log( $( this ).html() );` gives you plain text and `console.log( $( this ).get(0) );` gives you the HTML. **But** in case the object got siblings: (you can test that yourself) if you append `.attr( 'id' )`, you'll get nothing for the first one and an error for the later one. The Error is `Uncaught TypeError: Object [HTML HERE] has no property 'attr'`. – kaiser Nov 19 '12 at 19:10
  • I didn't get attr() part at all – Mikko Ohtamaa Nov 19 '12 at 21:34
5

Here is an even better solution than console.log.apply(console, obj); that I just discovered. Check out console.dirxml(obj); which gives nearly the same output when obj is a jQuery selector result set. However, only the latter works when obj is a specific element from a jQuery selector result set.

Here is a demo you can do on this page...

var i=0
console.log(++i);
console.dirxml($$('.answer'));
console.log(++i);
console.dirxml($$('.answer')[0]);
console.log(++i);
console.log.apply(console, $$('.answer'));
console.log(++i);
console.log.apply(console, $$('.answer')[0]);

You'll see that #4 logs "undefined".

Performed at the console on this very page.

So, from now on I'm going to use console.dirxml because it's simple, effective, and built in. Having to pass console as the first argument to apply never sat right with me anyway.

Bruno Bronosky
  • 66,273
  • 12
  • 162
  • 149
2

By default , chrome now returns an object with all details pertaining to that element when u do a console.log($(element)).

an example of what it actually returns

  console.log($('input:first'));
  [<input>, prevObject: c.fn.c.init[1], context: #document, selector: "input:first"] 
  0: <input>
  context: #document
  length: 1
  prevObject: c.fn.c.init[1]
  selector: "input:first"
  __proto__: Object[0]

so if u do console.log($('input:first')[0]) u would get ur desired Result.

hope this helps

achand8238
  • 124
  • 6
  • In previous versions logging a jQuery object would display an array with the html representation of each of the objects. – Macario Nov 15 '12 at 22:51
  • This is the correct answer. putting `[0]` mimics the old behavior. – brentonstrine Nov 15 '12 at 23:48
  • I will repeat my previous comment, as everyone seems to think appending `[0]` to your jQuery selector will give you the old output, it will not: $(this)[0] does only give you "old output" correctly if you only find one element, if you find many different elements, you will see it outputs only the first[0] in the array of elements, and thus is not useful. – Victor S Nov 26 '12 at 20:20
2

My edit to @brentonstrine's answer got rejected, so I'm going to make a new answer for it. But see my other answer on this page for an even better solution.

This demo shows you why we care about logging this new way versus the normal way...

// paste this whole block into the console of THIS PAGE and see a working demo!

var domlog = function(obj){ console.log.apply(console, obj); };

domlog($('#answer-13594327'));

// compare ^that^ to the normal element logging...

var normallog = function(obj){ console.log(obj); };

normallog($('#answer-13594327'));

Demo of the 2 different loggin metods

Community
  • 1
  • 1
Bruno Bronosky
  • 66,273
  • 12
  • 162
  • 149
  • In case my edit suggestions will not make it through (2 reject vs. 2 approve) If `domlog($(id))` is used it returns the domnode in a way that you can mouse over it in the console and the matching node `
    ...
    ` is highligthed in its page context (see screenshot). The function `normallog($(id))` returns the [node] in brackets - mouse over does not highlight the bracketed node `[
    ...
    ]`
    – surfmuggle Apr 28 '13 at 16:28
1
console.log.apply(console, [].slice.call($('p'), 0))
-> ►<p>…</p>, ►<p>…</p>, <p class="label-key">viewed</p>

Update: Simpler solution.


Rationale behind the console output change:

What was the rationale behind the request to not include attributes/textContent?

Response from pfeldman, DevTools developer:

people that dump DOM lists appreciate the dense look.

crbug.com/50316

Community
  • 1
  • 1
NVI
  • 14,907
  • 16
  • 65
  • 104
  • I see you beat me here with almost the same solution that I posted. What does the additional `[].slice.call(x,0)` that is in yours but not mine do? – brentonstrine Nov 27 '12 at 22:36
  • It’s a common way to convert an array-like object to a real array. http://stackoverflow.com/questions/4929924/how-to-sort-a-javascript-object-or-convert-it-to-an-array – NVI Nov 28 '12 at 09:07
  • [].slice.call doesn’t do anything here to the output of the console, it seems. – NVI Nov 28 '12 at 09:12
0

This is my sollution, to wrap console.log in my own function, it has some shortcomings, like it doesn't tell you the line number the problem occured in but I make up by outputing significan log messages... if anyone want to improve on it feel free!

Note: underscore.js is a dependency, I'm sure you can do it in pure JS, but I always depend on underscore.js :)

// wrap the console.log function
var log = function(data) {
    // switch setting
    var allowed = true;
    if (allowed) {
        console.log("LOG");
        console.log(typeof data);
        if (typeof data == "object" || typeof data == "array") {
            _.each(data, function(item) {
                console.log(item);
            });
        } else {
            console.log(data);
        }
    };

The take home message here is:

if (typeof data == "object" || typeof data == "array") {
            _.each(data, function(item) {
                console.log(item);
            });
        } else {
            console.log(data);
        }

Then you just do: log($(".some.class")); and get the elements as old school DOM objects in the console.

Victor S
  • 5,098
  • 5
  • 44
  • 62