JQuery splice DOM elements - javascript

I would like to perform a splice method much like the native Array.splice but I would like to splice a jQuery collection of DOM elements. How is this done cleanly?
Edit: why do I need example code? I am looking for the exact same functionality of the ECMAScript Array.splice function, except I want it to work on a jQuery array of DOM elements, and update the DOM when it's done.

If you are using a DOM collection after splice of your collection you need reload the DOM with that collection to made effect the changes .
So use append and remove keywords for live changes .. which are equals to splice on an collection.

Selecting elements with jQuery actually gives you an array of elements, which can be treated as a normal javascript array as well as a jQuery object. To ensure that an array is a jQuery object you can wrap it in a call to jQuery(). For example:
var x = jQuery('p'),
y = jQuery(x.splice(x.length / 2, x.length));
x.css('background-color', 'red');
y.css('background-color', 'blue');
x contains the first half of <p> tags, which all now have a red background, and y has the second half, with a blue background.
Here's some proof.
Also, there is no problem with mixing tags (e.g. <p> and <div> tags can be in the array and jQuery will work as expected). See here.

Related

Do HTML elements have 'hidden indexes' for the DOM?

For example, document.getElementsByClassName("whatever") returns a list of elements, and each element has an index (so the element x is the [3] in that list, for example).Do HTML elements save that index inside the element, somehow? Or they're 'unaware' of their position?
Example of the usage I'd do with that property:
You click an element with class "People", using event.target when onclick. So you want to know which position it has, in the 'People' list. Let's say it's event.target.classNameIndex. So once you know the index, you can do things in JavaScript.
Obviously the simple alternative I can think of this is simply picking event.target and searching it inside the getElementsByClassName list. Or simply giving IDs to all elements. But avoiding that would be nice.
Hope you understand my question. :)
No
The elements are generated either dynamically or statically and are independent from everything done with them after being displayed. There are pure javascript ways of obtaining the index of an element in a array-like structure but they will most likely depend on the use of a element.onClick function and pairing them with other elements via some sort of selector.
No, for lots of reasons.
First of all, you are doing a query on the internal DOM structure, and the DOM tree itself might change immediately after your query. Elements can be added, moved or removed.
Furthermore, two very different queries might have overlapping results. E.g. query 1 might return:
[ <div id="a">, <div id="b"> ]
While query 2 could return:
[ <div id="b">, <div id="c"> ]
(for simplicity I am representing the results as arrays)
In the above, how would the element <div id="b"> know its unique and unchanging "index", given the truly infinite amount of possible queries, not the mention the possibly variable DOM again?

Why the first element of the return value of the jQuery empty() function is the element itself?

I saw a code as bellow in a javascript function:
A.empty()[0].options.add(new Option('', ''));
and A is a dom select element. It seems A.empty()[0] is refering to the same select element. This means that empty returns an array whose first element is the dom object itself (i.e, A here).
Can somebody explain this behavior or link me somewhere I can read about this behaviour? (Or I completely misunderstood this code!?)
update: looking at the API documentation here does say the return value is a jQuery. Is this the expected behavior of the jQuery functions that their return value's first element is always the element the function is called upon (given the return value is of type jQuery)?
The empty() method removes all child nodes and content from the selected elements.
and adding option to that select element with a blank ''.
empty() just removes any child nodes and returns the original element.
[0] just returns the first DOM element in the collection. jQuery objects contain an "array-like" collection of HTML elements.
Followup:
jQuery objects are always a collection of 0 or more HTML elements. This is one of the best features of jQuery and allows code to be written that does not fall over when there are no matching elements (although accessing [0] will fall over if you try to access a property when the jQuery object has 0 length, but [0] is a non-jQuery way of doing things).

jQuery: Chain selectors off of DOM element variables

I have this event handler from kendo's drag and drop UI and I've assigned it to a variable, lets say e.
I'm trying to select divs that have ID's containing a certain string. I know the syntax for that when continuing from classic jQuery selectors, i.e.
$('select div[id*="whatever"]')
But can I do this off of a variable that contains a DOM element? I know this is a rather simple question but google has thus far been unable to help me.
If you want to filter a preexisting jQuery result, you can go with this:
var $allDivs = $("div"),
$certainDivs = $allDivs.filter("[id*='whatever']");
I believe you might want .find
// returns all DOM elements that
// (1) are descendants of e
// (2) match the selector
e.find("selector");
If e isn't wrapped with jQuery, you might need to do $(e) instead.

jQuery's after method not working with newly created elements

Insofar as I can tell, the following code should work, creating a <div> element, and then creating a <p> element; the expression should result in a jQuery object with two elements:
$("<div>first element's content</div>").after("<p>second element's content</p>");
However, what I get is very different. The documentation (see the heading "Inserting Disconnected DOM Nodes") tells me the above code should result in a jQuery object, grabbing both HTML snippets and building the two DOM elements. But, what I've gotten, in several different versions of jQuery, all above 1.4, is a jQuery object with only 1 node. However, the following code works just fine, returning (what I believe is) the correct jQuery object, two elements inside:
$("<div></div>").after("<p>second element's content</p>");
And this example works as well:
$("<div></div>").after("<p>second element's content</p>").after("<p>third element's content</p>");
It seems the .after() method works fine if the first DOM node being created is empty, but does not when it is not (irrespective of the contents of subsequent DOM nodes being appended to it).
Am I missing something about jQuery's internals, quirky DOM issues and/or JavaScript peculiarities, or is this simply a jQuery bug that's persisted from version 1.4 on through 1.7?
(Here's a meager JSFiddle demonstrating the issue pretty plainly.)
This was a known bug in jQuery < 1.9. See http://bugs.jquery.com/ticket/8759
In jQuery >= 1.9, the following information from the upgrade guide should be noted:
Prior to 1.9, .after(), .before(), and .replaceWith() would attempt to add or change nodes in the current jQuery set if the first node in the set was not connected to a document, and in those cases return a new jQuery set rather than the original set. This created several inconsistencies and outright bugs--the method might or might not return a new result depending on its arguments! As of 1.9, these methods always return the original unmodified set and attempting to use .after(), .before(), or .replaceWith() on a node without a parent has no effect--that is, neither the set or the nodes it contains are changed.
Use add() to add objects to the collection. I use after() more in DOM elements that already exist or that are cached in a variable, but most of the time, if you work with dynamic markup is more practical to use the equivalent insertAfter().
$("<div>first element's content</div>").add("<p>second element's content</p>");
EDIT:
This works...
var $el = $('<div/>', {
text: 'hey there'
}).after('<p>Lorem</p>');
I found I was still sometimes having issues with .add() in place of .after(), so another easy way to get around this bug is to make a throw away wrapper element, .append() the sibling elements, and use .html() to just get the inner contents of the wrapper.
Example:
$('body').append(
$('<span/>').append(
$("<div>first element's content</div>")
).append(
$("<p>second element's content</p>")
).html()
);
This will add the <div> and <p> but discard the outer <span>. I have found this usually works fine with .append() but can have problems with .appendTo()
In jQuery 1.12.4, I found out that using a class selector instead of an ID selector solves this issue.
If you are struggling with
    $("#myelement1").after("<p>test</p>"),
add a unique class to your element and try this:
    $(".myelement1").after("<p>test</p>")

Break up a form with jQuery?

I have a form, which I want to iterate through. I want to show one fieldset at a time, and then show a "next" and "back" button to go to the next section.
I'm assuming that I start with $('fieldset'); but how do I access individual elements thereafter?
$("fieldset")[i] does not seem to work.
How would I accomplish that with jQuery?
I don't necessarily recommend this, but:
$($('.fieldset')[i]).css(...)
Should work.
If you wrap each call to $('.fieldset')[i] in a new JQuery selector, you create a new JQuery object out of that single item. JQuery objects have the method css that you want. Regular dom objects do not. (That's what you get with $('.fieldset')[i])
From the jQuery documentation:
How do I pull a native DOM element from a jQuery object?
A jQuery object is an array-like
wrapper around one or more DOM
elements. To get a reference to the
actual DOM elements (instead of the
jQuery object), you have two options.
The first (and fastest) method is to
use array notation:
$('#foo')[0]; // equivalent to
document.getElementById('foo') The
second method is to use the get
function:
$('#foo').get(0); // identical to
above, only slower You can also call
get without any arguments to retrieve
a true array of DOM elements.
To get a jQuery wrapper back around the DOM element you just extracted, rewrap it like so:
$( $('#foo')[0] ) //now it's ajQuery element again.
$("fieldset").each(function() {
// code, applied for each fieldset
})

Categories