How to remove empty elements after class?(jQuery) - javascript

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();
});
});

Related

Why does removeChild function behave differently with list items and i tag?

I have noticed that removeChild does NOT behave as it does with other elements such as list item. I am using the i tag for some icons from frontAwesome and want these items removed individually when a button is clicked.
Unfortunately, I can only remove each i tag element only if I use removeChild() function twice. (Weird!)
What's going on?
HTML:
<div id="myFonts">
<i>1</i>
<i>2</i>
<i>3</i>
<i>4</i>
<i>5</i>
</div>
Javascript:
function FunctionTwo() {
var font = document.getElementById("myFonts");
font.removeChild(font.childNodes[0]);
}
https://codepen.io/anon/pen/EeaYvL
EDIT
Note: It makes a difference if you use LineBreaks or not!
<ul id="myList">
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
Here, there are 6 child nodes. Apparently, the LineBreaks are also considered as child nodes!
<ul id="myList"><li>Coffee</li><li>Tea</li><li>Milk</li></ul>
Here, there are 3 child nodes. WEIRD - is this a bug?
From MDN,
childNodes includes all child nodes, including non-element nodes like
text and comment nodes. To get a collection of only elements, use
ParentNode.children instead.
Hence, in both the cases, the elements are being removed weirdly. You should update
from
font.removeChild(font.childNodes[0]);
to
font.removeChild(font.children[0]);
For tweaking, https://codepen.io/anon/pen/aazoLK
Also.. if you notice both of your code closely on your link...
Code for <ul id="myList">
<ul id="myList"><li>Coffee</li><li>Tea</li><li>Milk</li></ul>
We see no spaces between tags.
Whereas, Code for <div id="myFonts">
<div id="myFonts">
<i>1</i>
<i>2</i>
<i>3</i>
<i>4</i>
<i>5</i>
</div>
You see the empty spaces before the <i>? Those got added as a text node in the childNodes object of your div
<div id="myFonts">
<i>1</i>
</div>
You could have used exactly the same code that you have currently, if you had chosen to rather Not add spaces before the <i> tags.
For Eg. like this:
<div id="myFonts"><i>1</i><i>2</i><i>3</i><i>4</i><i>5</i></div>
Check modified HTML for div here:
CodePen

Check if control present in main Ul tag or not?

I have following structure.
<ul id="main">
<li id="a"/>
<ul id="main1">
<li id="b"/>
</ul>
</ul>
In above code when the user clicked on the button, I want to check whether li with id=b present in id=main ul or not using jquery. So pleases let me know how can I check using jquery.
You can use below code to achieve what you want
if ($("ul[id='main']").find("li[id='b']").length > 0)
{
// Element is present.
}
else
{
// Element is not present.
}
Try this for a check:
if($('#main').has('li[id="b"]').length > 0)
This will check, if main has any li element with id equals b. The result is an array with all elements or zero elements.

Jquery find('*') doubling A tags

I'm slightly confused by the Jquery find('*') on an element finding A tags. My example code is below:
<ul>
<li id="cell1" data-link="Page 1">
<p>Example text</p>
</li>
<li id="cell2" data-link="Page 2">
<h2 class="story-body__crosshead">More from our Diet Debate series:</h2>
<p>Read: Is breakfast a waste of time?</p>
<p>Watch: How healthy is your breakfast?</p>
</li>
<li id="cell3" data-link="Page 3">Cell 3</li>
<li id="cell4" data-link="Page 4">Cell 4</li>
</ul>
Js Code
$(elem).find('*').each(function(){
if ($(this).html().indexOf('breakfast') > 0){
alert($(this).html());
}
});
Alert is however alerting twice per A tag. It shows the inner text and the outer text (full a html). However I am relying on moving elements and replacing them so this code ends up outputting links twice on the same page. Am I missing something obvious?
Your code is matching the a tags and any ancestors of the a tags because * matches all DOM elements within the elem (which is your LIs). In your example it will match the p tags as well as the a tags.
Use a scoped selector that targets only the a tags:
e.g.
// Elem here is the li about
$("a", elem).each(function(){
if ($(this).html().indexOf('breakfast') >= 0){
alert($(this).html());
}
});
Or simpler using :contains:
$("a:contains(breakfast)", elem).each(function(){
alert($(this).html());
});
Note: Your code only allows for text containing breakfast but not Breakfast (e.g. if it was at the start and capitalized) as the check is case-sensitive.

How to permanently remove an element from a jQuery object

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>

jQuery.HTML not obeying formatting within text

Why dose the following not obey formatting, the "li"s have no effect
<script>
function showENQ() {
jQuery('#enqtext').html("<li>showtext</li>");
}
$('#enq').live('pageshow', function () { showENQ(); });
</script>
<ul data-role="listview" data-filter="true" data-filter-placeholder="Search Enquirylist..."
data-theme="e" data-filter-theme="d" >
<div id="enqtext"></div>
</ul>
try innerHTML instead:
jQuery('#enqtext').html("<li>showtext</li>");
or
jQuery('#enqtext').append("<li>showtext</li>");
I'm not 100% sure but my first idea is that you are placing the <li>'s into a div and not directly into the list itself.
Might work if you append to the ul by giving it an id, e.g.
<ul id="list" ... >
and then do
function showENQ() {
jQuery('#list').append("<li>showtext</li>");
}
Also might be worth changing enqtext to a span instead of a div and finally, check that you are not changing the style of the list items, i.e. make sure you are not doing list-style:none; anywhere in your css.
Try changing:
jQuery('#enqtext').html("<li>showtext</li>");
to:
$('#enqtext').append("<li>showtext</li>");
Edit : Come to think of it, I would remove the Div of ID #engtext completely and give the ID #engtext to your ul.

Categories

Resources