I have a large Javascript codebase to convert to jQuery. The code is structured such that DOM elements are created in Javascript (using a library called DomBuilder), and saved to variables if they will be needed later, before being added to the DOM.
Eg.
var inputs =
{
submitConfirm: INPUT({type: 'button', value: 'Submit'}),
submitCancel : INPUT({type: 'button', value: 'Cancel'})
};
document.appendChild(inputs.submitConfirm);
Then later for example...
inputs.submitCancel.style.display = 'none';
inputs.submitCancel.addEventListener('click', onClickSubmitCancel, false);
My problem is that jQuery seems to lack a way of manipulating DOM elements directly, as opposed to selecting them first (with for example $('#submitCancel').
Can anyone suggest a way to directly translate the last two Javascript lines given above to use jQuery, given that the DOM elements are already available, and so do not need to be selected?
$(inputs.submitCancel).css('display', 'none');
and
$(inputs.submitCancel).bind('click', onClickSubmitCancel);
See http://api.jquery.com/jQuery/ to see what jQuery accepts.
Any DOM element can be wrapped into a jQuery object very easily:
var myObject = $(domElement)
With myObject you can use jQuery methods.
Use $(elementVar) to get a jQuery object containing the DOM element. For the example you gave:
$(inputs.submitCancel).hide().click(onClickSubmitCancel);
Related
I have been searching this on internet, I have found some answers which were helpful like but they were not enough to solve my problem (e.g.
Similar Problem but no solution provided for my problem)
I am using JRate plugin, I am adding a div inside a div using jQuery. The problem is that when I add it using jQuery and use the JRate Functions then they are not working. But they are working without appending a new div.
I know how to make it work. I will have to use $(document) but I dont know how to use it with this code.
Here is HTML
<div class="jRate"></div>
Here is my Jquery
$(".jRate").jRate({
onSet: function(rating) {
alert(rating);
}
});
Here is my appending code
var divjRate = "<div class='jRate'></div>";
$(divjRate).appendTo('.fb-jRate');
Can any one tell me how can I use $(document) here or any other alternative solution you have.
You need to append the html element first so that it is registered in the DOM. Then, you can call jRate on it
var divjRate = "<div><div class='jRate'></div></div>";
// Append new element to container of choice
$(divjRate).appendTo('.fb-jRate');
// Use plugin on new element
$('.jRate').jRate({
onSet: function(rating) {
alert(rating);
}
});
The solution you have linked applies to binding event listeners, which is not the case with a typical jQuery plugin that usually involves DOM replacement and other things.
You will need to apply the method to newly added DOM elements. The DOM mutation event specification is deprecated due to performance issues, and it is not realistic to expect the browser to keep track of all changes (and what kind of changes) happening in the DOM.
For example, if you're adding new content with an AJAX call, you can apply the method to newly added content within the jqXHR.done() function.
Update: OP provided with some code, so I have adding a way to initialize the plugin for newly added DOM element:
// Declare new element
var divjRate = "<div><div class='jRate'></div></div>";
// Use plugin on new element
$(divjRate).find('.jRate').jRate({
onSet: function(rating) {
alert(rating);
}
});
// Append new element to container of choice
$(divjRate).appendTo('.fb-jRate');
I would like to know if it's possible to access an object property from an appended element. For example:
function anyFct(){
this.div=$('<div ref="dv">').html('Hi').appendTo('body');
div.animal='dog';
div.yld=function(){
alert(div.animal);
};
$('input type="text" value="anyIn" onclick="yeldAnimal(this);"').appendTo(div);
}
function yeldAnimal(obj){
var actElement=$(obj).closest('div[ref=dv]');
actElement.yld(); // I want that this yields 'dog'
}
and my HTML:
<input type="button" value="test" onclick="anyFct();">
So this is the logic: I create a div element when the button is clicked on. This div element has a text that when clicked on calls an external function that calls a method on its parent element (the div).
For many contextual reasons this must be the logic. I've already found a solution that is saving the object div in a global array and then search in all values of the array for the object that triggered the method. However, I would like to know if there is a 'cleaner' or correct way to do this.
It's possible, and there are a couple of ways you could achieve it. The important thing you need to understand is the distinction between jQuery objects and actual DOM elements. When you use jQuery to create a <div> element, you create both; but what you end up with a reference to is the jQuery object - or, if you're chaining jQuery function calls, the result of the last function called. The DOM element, assuming you actually append it to the DOM, persists once that section of code has finished execution, but the jQuery object that's created will vanish when that variable goes out of scope.
When you execute some jQuery code later on to get a reference to your DOM element, it's referring to the same element on your page but it's a different jQuery object, so any custom properties you added to the original one won't be available. How do you get around that? Set the properties on the actual DOM element.
You can use the .get() method to access the underlying DOM element from a jQuery object, indexed from 0 (so .get(0) called on a jQuery object will return the first DOM element it references). With that you can then set your custom properties and later retrieve them, something like this:
function anyFct(){
this.div=$('<div ref="dv">').html('Hi').appendTo('body');
var elem = div.get(0); // the actual DOM element, the div
elem.animal='dog';
elem.yld=function(){
alert(elem.animal);
};
$('<input type="text" value="anyIn" onclick="yeldAnimal(this);"/>').appendTo(div);
}
function yeldAnimal(obj){
var actElement=$(obj).closest('div[ref=dv]').get(0); // also the div
actElement.yld(); // alerts 'dog'
}
jsFiddle demo
Note that I've made a few changes to your code in addition to adding in the usage of .get(), most notably correcting the syntax for creating the <input type="text"> element in the first function.
Okay, most of this is not syntactically correct javascript and seems to be overly complicated. I believe if I understand what you're trying to achieve you want the following:
function anyFct(){
var div=$('<div ref="dv">').html('Hi');
div.animal='dog';
div.yld=function(){
alert(this.animal);
};
var element = $('<input type="text" value="anyIn">');
$(element).click(function() {
div.yld();
});
$(div).append(element);
$('body').append(div);
}
So, I know how to create an element in jQuery in various ways. But I've never come across this before today:
var myspacer = $('<div />', {
"id": "nav-spacer",
"height": mynav.outerHeight()
});
Later on in the code, this variable is added to the DOM with jQuery's .before() method. Can somebody explain what's going on here? What kind of object is being created? How does jQuery know how to turn this into an HTML element?
That is the $( html, props ) syntax of the jQuery() function - it is explained quite clearly in the API documentation:
html A string defining a single, standalone, HTML element (e.g. <div/> or <div></div>).
props An map of attributes, events, and methods to call on the newly-created element.
If the function determines that the first parameter is a string that looks like an html snippet it creates a new element (or elements) from that snippet. If you pass a map in the second parameter it creates the specified attributes on the newly created element.
The new element is not automatically added to the document, but you seem to already have seen that since you mention the .before() code that does add it.
According to jQuery $( html, properties) syntax, above code creating a div with id="nav-spacer" and height supplied by mynav.outerHeight() method without any content as jQuery object but not added to DOM.
In $( html, properties), html is string and properties is collection of attributes/event and so on.
An alternative approach may be:
var myspacer = $('<div id="nav-spacer" height="'+ mynav.outerHeight() +'"></div>');
But your one is more readable and efficient.
Using .before() method myspacer is added to DOM just before the selector passed within .before() as param. Example:
myspacer.before('div.hello');
Will add myspacer before the div with class=hello like:
<div id="nav-spacer" height="some_value"></div>
<div class="hello"></div>
jQuery creates a new element if you pass in HTML like $('<div/>') because it's smart. :P It recognizes that the string is HTML (rather than a selector) and treats it differently. See the docs.
The new element is created but not added to the DOM until you add it yourself, eg. with appendTo().
From the documentation: "To ensure cross-platform compatibility, the snippet must be well-formed. Tags that can contain other elements should be paired with a closing tag."
Edit: I stand corrected, you can write $('<div/>') without an explicit closing tag. This works as long as the HTML doesn't contain nested elements (of course). See the other examples from the docs:
// With nested elements and closing tags - HTML must be well formed
$("<div><p>Hello</p></div>").appendTo("body");
// Without closing tag - HTML is still well formed
$("<div/>", {
"class": "test",
text: "Click me!",
click: function(){
$(this).toggleClass("test");
}
}).appendTo("body");
Similar questions:
jQuery document.createElement equivalent?
Creating a div element in jQuery
What is the most efficient way to create HTML elements using jQuery?
http://api.jquery.com/jQuery/#jQuery2
This should give you the explanation you're looking for =D.
To summarize, it's a quick JQuery on-the-fly element creation method.
How can I get jQuery to return a html element exactly the way that getElementById does?
if I console.log($('#container')) I will get :
[<div id="container"></div>]
But the API I am interacting with obviously doesn't want that (an array) - it wants :
<div id="container"></div>
I know I can achieve this with $('#container').get(0) and a few other ways, It just seems overkill - especially as I'm selecting an ID which will always be unique.
What am I missing guys?
Thanks
If you just want a single DOM element, then just use plain javascript:
var obj = document.getElementById("container");
jQuery selectors always create a jQuery object with an array of elements in it. That's just the way it's designed. If you want a single element, you either get the first element out of the jQuery object or you use a different tool.
From a jQuery object, you can get the first object either with:
$('#container').get(0)
or with:
$('#container')[0]
But, I would argue that both are more than you need if all you want is the single object that has an id. Just use document.getElementById(). If you want less typing, you could make your own short function:
function $$(id) {
return(document.getElementById(id));
}
var obj = $$("container");
try using .html() it will return the html of the element your selecting see:
http://api.jquery.com/html/
I've just started using jQuery, but am a bit stuck. I am building a table dynamically in Javascript and am adding classes all the time to cells (for styling), so I would like to use the addClass function:
var row = table.insertRow(-1);
var cell = row.insertCell(0);
cell.addClass('boldRow');
but this does not work. I know you can use the magic $('') function to be able to use jQuery, but can I use it on 'native' HTMLElement references?
$(cell).addClass should do the trick - why don't you try it and let us know.
In any case you have to use the $() to load the jQuery framework to get access to addClass.
You just place the element in like you would a string.
$(someElementReference).addClass('boldrow');
You can also pass in a collection of elements if that is what you have.
Here's an example: http://jsfiddle.net/qS473/
Yes, you can pass in native DOM objects into the jQuery function, and it will create a jQuery object from the DOM object:
$(cell).addClass('boldRow');
But you don't need jQuery to add a CSS class to a DOM object!:
cell.class += ' boldRow';
Yes, you can select all HTML elements with $() for example, $('body'), or $('html') etc. Since it's only a framework, you can also use any other Javascript you can think of to fix this.
Usually the first thing I do when creating a new element is something like this:
var newDivJQObject = $(document.createElement('div'))
.attr('id', '[uniqueID]')
.addClass('[className]');