I'm doing a fairly exhaustive series of DOM manipulations where a few elements (specifically form elements) have some events.
I am dynamically creating (actually cloning from a source element) several <select> boxes and assigning a change() event to them.
The change event executes, and within the context of the event, "this" is the HTML Element Object.
What I need to do at this point however is determine a context for this HTML Element Object. I have these objects stored already as jQuery entities in assorted arrays, but obviously
[HTMLElement Object] != [Object Object]
And the trick is that I cannot cast $(this) and make a valid comparison since that would create a new object and the pointer would be different.
So... I've been banging my head against this for a while. In the past I've been able to circumvent this problem by doing an innerHTML comparison, but in this case the objects I am comparing are 100% identical, just there's lots of them. Therefore I need a solid comparison.
This would be easy if I could somehow derive the HTMLElement object from my originating jQuery object.
Thoughts, other ideas? Help. :(
This would be easy if I could somehow derive the HTMLElement object from my originating jQuery object
you don't just mean $("#object")[0] or $("#object").get(0) with 'derive' do you?
Can't you just use $(this).data("something") to keep data on your elements and then check the values later? (That's assuming you can't just give these things plain ol' "id" values.)
Oh also jQuery itself has a "guid" element that you can use (be careful!)
$(myNewObject).data("identity", $.quid++);
If you maintain a jQuery object containing the elements you've created/cloned (let's call it "jqClonedElements"), you can reduce that set to the single element matching "this" with $().filter(element):
var jqThis = jqClonedElements.filter(this);
After this, you may want to confirm that your element was found, as follows:
var elementWasFound = (jqThis.length > 0);
That should be all there is to it!
-Matt
Related
I have this scenario where i need to assign a java-script object to div attribute.
var temp["name"]="first";
i assigned it to a div tag attribute using Jquery.
div.attr('data-polygon',temp);
Object [ <div#image01> ]
when i try to retrieve it , it does not come back same.. it is converted as String.
div.attr('data-polygon');
"[object Object]"
Any proper option / alternate to retain the object in attribute? please let me know
Attributes are always strings.
Here are two options for doing this; since you're already using jQuery, the first is probably best:
jQuery's data
jQuery provides the data method for doing this:
// Setting -- notice no "data-" prefix
div.data("polygon", temp);
// Retrieving
varName = div.data("polygon");
Under the covers, traditionally data assigns the element a unique ID and manages a data cache for the element, separate from it. I think in the v3 branch they've updated it to actually store the data on the element (there were memory issues with doing that in Internet Explorer 8 and earlier, which is why jQuery didn't do it before).
Assign it as your own "expando" property
If you don't need to support Internet Explorer 8, you can just create a property on the actual DOM element.
// Setting
rawDiv.myUniquePrefixToAvoidConflicts_polygon = temp;
// Getting
varName = rawDiv.myUniquePrefixToAvoidConflicts_polygon;
Note that to avoid conflicts with the many predefined properties elements have, and future ones they don't have yet, you'll want to use a likely-unique prefix.
How to can I treat the return value of jQuery functions that would return a bunch of DOM elements. E.g. I'm using the .nextAll() function, that returns a bunch of elements, does it? Can I store the return value in a JS array? Sooner or later I want to iterate through those elements. I know there's the jQuery .each() function that would help me out here. Nevertheless, for training and understanding issues I first want to do it step by step.
I'm pretty sure, this basic question is answered somewhere, but I searched for an answer and did not find anything useful for me. Maybe I didn't find the right words. So please be kind.
jQuery functions typically returns a bunch of DOM elements, it masquerades as an array.
If you run something like:
$('p').css('background-color', 'red');
jQuery will build an array of all p elements, and then applies the css() function to each of them.
If you want a single DOM item, use get with an index:
$( "li" ).get( 0 )
So, .nextAll() also typically returns a number of elements, so it is behaving just like jQuery typically does.
each() is a handy-dandy function that operates on arrays, so it will of course operate just fine on jQuery objects:
$('li + li').nextAll().each(function(i){
//glorious code
});
You could also do this:
var nexts = $('li + li').nextAll();
$.each(nexts, function(i){
//Glorious code!!
});
Hope that makes things clearer!
You can just assign it to a variable:
var $els = $(selector).nextAll();
This way, $els will be a jQuery wrapper (array-like object) of the elements.
If you want to have an array of the elements instead, you can use
var arr = [].slice.call($els);
As the documentation of .nextall() says, it returns jQuery
A jQuery object contains a collection of Document Object Model (DOM)
elements that have been created from an HTML string or selected from a
document. Since jQuery methods often use CSS selectors to match
elements from a document, the set of elements in a jQuery object is
often called a set of "matched elements" or "selected elements".
The jQuery object itself behaves much like an array; it has a length
property and the elements in the object can be accessed by their
numeric indices [0] to [length-1]. Note that a jQuery object is not
actually a Javascript Array object, so it does not have all the
methods of a true Array object such as join().
How can I remove all the elements with a specific tag name using Javascript. For example, I did the following:
var els = document.getElementsByTagName("center");
and it returned an array of all the center elements. How may I remove all these elements?
Coming from Remove all child elements of a DOM node in JavaScript and JavaScript DOM remove element I know that I can loop through els, find the parent of each element and then remove that specific node. But is there anyother way provided by javascript. Like we can do $('center').remove() in jquery and it removes all the elements with center tag. Anything similar to that in Javascript?
With the mention that you still loop over the elements (there is no way to avoid that), you can do this:
Array.prototype.slice.call(document.getElementsByTagName('center')).forEach(
function(item) {
item.remove();
// or item.parentNode.removeChild(item); for older browsers (Edge-)
});
DEMO: http://jsbin.com/OtOyUVE/1/edit
Some notes on slice:
document.getElementsByTagName doesn't return an array, it returns a live list with a length
property. That is why it is needed to first convert it into an array (Array.prototype.slice does that for any object with the length property). By doing that you eliminate the problem of the list being live (gets updated when you change the DOM) and you also get the other array functions to work (like forEach) which have a more functional syntax for looping.
"it returned an array of all the center elements."
Well, it returned an array-like object (a live NodeList or an HTMLCollection depending on the browser).
"How may I remove all these elements?"
You have to loop through the list removing them one at a time as you mentioned later in your question. If you find yourself doing that a lot, encapsulate the looping inside a function so that you don't have to repeat it.
"we can do $('center').remove() in jquery and it removes all the elements with center tag. Anything similar to that in Javascript?"
jQuery is a collection of JavaScript functions, so it can't do anything JavaScript can't do. jQuery's .remove() method (like most other jQuery methods) will loop internally, it just saves you having to think about it. So that comes back to what I already mentioned above, encapsulate the loop/remove code in a function so that you can use it from any part of your code.
$(".item").each (i, elt) ->
$(elt).attr("href")
# ...
Doing $(elt) is necessery to get the jquery object. Is there a way to iterate over a jquery collection, without having to rebuild the jquery object?
Doing $(elt) is necessery to get the jquery object.
Yes.
Is there a way to iterate over a jquery collection, without having to rebuild the jquery object?
No. Because the jQuery object you have is a set of all of the matched elements. To use the jQuery methods on individual elements, you need to get a jQuery object containing just the individual element you want to act on. In a loop, that means wrapping your elt (or this, as both are the same DOM element).
For lots of things, though, you don't need jQuery methods. Your example is one of those things, just use elt.href directly:
$(".item").each (i, elt) ->
var someVar = elt.href;
# ...
The DOM2 HTML spec and the newer HTML5 spec both list lots of reflected properties you can use directly. id, for instance, is one in particular people frequently use. You see $(this).attr("id") a lot where this.id would be sufficient (and more efficient, although it's extremely rare that the efficiency matters).
Yes, cache the jQuery object then select by index.
var $items = $(".item");
$items.each(function(i) {
$items.eq(i).doStuff();
});
I have an array of objects with various objects within to hold UI values. I wanted to have a button so that element 0's values are replicated through the whole array. However I noticed that setting one set them all. Here is an example without using any looping:
console.log('manual 3: ', lis[3].spacer.divider.type); // prints 'none'
lis[1].spacer.divider.type = 'bananas';
console.log('manual 3: ', lis[3].spacer.divider.type); // prints 'bananas'
I am completely baffled how setting lis[1] also set lis[3]
They must both be references to the same object.
If they're DOM nodes, you can copy them using cloneNode().
Watch out for IE bugs - it has a habit of not cloning properly (for example cloning a <select> doesn't maintain the selectedIndex).
See also What is the most efficent way to clone a JavaScript object? for cloning objects.
Because the variables are reference variables and they all reference the same object and as a result it looks like changing one changes all of them, really they are all the same underlying object.
If you want lots of unique arrays they should all be created as a fresh or be clones of each other.
It turns out I was referencing the same object. Thanks. It didn't click to me since all the other objects above (spacer,lis) were unique. I accidentally was setting divider to a member default of spacer instead of a function returning the default.
Thanks!