jQuery object html() doesn't work ... but innerHtml does - javascript

I have an object that should be a valid jQuery object. When I look at the variable in FireBug it contains all the jQuery functions I'd expect (clone, remove, removeat, etc.). However, I don't see html() as a valid function and when I do this:
stringValue = myjQueryObject.html();
It does fail, saying html() is not a function. However if I do something like this:
stringValue = myjQueryObject[0].innerHTML;
It will correctly pass back the object, minus the parent div and text (which I would expect, seeing as how it is just getting the innerHtml). What do am I missing here?
As noted below, it was an external library that was generating myjQueryObject that had previously returning a valid jQuery object and was updated ... incorrectly. For posterity's sake, I've updated my unit tests to verify that the external library returns a correct jQuery object, make sure this doesn't return null or undefined:
myjQueryObject.jquery
Thanks all! Had a bit of a freakout when my code suddenly broke this morning.

Either something is modifying the jQuery object prototype, or you have a different library loaded.
Take your object, and test for the jQuery version like this:
alert( myjQueryObject.jquery ); // should give the jQuery version number
EDIT:
Additionally, you state that there's a removeAt method. jQuery doesn't have one of those, unless you mean removeAttr().

Are you sure it's a jquery object? Wrap it in $() again and .html() should exist.
it's [0].innerHTML or .get(0).innerHTML, in that innerHTML is a property not a method.
You should make sure that jquery exists by doing alert( jQuery == $) and you can check for the .jquery property.

That's odd; try $(myjQueryObject).html();. If that works, the object isn't really a jQuery node.
If you still can't figure out why the object lost the html() method, post the code which creates it. Then, we might be able to help.

How are you setting myjQueryObject?
<div id='myElement'></div>
//Good Javascript, Incorrect jQuery
myjQueryObject = document.getElementById('myElement');
myjQueryObject.innerHTML = '<b>My HTML Here</b>';
//Correct jQuery
myjQueryObject = $('#myElement');
myjQueryObject.html('<b>My HTML Here</b>');
//Compact Version of Correct jQuery
$('#myElement').html('<b>My HTML Here</b>');

Related

jQuery version of simple javascript doesnt work

I have this code in javascript
var greet;
greet = function() {
var textoNombre;
textoNombre = document.getElementById("textoNombre");
return alert(textoNombre.value);
};
what is working on the HTML document. But if I change document.getElementById("textoNombre") by the jQuery version $("#textoNombre") it just dont work. The alert says "undefined".
I have the jQuery script linked on the head of the HTML before to my custom js file.
This is a very basic question but I tried different things and no one work, can you help me please? Thank you in advance.
That's because jQuery objects don't have a value property, the equivelant is $('#someId').val().
To get the underlying DOM object, you can use $('#someId')[0]. This is because jQuery objects are actually like arrays, and their elements are the DOM objects themselves. That means $('#someId')[0].value would work as you'd expect.
jQuery objects are not DOM objects and don't share all their properties.
To get the current value of a form control, you would use the .val() method, not the .value property.

Why can't you call outerHTML on $(this)?

When you want to get the HTML of an entire DOM element (wrapper included), you can do the following (as explained here):
$('#myElementId')[0].outerHTML
But what you can't do is call outerHTML on $(this) inside e.g. a click listener or selector function body scope:
$(this).outerHTML //Doesn't complete in IntelliSense, returns undefined in browser
or
$(this)[0].outerHTML //Correction, this DOES work, but it doesn't complete in IntelliSense
because IntelliSense won't show innerHTML or outerHTML in those circumstances, although with vanilla JavaScript you can do:
document.getElementById($(this).attr('id')).outerHTML
So... what's up with that?
outerHTML is a DOM property; jQuery doesn't expose all DOM properties.
If you have a jQuery object, you can only directly access those properties and methods that jQuery exposes, and vice versa for DOM objects.
In object-oriented terms, jQuery objects don't inherit from DOM objects, they contain them.
Saying $x[0] gets you the DOM object for the first element represented by a jQuery object.
You can use directly this to access outerHTML of the current object instead of indirectly going through $(this) as this represents the DOM object (which has outerHTML property) whereas $(this) represents jQuery object.
this.outerHTML
jQuery selector returns an array-like jQuery object which has no outerHTML property.
However, the jQuery resulting array contains DOM elements.
It means that you can actually access it this way.
$(".someClass")[0].outerHTML // it works for me
Update:
It works for me in every browser.
I can access array-like jQuery object in a click event handler as well.
$(".someClass").click(function()
{
alert($(this)[0].outerHTML); // it works me too
});
Here is my JSFiddle: http://jsfiddle.net/13btf60p/
Update 2:
OK, now I get your question. It should have worked.
Do you really need an IntelliSense to complete such a plain and simple construction?
I will add what I found to be the correct solution to what ended up being a simple flaw in the default Visual Studio settings for future reference.
Since I didn't want to let this go, I searched further and found out that, by default, jQuery IntelliSense is somewhat deplorable out of the box in Visual Studio 2013.
Under
Tools > Options > Text Editor > Javascript > IntelliSense > References
I set
Reference Group: "Implicit (Web)"
and added an existing jQuery file. This solved all issues of my question and IntelliSense now suggests all members and methods correctly, although this should have simply worked out of the box instead of costing everyone a bunch of time.
this.outerHTML is enough.
If you use getElementById maybe you can use:
var table = document.getElementById('blablabla');

What does $($(this)) mean?

I saw some code around the web that uses the following statement
if ($($(this)).hasClass("footer_default")) {
$('#abc')
.appendTo($(this))
.toolbar({position: "fixed"});
}
What is the use of $($(this)) and why is that necessary here?
Yes, $($(this)) is the same as $(this), the jQuery() or $() function is wonderfully idempotent. There is no reason for that particular construction (double wrapping of this), however, something I use as a shortcut for grabbing the first element only from a group, which involves similar double wrapping, is
$($('selector')[0])
Which amounts to, grab every element that matches selector, (which returns a jQuery object), then use [0] to grab the first one on the list (which returns a DOM object), then wrap it in $() again to turn it back into a jQuery object, which this time only contains a single element instead of a collection. It is roughly equivalent to
document.querySelectorAll('selector')[0];, which is pretty much
document.querySelector('selector');
You can wrap $ as many times as you want, it won't change anything.
If foo is a DOM element, $(foo) will return the corresponding jQuery object.
If foo is a jQuery object, $(foo) will return the same object.
That's why $($(this)) will return exactly the same as $(this).
There is no specific need for double-wrapping and $($(this)) is exactly the same as $(this).
That said, I once found this double-wrapping in one file in my project, committed by another developer. Tracking the changes through revision, turned out that it started as $($(this).find('selector').first()) - that is, the result of some selector was wrapped to create a new object. Then for whatever reasons, the selector was removed and only the double-wrapping of this remained. Needless to say, on the next commit it was changed to $(this).
As explained before me, $($(this)) and $(this) are absolutely identical. jQuery returns the same jQuery object if you try to wrap it more than once.
Additionally, for performance considerations it is a good practice to reuse jQuery objects - it is quite expensive to create jQuery objects, especially the ones with complex selectors. Example:
var $this = $(this);
if ($this.hasClass("footer_default")) {
$('#abc')
.appendTo($this)
.toolbar({position: "fixed"});
}
Just google for 'jQuery best practices' - it will take a 30 min for you to learn these basics and you will use jQuery way more effectively.
There is no meainig of doing that.
The following code return the same:
console.log($($(this)).hasClass("footer_default"))
console.log($(this).hasClass("footer_default"))
a boolean value depenging on if the selected element has or not the class footer_default:
.hasClass( className )Returns: Boolean
Demo: http://jsfiddle.net/IrvinDominin/aSzFn/
$(this) and $($(this)) both return jquery object.
There is no difference between these two.

jQuery in console not working properly

I'm using the jQueryify bookmarklet on a page so that I can call jQuery functions from the console. But everytime I invoke a jQuery function on a selected object, I get the error:
"TypeError: jQuery("li")[0].children[0].html is not a function
[Break On This Error] jQuery('li')[0].children[0].html();
I have tried this in FireBug as well as Google Chrome's Webkit console.
You are no longer working with jQuery objects when using square braces.
jQuery("li")[0]
This returns you the 1st li as a DOMElement, not a jQuery object.
jQuery("li")[0].children[0]
This returns the 1st li's 1st child as a DOMElement, not a jQuery object.
.html()
This function only works for jQuery objects. For DOMElements, you can use the .innerHTML property.
I suggest instead of dealing with DOMElements, you should continue working with jQuery objects. Try using this instead:
jQuery('li').eq(0).children().eq(0).html()
It looks like you are trying to call a jQuery function, html, on a DOM object children[0]. Try wrapping that in a jQuery object and then calling html
var temp = jQuery("li")[0].children[0];
var html = jQuery(temp).html();
Check the result of jQuery("li")[0].children[0] , it's a regular DOM object NOT a jQuery object. Without seeing your HTML i can't recommend a better selector but a cheap and dirty fix would be
jQuery(jQuery('li')[0].children[0]).html();
This will convert the DOM object result into a jQuery object which has the .html() function.
Accessing the array elements on the jquery object (using []) returns a DOMElement, which obviously doesn't have jquery's methods. You probably want to use eq() instead.
Try following
jQuery(jQuery("li")[0].children[0]).html();
or better one
jQuery("li:eq(0)").children(':eq(0)').html();
or another one
jQuery("li:eq(0)").children().eq(0).html();
even this one will work
jQuery("li").eq(0).children().eq(0).html();

Weird Behaviour in jQuery's html method

Any good reason why $("p").html(0) makes all paragraphs empty as opposed to contain the character '0'?
Instead of assuming I found a bug in jQuery, it's probably a misunderstanding on my part.
jQuery only accepts a string as an argument for the val parameter of the html() method. If you pass a number like you are it will call the html() method override that sets the contents of the element but the value of the argument will end up being null or an empty string.
Try this:
$("p").html((0).toString())
Relevant documentation
I guess that at some point, it checks if (newContent == false), and doesn't continue with adding any content? I tried looking at the source, but got a bit lost...
I also guess that this would not be counted as a bug, since the function calls for a string, and if "0" is passed (as a string), it works as expected.
A workaround would be to do this:
var myNum = 0;
$('p').html('' + myNum);
The code performing the html call was within someone else's plugin and rather than modify it, making upgrading it tedious, I just wrote the following tiny plugin that modifies the html method to do as spoon16 recommended.
(function($) {
var oldHtml = $.fn.html;
$.fn.html = function (content) {
oldHtml.apply(this, [content.toString()]);
}
})(jQuery);
It's a little bit of a hack, but it's working for me and doesn't require me to modify the Plugin I'm using.
I just thought someone else might like to see this.
Try using text() instead html().
I geuss you missed part of how jQuery works,
$('p')
returns all paragraphs and the html( val ) function:
Set the html contents of every matched element. This property is not available on XML documents (although it will work for XHTML documents).
http://docs.jquery.com/Attributes/html#val
So if you just want to set the contents for the first p use
$("P").eq(0).html( 'something' );
or to get the html:
$("P").eq(0).html();
http://docs.jquery.com/Core/eq#position
more on jQuery selectors here:
http://docs.jquery.com/Selectors

Categories

Resources