Creating Javascript object from JQuery object - javascript

Currently I'm unit testing the following code:
if ($(selectedElement).innerText == 'blah')
{
// do something
}
with selectedElement being an anchor object selected from the UI.
In my test code, I have created a DOM structure which has that anchor in the proper position ready to be selected. The problem here is that since selectedElement is originally a javascript object, I need to convert the anchor I got from the DOM structure (which is a JQuery object) in order to get into the above condition.
I have tried the following, with no success:
// DOM structure using HtmlDoc
/*:DOC += <span id='testSpan' class='testSpanClass'><a href='#' id='selectedElem'>blah</a></span> */
selectedElement = $('#selectedElem')[0];
My goal is to be able to use a normal Javascript object to satisfy the condition, and also be able to switch it back to a jQuery object to satisfy conditions further down the function. But if there is a better approach I'll give it a go.
Does anyone have any ideas on how to go about this problem?
EDIT: Is there a solution that does not require changing of the code? selectedElement is actually a global variable.
Thanks.

I am not sure what browser you are testing in, but innerText is an IE only property. Since you are already using jQuery, I would suggest you just call the .text() method on the selected element like this:
selectedElement = $('#selectedElem')[0]; // Get DOM element
if ($(selectedElement).text() == 'blah')
{
// do something
}
You're method of getting the DOM object is fine: $('#selectedElem')[0] or $('#selectedElem').get(0) are equivalent, but the first one is faster in large loops.

jQuery's get method returns the original DOM elements for that jQuery object.
I think perhaps you need to use $('#selectedElem').get(0)

can you use jquery's .html() ?
if ($(selectedElement).html() == 'blah')
{
// do something
}
otherwise, without changing code:
var selectedElement = $('#selectedElem')[0];
if (selectedElement.innerHTML == 'blah')
{
// do something
}

Related

Parent of DOM element that is returned by jQuery

I have a problem understanding what is wrong here. I use jQuery to find an element, but I fail finding the element's parent without using jQuery:
$(".selectbox").on("click", function(e) {
e = e || window.event;
var eTarget = e.target || e.srcElement;
find_parent(eTarget);
});
using above to call find_parent function works:
function find_parent (el) {
element_parent = el.parentElement;
}
but if use this to call find_parent it fails:
function someFunction {
selectBoxEl = $(".xyz").find('.selectbox');
find_parent (selectBoxEl);
}
I am not looking for the solution of "why not using jQuery parent()" - and it works fine. I am trying to understand why normal DOM methods don't work on an element returned by jQuery and what I am doing wrong.
Edit:
Sample code above is not the actual code being used, but a very simplified version to illustrate my question. The actual find_parent() function is a long and complicated piece that goes through many elements and their parents for various updates and it doesn't use jQuery. I want to leverage that code and not duplicating it for my need in the sample function someFunction().
The element returned by jQuery is wrapped. Use find_parent(selectBoxEl[0]);
As already you are using jQuery, there is no need use separate function to identify parent DOM element. $('#id').parent() returns parent DOM element.
Still if you want to use .parentElement javascript method, use below method.
$('#id')[0].parentElement
JQuery is not actually returning any DOM element, it will return only instance of DOM object. parentElement propery has to be apply only for DOM element not for instance object.

Why is innerHTML returning 'undefined'?

I'm trying to catch the "value" inside this div, which is editable:
<div class="editable-div" contentEditable="true">Hey</div>
I figured I could do this simply via JavaScript:
var changedText = $('.editable-div').innerHtml
However, this variable will always return "undefined", which confuses me.
Can someone enlighten me on how to reach this "value"?
It is jQuery - you have to use:
$('.editable-div').html()
A jQuery wrapped object is actually not the raw DOM node, but essentially an array of raw DOM nodes that can be acted upon with jQuery specific methods, such as .html(). If you want to interact with the DOM node, you can retrieve it by either iterating through the list or getting the element of that list if you know which one it is:
$('div').each(function(index, element) {
element.innerHTML // ...
}
$('div').get(0).innerHTML
$('div')[0].innerHTML
Note that while it is "kind of" like an array, in that you can get DOM nodes using the array syntax of $('div')[0], you can't treat it like an array in Javascript. In other words, you can't do this:
$('div').forEach(function(element) {
element.innerHTML
}
innerHtml is used with javascript selector and you are using jQuery. so replace innerHtml with .html() or .text() function.
Use this:
var changedText = $('.editable-div').html();
innerHtml is DOM. try $('.editable-div')[0].innerHtml

How do I find out whether an element with that ID exists or not?

I do a:
console.log($('#test'));
I know that test doesn't exist. If I do a console.log, it doesn't output undefined/null. Rather it ouputs something like an empty array and when I check that array it looks like it returns the jQuery object itself.
I also tried:
if ($('#test')){
//do something
}
But it still doesn't work. I want to know whether the ID I am selecting exists on page or not. How do I do that using jQuery?
It's something like 20x faster to do this:
if (document.getElementById("test"))
compared to the jQuery operation to just determine if a DOM object with that id exists in the page. jQuery can do a lot for you, but when its general selector engine and general object structure isn't needed, it's not the quickest way to do things.
As others have said, $("#test") is always a valid jQuery object, even if #testdoesn't exist. If the #test object doesn't exist, then $("#test") will be a jQuery object that has no DOM objects in it (the internal array will have a .length === 0), but it's still a valid object.
In JavaScript, objects are always truthy, so using it in that fashion will always pass the condition.
You need to check the length property. A response of 0 is falsy, and will work as expected.
if ($('#test').length) {
// ...
}
This is unlike document.getElementById(), which returns null if the element with that id attribute does not exist.
If this is confusing, you could always write a quick jQuery plugin.
$.fn.exists = function() {
return !!this.length;
};
You can then call exists() on a jQuery collection, to ensure that selector has matched at least one item.
Use '(' and ')' for 'if' statements, and check if the returned array has length greater than 0:
if ($('#test').length > 0){
//do something
}
use something like this
if ($('#test').length > 0){
alert('hi')
}else
{
alert('hello')
}
Live Demo ​
Use
if ($('#test').length > 0){
//do something
}
the length tells you how many items were selected if it is 0 no element has the id test.
best way for this is to check length of the selected element
if ($('#test').length > 0){
//do something
}
But if you want to create a exist function jQuery welcomes you just add the line in your script
jQuery.fn.exists = function(){return this.length>0;}
and now you can Check if element exist or not
if ($(selector).exists()) {
// Do something
}
console.log($('#test'));
This won't print the value because it represents the object found in the DOM with the id test.
If you want to get values, use $("#test").val(); or $("#test").html();
If you want to check existence, do the length test as suggested above.
Also, if you're testing for the existence of a generated element (something you added to the DOM), make sure you checkout .live (http://api.jquery.com/live/). This is need for all elements that are created after the page is loaded.

Can JQuery and Javascript be mixed together?

I am wondering if I could use query and javascript together so I could select an element by class with the javascript and then use javascript to work on that element. Sorry if that didn't make sense. Here is an example:
$('.nav_flag').src = "images/flags/"+userCountryLower+".gif";
Would that work, if not how do I get an element by class using regular javascript. Thanks!
EDIT:I know JQUERY is JavaScript but I was wondering if I could mix jquery selectors and javascript 'controller'-for a loss of a better word
To answer your question as asked, there are several ways to take a jQuery object, i.e., what is returned by $('some selector'), and get a reference to the underlying DOM element(s).
You can access the individual DOM elements like array elements:
// update the src of the first matching element:
$(".nav_flag")[0].src = "images/flags/"+userCountryLower+".gif";
// if you're going to access more than one you should cache the jQuery object in
// a variable, not keep selecting the same thing via the $() function:
var navFlgEls = $(".nav_flag");
for (var i = 0; i < navFlgEls.length; i++) { ... }
But you wouldn't manually loop through the elements when you can use jQuery's .each() method, noting that within the callback function you provide this will be set to the current DOM element:
$(".nav_flag").each(function() {
this.src = "images/flags/"+userCountryLower+".gif";
});
However, jQuery provides a way to set attributes with one line of code:
$(".nav_flag").attr("src", "images/flags/"+userCountryLower+".gif");
To answer the second part of your question, doing the same thing without jQuery, you can use .getElementsByClassname() or .querySelectorAll() if you don't care about supporting older browsers.
jQuery IS Javascript. You can mix and match them together. But you better know what you're doing.
In this case, you probably want to use .attr function to set value of attribute.
Use .attr() in jQuery, rather than mix the two here.
$('.nav_flag').attr('src', "images/flags/"+userCountryLower+".gif");
In many instances, it is fine to mix jQuery with plain JavaScript, but if you have already included the jQuery library, you might as well make use of it. Unless, that is, you have an operation which in jQuery would be more computationally expensive than the same operation in plain JavaScript.
You can do it with jQuery too:
$('.nav_flag').attr("src", "images/flags/"+userCountryLower+".gif");
keep in mind that jQuery is simply a library built upon javascript.
for any jQuery object, selecting its elements by subscription will return the corresponding dom element.
e.g.
$('#foo')[0] // is equivalent to document.getElementById('foo');
You need to add an index to the jQuery object to get the native Javascript object. Change:
$('.nav_flag').src = "images/flags/"+userCountryLower+".gif";
To:
$('.nav_flag')[0].src = "images/flags/"+userCountryLower+".gif";
To get elements by class name in Javascript you can use:
document.getElementsByClassName( 'nav_flag' )[0].src = "images/flags/"+userCountryLower+".gif";
To answer your question, you could use .toArray() to convert the jQuery object into an array of standard DOM elements. Then either get the first element or loop through the array to set all the elements with the class.
However, you could do this easier with pure jquery with attr or prop depending on the version:
$('.nav_flag').attr("src", "images/flags/"+userCountryLower+".gif");
Or use pure javascript:
if (navFlagElements = document.getElementsByClassName("nav_flag") && navFlagElements.length > 0) {
navFlagElements[0].src = "images/flags/"+userCountryLower+".gif"
}

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