Use .splice() on JQuery object - javascript

We remove child of a certain html element through JQuery via:
$(PARENT_SELECTOR).children(CHILD_SELECTOR).remove()
But how can I make this behave like .splice() method (e.g. removing on the DOM tree the given index and offset). For instance:
Remove the last three children. Here I'll most probably use:
for(var x = 0; x < 3; x++) {
$(PARENT_SELECTOR).children().last().remove()
}
Remove 4th to 6th children. Here I'll use:
$(PARENT_SELECTOR).children().eq(3).remove()
$(PARENT_SELECTOR).children().eq(4).remove()
$(PARENT_SELECTOR).children().eq(5).remove()
Remove 5 elements starting from the 5th child ( this is the real scenario where I want to have a .splice()-like function for JQuery ):
var starting = 5,
index = 5
// I haven't tested this yet.
for(var x = index + starting; x > index; x--) {
$(PARENT_SELECTOR).children().eq(x - 1).remove()
}
And the list goes on... I can make my own case-to-case scripts for each scenarios [, that's easy]. I'm just wondering if JQuery has already it's own feature like this-- it will make my scripting shorter and will not make me to repeat writing similar codes.

I think $.slice is really what you are looking for. Below is the example:
<ul>
<li>list item 1</li>
<li>list item 2</li>
<li>list item 3</li>
<li>list item 4</li>
<li>list item 5</li>
</ul>
$( "li" ).slice( 2, 4 ).remove();
Just keep in mind that .slice() starts with index 0, so example above will remove the third to fifth child.

jQuery Slice method selects a subset of elements based on its index.
This method is used to limit the selection of elements in a group, by a start and end point: the start parameter is a starting index (starts at 0) from which to create the subset, and the stop parameter is an optional ending point.
You can find the better explanation here and here
$(document).ready(function(){
$("p").slice(1).css("background-color", "red");
$("p").slice(2,4).remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>para 0.</p>
<p>para 1.</p>
<p>para 2.</p>
<p>para 3.</p>
<p>para 4.</p>

Related

Javascript function called only once despite multiple event listeners

I am rebuilding one of my own websites specifically to avoid using jQuery since I used so little of it that the memory overhead just isn't necessary, and I'm not concerned about supporting older browsers (the version of Firefox I'm using is likely to be the oldest browser to ever look at my sites; so if they work in that they'll work for 99.99% of my audience). I am encountering a problem when adding multiple event listeners to a few list items in the document.
HTML snippet:
<div class="SubColumn LeftCol grid_12 alpha">
<div class="InfoBox grid_12 alpha omega">
<h1>Side Detail</h1>
<ul>
<li data-detail-item="Detail item" data-detail-info="Info about the detail item!">Detail item</li>
<li data-detail-item="Detail item 2" data-detail-info="Info about the second detail item!">Detail item 2</li>
<li>Detail item</li>
<li>Detail item</li>
<ul>
<li>Detail item</li>
<li>Detail item</li>
<li>Detail item</li>
<li>Detail item</li>
</ul>
<li>Detail item</li>
<li>Detail item</li>
<li>Detail item</li>
<li>Detail item</li>
</ul>
</div>
</div>
Relevant Javascript:
function PrepareDefBoxes()
{
// I'm using document.querySelectorAll() here as a generic swiss army knife
// I use it multiple times throughout the script
// Quite frankly its CSS-selector-syntax input is easier for me to read & maintain
// CSS-style selectors even work on the custom data-* global attributes ^_^
var AllDeets = document.querySelectorAll("li[data-detail-item][data-detail-info]");
// An array of events to add to all the details list items
// Declared here because I *might* need to add more events; you never know~
var Events = ["mouseover", "mouseout", "click"];
// This is a coding trick I've used in C++ and in php
// If you have nested for loops and all your code is in the innermost loop,
// you can actually put them all on the same line or on successive lines,
// then have the scoping braces following the innermost for loop :3
for(var i = 0; i < AllDeets.length; i++)
for(var e = 0; e < Events.length; e++)
{
AllDeets[i].addEventListener( Events[e], function(event) {
DefBox(event.target);
});
console.log("Added " + Events[e] + " to " + AllDeets[i].innerHTML);
}
}
function DefBox(ListItem)
{
console.log("It works!");
}
The function PrepareDefBoxes() is called by an earlier Bootstrap() function that is itself invoked via an onload inline event listener on the document's body tag a la <body onload="Bootstrap()">. When I refresh the page, I get this chunk of output logged to the console, exactly as expected:
Added mouseover to Detail item
Added mouseout to Detail item
Added click to Detail item
Added mouseover to Detail item 2
Added mouseout to Detail item 2
Added click to Detail item 2
However, when I randomly mouse over and mouse out from the two list items that should have THREE event listeners bound to each of them, the function DefBox() is only ever called once! And it logs its output to the console only that once. I don't even get extra output by clicking on the list items, either. When I move the cursor around over those two items, I should be getting a mess of "It works!" printed to the console.
I humbly request solutions that do not use jQuery, por favor!
Your code works fine. I would guess that you just misinterpreted the console output information.
See fiddle: https://jsfiddle.net/3h4y0t01/1/ (I've just made output more obvious):
var counter = 0;
function DefBox(ListItem)
{
document.getElementById('out').innerHTML = counter++;
}

Ordered List Iteration in Javascript

Is there a way to allow me to iterate through an ordered list similar in functionality as table.rows? I am using Javascript.
The reason I ask this is because I have an ordered list that contains another ordered list inside. I just want to return the parent list items and not the child.
<ol id="pList">
<li>Item A</li>
<li>
<ol id="cList">
<li>A's Child 1</li>
<li>A's Child 2</li>
</ol>
</li>
<li>Item B</li>
<li>Item C</li>
<li>Item D</li>
</ol>
I now use getElementsbyTag and that returns all li's including the one in cList. I just want the ones in pList.
Thanks
FYI: I would prefer it done in Javascript. The code has to work within Greasemonkey. I don't really know much about jquery and I am not really much of a javascript programmer.
There is no specific property that gives you direct access to the <li> children of an <ol>.
However it is very easy to enumerate them, particularly when you consider that the only legal children of an <ol> must be white space text nodes and <li> nodes.
var ol = document.getElementById('pList');
var li = [];
var node = ol.firstChild;
while (node) {
if (node.tagType === 3 && node.tagName === 'LI') {
li.push(node);
}
node = node.nextSibling;
}
At the end of which, the array li contains the required children.
The above code will work in any browser. The .children collection has problems on older versions of MSIE, and querySelectorAll is even more modern (and therefore less widely supported).
If using querySelectorAll()* is an option for you, it's easy:
var listItems = document.querySelectorAll( '#pList > li' );
* note: it's a native DOM method, and has nothing to do with jQuery
There's a table of immediate children in every javascript object :
document.getElementById('pList').children
You can even iterate through it and check whatever your need :
var el = document.getElementById('pList');
for (var i = 0; i < el.children.length; i++) {
if (el.children[i].tagName == "LI") {
el.children[i].doWhatever();
}
}

Filter method jQuery

Please help me out with the following code. I don't understand it. I have to use a snippet like this in my project.
$('strong', this) <- this part is not clear to me at all.
Please be kind enough to explain the whole code line by line if possible.
<ul>
<li><strong>list</strong> item 1 -
one strong tag
</li>
<li><strong>list</strong> item <strong>2</strong> -
two <span>strong tags</span>
</li>
<li>list item 3</li>
<li>list item 4</li>
<li>list item 5</li>
<li>list item 6</li>
</ul>
JavaScript:
$('li').filter(function(index) {
return $('strong', this).length == 1;
}).css('background-color', 'red');
$('strong', this) is jQuery selector with $(target, context) format.
According to your code:
this refers to li and $('strong', li) is searching a <strong> that within that li tag.
This statement can also be written as:
$(this).find('strong') and from jQuery library code you'll see that:
$(target, context) format internally implement the
$(context).find(target) process.
For more see here.
The code is basically getting a list of li elements using the jQuery $('li') (this will get all <li> ... </li> tags on the page)
It then reduces this set with the .filter function, filter takes a function as an argument, the function is called on each element in the list, if it returns true the element is returned in the list from filter if it return false the item is ignored.
In this context the function calls $('strong', this).length == 1 where this is the li tag that currently being decided checked by the filter, as mentioned in other answers it's simply checking returning the list of <strong>..</strong> tags in the current li. If there is not strong in the current li, length is 0 so the function returns false, this means the filter wont return that element in the list it produces, it then moves on to the next li.
this means the the first part of the code simply produces a list of li's with a strong tag in them, this is then chained with the css function which colours all those tags in red.
Hope that helps.

Getting an element in Javascript - but what element # is it within the document?

I've got a set of elements that, on click, I want to change colour. Now, I have a colour assigned to each of them (ie, if it's the first one in the list then this colour, if it's the second then a different colour...) but how do I check which one they are? Like, if I click on the third, how do I know it was the third? Is there a javascript method for it or even a jQuery method?
Thanks
If they're siblings:
$(this).index();
This returns a 0-based index, so the third is 2.
If they're not siblings, cache the set:
var els = $('.my_group_of_elements');
Then do this:
els.index( this );
jQuery has an .index() method, that should do what you want.
Example: http://jsfiddle.net/au2fQ/
HTML
<ul id="Test">
<li>Click Me</li>
<li>Click Me</li>
</ul>
<ul id="Test2">
<li>Click Me 2</li>
<li>Click Me 2</li>
</ul>
JS
$('li', '#Test,#Test2').click(function(){
var i = $(this).index(),
k = $(this).index('li');
alert('This is li '+i+' in the ul. This is li '+k+' in the page.');
});

Jquery child selector vs. .each

Given the following example table:
<ul class="topnav">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
What are the differences between:
$selector1 = $('ul.topnav > li');
and
$selector2 = $('ul.topnav').each();
EDIT:
$selector2 = $('ul.topnav li').each();
The first will contain all li's which are a direct child of ul.topnav, the second will contain all ul.topnav elements.

			
				
$('ul.topnav > li') will select all <li>s directly under the ul.
each should take a function as a parameter, and iterate over all matched <ul> - it doesn't not take the children <li>s. If anything, you want $('ul.topnav').children(), which is identical if the ul only contains li elements anyway.
For example, this will alert the number of children each list has (in your case, only the number 3)
$selector2 = $('ul.topnav').each(function(){
alert($(this).children().length);
});
Also see the jquery API.
The second one will evaluate them individually, whereas the first one will evaluate them as a group

Categories