How to permanently remove an element from a jQuery object - javascript

here is the problem.
I have code like this where I get all li elements into a jQuery collection and then I remove last item from DOM. But I don't know how to also remove an element from a jQuery collection?
Now it's something like this:
console.log(myList);
['li.item', 'li.item', 'li.item']
I need to pop last item and get something like this:
console.log(myList);
['li.item', 'li.item']
var myList = $('.item');
console.log(myList);
myList.last().remove();
console.log(myList);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="item">Item</li>
<li class="item">Item</li>
<li class="item">Item</li>
<ul>

To remove an element in the jQuery object, you can use .splice().
To remove the last element :
myList.splice(-1);
To remove the first element :
myList.splice(0, 1);
It is important to know that the returned value is an HTMLElement. If you wanna do something with it, you need to convert it into a jQuery element again.
Unfortunatly, jQuery doesnt have pop or shift by default. But you can easily create those methods with that :
$.fn.pop = function(){
return $(this.splice(-1));
}
$.fn.shift = function(){
return $(this.splice(0,1));
}
Then call:
myList.pop();
myList.shift();
If you want to remove in the DOM and in the object, you can chain the remove function :
myList.pop().remove();
myList.shift().remove();
$(myList.splice(0, 1)).remove();
$(myList.splice(-1)).remove();

The problem is that $.fn.remove doesn't update collection elements and length property after it removes elements from DOM. As the result collection becomes desynchronized with actual DOM. What you can do however is to use combination of jQuery's remove method and native javascript pop or splice. It can be pretty concise:
$([].pop.call(myList)).remove();
Check the demo below.
var myList = $('.item');
alert(myList.length);
$([].pop.call(myList)).remove()
alert(myList.length);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="item">Item 1</li>
<li class="item">Item 2</li>
<li class="item">Item 3</li>
<ul>

You can use .slice to select a specific cached item from the jQuery object, but it is little tricky to update the original cached element. I used .not function to filter out the removed element from the cached selector.
Explanation:
//read as numbered for better understanding
myList = myList.not( // 3. Use .not to remove the Last element from the
// cached selector
myList.slice(-1) // 1. Select Last element using .slice(-1)
.remove() // 2. Remove Last element
);
var myList = $('.item');
console.log(myList);
myList = myList.not(myList.slice(-1).remove());
console.log(myList.css('color', 'red'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="item">Item 1</li>
<li class="item">Item 2</li>
<li class="item">Item 3</li>
<ul>

Related

How to keep only the first element from a class when cloning with jquery

Each of my divs have a class attributes named remove, the first class has the id: remove_item then the second remove_item_1, the third remove_item_2, etc.
My problem is that i only want to clone first one with the id remove_item and remove all the other one from the clone.
If i do clone.find('.remove'); i am able to gather all the elements with remove class but from there i am kinda lost on how to do that.
Could anyone help ?
Thanks.
You can keep first div by adding :first.
clone.find('.remove:first');
I think I got what you mean
here's an example how to pick the first element of a cloned div:
lets say you have
<ul id="list">
<div id="clone">
<li class="remove remove1">Remove 1 </li>
<li class="remove remove2">Remove 2</li>
<li class="remove remove3">Remove 3</li>
</div>
</ul>
The script to clone the list and remove the first child of the clone goes like this :
<script>
let clone = $('#clone').clone().appendTo('#list');
clone.children().first().remove();
</script>
or you can select the first one by class selection as #Manashree Shah mentioned like this:
clone.find('.remove:first');
The code uses jQuery, you can add this before the script if you haven't already added it :
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

jQuery target next `ul` element from `li` with class `active`

Cannot figure what I am doing wrong, as I get no errors. Essentially I want to target the very next ul element from the one and only li containing a class of active.
My HTML is:
<li id="abc"></li>
<li id="account" class="active">
<img class="menu-logo-symbol" src=" /img/app/logo-symbol.png">Your Account
<ul class="nav-pills nav-stacked sub-nav nav-list" style="display: none;">
<li id="account-details"></li>
......
</ul>
</li>
I have tried the following:
var checkElement = $('li.active').next('ul');
checkElement.slideDown('normal');
and
$('li.active').next('ul').show();
and also
$('li.active').next('ul').slideDown('normal');
Thanks
In jQuery, next() and prev() find siblings, or elements at the same depth in the DOM. In this case, since the ul is a child element of .active, you'd actually need to use the find() method like so: $('li.active').find('ul').first().show();
Using first() in combination with find() ensures that it'll only return that single ul element and not any others that may be nested deeper.
Done as follows:
$('.active ul:first').slideDown('normal');
I still do not understand why this did not work
$('li.active').next('ul').show();

How to remove empty elements after class?(jQuery)

I have a series of elements after a certain class that are empty or having a white space inside it.
<div class="post-content">
<div class="slider-1-smart">
--- contents of the slider ---
</div>
<div></div>
<div> </div>
<ul>
<li>Text 1</li>
<li>Text 2</li>
<li>Text 3</li>
</ul>
</div>
This is the code that i tried so far:
$(function() {
$('.post-content > div:empty').each(function() {
j(this).remove();
});
});
The result of that code is that the slider container also dissappears. What is the way to select elements after class="slider-1-smart" and remove it
Please let me know, THanks
The :empty psuedo-class only selects elements that are completely empty. In other words, if it has whitespace, it's technically not considered empty.
You could select all the following sibling div elements with .nextAll() and then filter them based on whether the trimmed HTML is equal to an empty string:
Example Here
$('.post-content > .slider-1-smart').nextAll('div').filter(function() {
return $.trim($(this).html()) === '';
}).remove();
If you don't want to check the slider element contents, all you need to do is make one modification to your code. Add .not("slider-1-smart") to the selector chain.
$(function() {
$('.post-content > div:empty').not(".slider-1-smart").each(function() {
$(this).remove();
});
});

jquery find element considering parent

How can I find an element considering parent node? Example:
<ul class="level-3">
<li class="item-1">1</li>
<li class="item-2">2</li>
<li class="item-3">3</li>
</ul>
var $ul = $('.ul');
console.log($ul.find('.item-1')) - // found - OK
if find
console.log($ul.find('.level-3')) - // not found - WHY ???
Assuming UL as element
You are not able to find it as level-3 is not the child of ul.
As per your current HTML, You need to use .filter()
Reduce the set of matched elements to those that match the selector or pass the function's test.
Code
var $ul = $('ul');
$ul.filter('.level-3')
You can use soma kind of jQuery functions to do this:
Closest: find the anchestor element matches the selector.
The .closest() method begins its search with the element itself before progressing up the DOM tree
Parents: walk the DOM tree looking for all parents that matches the selector.
is: check if the element match the selector.
$ul.closest(".level-3")
In your point you don't have ".level-3" class. For simply you can use jquery to do this.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("#btn1").click(function(){
alert($("ul").find('.item-3').text());
});
});
</script>
</head>
<body>
<ul class="level-3">
<li class="item-1">1</li>
<li class="item-2">2</li>
<li class="item-3">3</li>
</ul>
<button id="btn1">Show level 3 Text</button>
</body>
</html>

Inserting HTML into tag using JavaScript

I'm having a problem with JavaScript/jQuery at the moment where I'm trying to access the element inside the h4 element in my code. I'm doing this because I would like to dynamically display to the user how many guides are available in each "h4" section. For the PC section, it should display "4 reviews available" and for the Xbox One section, it should display "3 reviews available". However, both say " reviews available", and I'm assuming it's because I'm not using the jQuery functions properly. Here's the HTML code:
<h4><li class="console">PC (<span class="number"></span> reviews available)</li></h4>
<div class="gameList">
<ul>
<li class="game">Guide #1</li>
<li class="game">Guide #2</li>
<li class="game">Guide #3</li>
<li class="game">Guide #4</li>
</ul>
</div>
<h4><li class="console">Xbox One (<span class="number"></span> reviews available)</li></h4>
<div class="gameList">
<ul>
<li class="game">Guide #1</li>
<li class="game">Guide #2</li>
<li class="game">Guide #3</li>
</ul>
</div>
And here's the jQuery/JavaScript code:
$("h4").each(function() {
var node = $(this).children().children(); // gets node that has "number" class
var count = $(this).next().children().children().length; // gets number of li tags
node.innerHTML = count;
});
I tested whether or not it's properly getting the correct node and count by using the alert function for JavaScript, but for some reason, node.innerHTML = count won't display the contents of "content" properly in the element. Rather, it just displays a blank. Does anyone know why?
Its a jquery object not a DOM one..use this...
node.html(count);
node is a jQuery object here. It does not have "innerHTML". Instead you can use one of these:
node.html(count);
node.get(0).innerHTML = count;
node.get(0) will give you first DOM object from jQuery one.
A good practice is to prefix or suffix all jQuery objects with $ (e.g. $node), so that you will always know if a variable is meant to be a jQuery object.
use find() lot more cleaner and readable
$("h4").each(function() {
var $this=$(this);
var node = $this.find('.number');
var count = $this.next().find('li').length; // gets number of li tags
node.text(count); //or html()
});
and you have come invalid HTML li in h4 make sure you change that
working fiddle here
Do not use .children().children().
Only one .children() would do.
$(this).children('.game');
Also innerHTML is plain javascript. use .html(value) as node is JQuery Object.
$("h4").each(function() {
var node = $(this).children('.number');
var count = $(this).next().children('li').length;
node.html(count);
});
Reference to JQuery APIs:
.html()
.children()
$("h4").each(function() {
var $spanNumber = $('.console .number', this),
gameListCount = $(this).next().find('ul li').size();
$spanNumber.text(gameListCount)
});
You may use this also,
$("h4").each(function() {
var node = $(this).find('.number');
var count = $(this).next().find('.game').length;
node.html(count);
});

Categories

Resources