jQuery isn't giving me jQuery objects - javascript

I'm working on a website that uses jQuery, and it works fine everywhere on the site except in one function. When I try to search the DOM with jQuery I don't receive jQuery objects back and I know what the result should be because it is different in my browser. For example, when I use
$cc = $('#cc_number');
console.log($cc);
I receive this:
[input#cc_number, context: input#cc_number, constructor: function, init: function, selector: "", jquery: "1.8.2"…]
0: input#cc_number
context: input#cc_number
length: 1
__proto__: Object[0]
But when I do it in the browser console I get:
$('#cc_number');
[<input id=​"cc_number" data-stripe=​"number" type=​"text" maxlength=​"16" tabindex=​"1" style="width:​220px;​" ph=​"Card Number">​]
If anyone knows what is going on, your help would be much appreciated.

That's expected. Try from your browser console running console.log( $( 'body' ) ), you'll get the former of your logs.
There are many ways to play with console, try console.log, console.dir on HTML elements, console.debug, etc.
Can you run jQuery functions on $cc? e.g. $cc.addClass( 'active' )

Related

Why $(document).append() doesn't work in jQuery 1.9.1?

Why following piece of code doesn't work since jQuery 1.9.1? With previous versions works fine.
$(function () {
$(document).append(test);
document.write('done');
});
var test = {
version: "1.0",
};
JSFiddle: http://jsfiddle.net/Chessjan/NsjqM/
In JS console it issues error like this:
TypeError: document is null
safeFrag = document.createDocumentFragment(); jquery-1.9.1.js (line 5823)
Edit:
Thanks everybody for quick and extensive aswers. Observed issue was found by accident, and of course, $(document.body).append() is proper approach.
jQuery 1.9.x calls
this[ 0 ].ownerDocument
within its buildFragment() method. Since you pass in the document, the call
document.ownerDocument
will reference to null and cause the error. Any other node will reference the document, which of course, works.
Conclusion: Don't call $(document).append() but use $(document.body) for instance.
Your code will of never worked. It has to document.body not document.
Here's a few examples in different versions of it not working:
jQuery 1.6.4: http://jsfiddle.net/us9Kz/
jQuery 1.7.2: http://jsfiddle.net/us9Kz/1/
jQuery 1.8.3: http://jsfiddle.net/us9Kz/3/
jQuery 1.9.1: http://jsfiddle.net/us9Kz/4/
jQuery 2.0.0b1: http://jsfiddle.net/us9Kz/5/
Code working with document.body (on jQuery 1.9.1): http://jsfiddle.net/us9Kz/6/
Inside the jQuery code it has this line:
jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
this is the jQuery object you selected. In your case, the document. The ownerDocument value of document is null and this is what is passed through as document to the call to document.createDocumentFragment();. Hence you get the error that document is null (Slightly bad naming of variables there as it makes you think the document object itself is somehow null)
As other people have said. Append to the body instead and it will work fine.
To answer your question i tried in JSfiddle all the available jQuery versions. It happened to give the same error.
Why it doesnt work: document becomes something like [object HTMLDocument] when cast to string, and there is of course no such id, it will return null.
The following works:
var test = "1.0"
$('body').append(test);
or doing it trough object notation like you did:
var test = {
version: '1.0'
}
$('body').append(test.version)

Why does prototyping Function not affect console.log?

I prototyped Function so that it has a getBody function:
Function.prototype.getBody = function() {
// Get content between first { and last }
var m = this.toString().match(/\{([\s\S]*)\}/m)[1];
// Strip comments
return m.replace(/^\s*\/\/.*$/mg,'');
};
See here for more info.
I tried to test it this way:
console.log(console.log.getBody.getBody());
but received an error: TypeError: console.log.getBody is undefined.
I figured out that maybe this happens because console.log was defined before I actually prototyped Function so I created an empty function x right before the prototyping and tried to call
console.log(x.getBody.getBody());
which worked without a problem. Checking the type of console.log with typeof console.log results in "function". Here's a CodePen to try it out. All of this wasn't really a surprise since it's what I expected except of console.log.getBody to be undefined.
So why does prototyping Function not affect console.log? I'm using Firefox 18.0.1 with Firebug 1.11.1.
This seems to be an issue with Firebug not with Firefox per se. My guess is that Function in Firebug lives in a different scope then Function in your page. (since unlike the other browsers Firebug is an extension , not a built in browser tool)
In fact if instead of Firebug you use the built in Firefox console (Ctrl+Shift+K), your code works perfectly fine.
More information about Firebug internals can be found here
http://getfirebug.com/wiki/index.php/Firebug_Internals
This excerpt may be interesting
When Firebug is detached from Firefox, open in a new or separate
window, the new window has its own scope. In that scope, a few Firebug
script tags compile to create a connection back to the original
browser.xul window. Most important, chrome.js is unique to each top
level window, but the Firebug object used by the detached window is
the object of the parent browser.xul.

How to mock JQuery with Jasmine?

How can I test that a certain JQuery selector has been executed with Jasmine? I'm trying to do the following:
spyOn($.fn, 'init').andCallThrough();
// my code
expect($.init).toHaveBeenCalled();
But after this call, $('div') returns Object { selector="div", context=document, NaN=div.spec, more...}, though it has to return (and $.fn.init('div') does return it): [div.jasmine_reporter, div.banner, div.logo, 4 more...]. This stuff naturally breaks the code since the JQuery object is no longer usable.
Example:
Say I want to test that a JQuery selector has been called, I write:
it('tests', function() {
spyOn($.fn, 'init').andCallThrough();
$('html');
expect($.init).toHaveBeenCalled();
});
This result it an error from Jasmine: Error: Expected a spy, but got undefined.. Then I set a breakpoint in FireBug on $('html') line and when I get there and try to watch, what the value of $('html') is, I get:
Object { selector="html", context=document, NaN=html, more...}
If I comment out spyOn, on that line $('html') evaluates to:
[html]
Which is what I expected to see with spyOn as well.
Well it looks like Jasmine does it's spy stuff by replacing the spied-on object with a wrapped version, and that seems to be messing up jQuery as a whole because (from the jQuery source code):
// The jQuery object is actually just the init constructor 'enhanced'
I'd suggest trying to spy on one of the functions that init uses, specifically "merge". If you look at the jQuery code, you'll see that any HTML=>DOM stuff ultimately gets returned through a merge call:
return jQuery.merge( this, selector );
(that's line 152 if you happen to be looking at the source of jQuery 1.5.1).
By spying on merge you should be able to test whatever you're testing, without inadvertently replacing the guts of jQuery.

Problem tracking what javascript is causing jQuery UI error in firebug

So I am getting the following error in firebug regarding jQuery UI. It would be as simple if it was a matter of a process-of-elimination on the JS on the page, but there is allot of JS as well as some on the page and some on the site.master.
ERROR
(this.uiDialogTitlebarCloseText = c("<span/>"))
.addClass("ui-icon ui-icon-closethick").text(m.closeText).appendTo
is not a function
Is there a way in Firebug to see what javascript is the initial caller?
Well your problem is likely that m.closeText is null. If you pass a null argument to text() it will actually return the text of the element, and not set the text to null.
I'm not sure about how to debug it though.
EDIT: The error is thrown because if text(null) returns a string, than you'll be saying string.appentTo rather than $().appendTo.

variable assignments using jQuery failing in Safari?

I'm using jQuery 1.3.2 and it's breaking under Safari 4 for mysterious reasons.
All of my javascript references are made right before the tag, yet with the following code:
var status = $('#status');
status.change( function(){ /* ... */ } );
The following error is displayed in the Web Inspector:
TypeError: Result of expression 'status.change' [undefined] is not a function.
However the error is not encountered if I eliminate the variable assignment attach the change method directly like so:
$('#status').change( function(){ /* ... */ } );
Why? I need to use variables for this and several other findById references because they're used many times in the script and crawling the DOM for each element every time is regarded as bad practice. It shouldn't be failing to find the element, as the javascript is loaded after everything except and .
Try changing the variable to something other than "status."
It's confusing your variable with window.status (the status bar text). When I typed var status = $('#status') into the debugging console, the statusbar changed to [Object object]. Must be a bug in Safari.
If you put the code inside a function, so that status becomes a function-local variable, it should work.
It's standard practice in jQuery to wrap things in a
$.onready(function() {
});
This makes sure the DOM is loaded before you try to manipulate it.

Categories

Resources