Via javascript or jquery, I am in need of removing duplicate elements in sets so that one remains. They're all the same, so it doesn't matter which are removed so long as one remains. The page appears as follows:
<div class="column-hr"></div>
<div class="column-hr"></div>
<div class="column-dude"></div>
<div class="column-hr"></div>
<div class="column-hr"></div>
<div class="column-dude"></div>
<div class="column-hr"></div>
One <div class="column-hr"></div> before every <div class="column-dude"></div> needs to stay, but every subsequent hr column before every dude column needs to go.
I tried the following, hoping it would be this simple. Didn't work.
$( "div.column-hr" ).each(function( index ) {
if ($(this).next('div.column.hr')) {
$(this).remove();
}
});
You can achieve this with sibling selector +. Very easy and also the fastest solution, since the browser's CSS engine will be used to select elements:
$(".column-hr + .column-hr").remove();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="column-hr">hr</div>
<div class="column-hr">hr</div>
<div class="column-dude">dude</div>
<div class="column-hr">hr</div>
<div class="column-hr">hr</div>
<div class="column-dude">dude</div>
<div class="column-hr">hr</div>
How it works: CSS selector .column-hr + .column-hr selects .column-hr elements that have immediate previous sibling .column-hr. As the result this expression will select all adjacent .column-hr elements except the very first one, because the first one doesn't have another .column-hr right before it.
You can try this:
$( ".column-hr" ).each(function() {
console.log($(this).html());
console.log($(this).next().attr('class'));
if ($(this).next().attr('class') == 'column-hr') {
$(this).remove();
}
});
https://jsfiddle.net/aodnw5ns/
var classesToRemove = ['column-hr', 'column-dude'];
var $elements;
for (var i = 0, l = classesToRemove.length; i < l; i++) {
// Find elements
$elements = $('.' + classesToRemove[i]);
var elementsLength = $elements.length;
// If there is more than one element
if (elementsLength > 1) {
// get all elements except the first
$elements = $elements.slice(1, elementsLength);
// remove them
$elements.remove();
}
}
// prevent memory leaks
$elements = null;
JSFiddle
Related
I'm trying to only show certain divs. The way I have decided to do this is to first hide all elements that start with "page" and then only show the correct divs. Here's my (simplified) code:
<form>
<input type="text" onfocus="showfields(1);">
<input type="text" onfocus="showfields(2);">
</form>
<div class="page1 row">Some content</div>
<div class="page1 row">Some content</div>
<div class="page2 row">Some content</div>
<div class="page2 row">Some content</div>
<script>
function showfields(page){
//hide all items that have a class starting with page*
var patt1 = /^page/;
var items = document.getElementsByClassName(patt1);
console.log(items);
for(var i = 0; i < items.length; i++){
items[i].style.display = "none";
}
//now show all items that have class 'page'+page
var item = document.getElementsByClassName('page' + page);
item.style.display = '';
}
</script>
When I console.log(items); I get a blank array. I'm pretty sure the regexp is right (get all items starting with 'page').
The code I'm using is old school JS, but I'm not adverse to using jQuery. Also if there is a solution that doesn't use regexp, that's fine too as I'm new to using regexp's.
getElementsByClassName only matches on classes, not bits of classes. You can't pass a regular expression to it (well, you can, but it will be type converted to a string, which is unhelpful).
The best approach is to use multiple classes…
<div class="page page1">
i.e. This div is a page, it is also a page1.
Then you can simply document.getElementsByClassName('page').
Failing that, you can look to querySelector and a substring matching attribute selector:
document.querySelectorAll("[class^=page]")
… but that will only work if pageSomething is the first listed class name in the class attribute.
document.querySelectorAll("[class*=page]")
… but that will match class attributes which mention "page" and not just those with classes which start with "page" (i.e. it will match class="not-page".
That said, you could use the last approach and then loop over .classList to confirm if the element should match.
var potentials = document.querySelectorAll("[class*=page]");
console.log(potentials.length);
elementLoop:
for (var i = 0; i < potentials.length; i++) {
var potential = potentials[i];
console.log(potential);
classLoop:
for (var j = 0; j < potential.classList.length; j++) {
if (potential.classList[j].match(/^page/)) {
console.log("yes");
potential.style.background = "green";
continue elementLoop;
}
}
console.log("no");
potential.style.background = "red";
}
<div class="page">Yes</div>
<div class="notpage">No</div>
<div class="some page">Yes</div>
<div class="pageXXX">Yes</div>
<div class="page1">Yes</div>
<div class="some">Unmatched entirely</div>
Previous answers contain parts of the correct one, but none really gives it.
To do this, you need to combine two selectors in a single query, using the comma , separator.
The first part would be [class^="page"], which will find all the elements whose class attribute begins with page, this selector is thus not viable for elements with multiple classes, but this can be fixed by [class*=" page"] which will find all the elements whose class attribute have somewhere the string " page" (note the space at the beginning).
By combining both selectors, we have our classStartsWith selector:
document.querySelectorAll('[class^="page"],[class*=" page"]')
.forEach(el => el.style.backgroundColor = "green");
<div class="page">Yes</div>
<div class="notpage">No</div>
<div class="some page">Yes</div>
<div class="pageXXX">Yes</div>
<div class="page1">Yes</div>
<div class="some">Unmatched entirely</div>
You can use jQuery solution..
var $divs = $('div[class^="page"]');
This will get all the divs which start with classname page
$(document).ready(function () {
$("[class^=page]").show();
$("[class^=page]").hide();
});
Use this to show hide div's with specific css class it will show/hide all div's with css class mention.
Here's the html:
<div class="col-sm-12" id="ProdutosPedido">
<div class="row">
<div class="col-sm-12 formProdutoAdd" id="produto_1">
...
</div>
</div>
</div>
As things happen within the page, divs are appended inside #ProdutosPedido, and #produto_1 increments to #produto_2 and so on.
This is not working for me:
console.log($("#ProdutosPedido > [id^=produto_]").length);
I need to iterate over these "produto_" and use the 'i' to refer to the current div, but I don't know how to do it. My example logs 0, and that should not be the case, since it starts with 1.
Since your produto divs are not direct children of ProdutosPedido, but its descendants, you need to use the following selector:
$("#ProdutosPedido [id^=produto_]")
Here is the working JSFiddle demo.
Pure Javascript Solution
function CountDiv() {
var nodes = document.getElementById('ProdutosPedido').getElementsByTagName('*');
var Count = 0;
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].id.substring(0, 8) == 'produto_')
Count++;
}
alert(Count);
}
I have a parent div and it has 9 same div's am trying to swap two div's index. Following is my code:
HTML:
<div id="cont" class="container">
<div class="no">1</div>
<div class="no">2</div>
<div class="no">3</div>
<div class="blank"></div>
<div class="no">4</div>
<div class="no">5</div>
<div class="no">6</div>
<div class="no">7</div>
<div class="no">8</div>
</div>
now I want to swap say 5th and 6th indexed elements. I have no clue how to do that in JavaScript. I know there is function called .index() but how to do that in pure JS.
Here's one implementation: http://jsfiddle.net/x8hWj/2/
function swap(idx1, idx2) {
var container = document.getElementById('cont');
// ditch text nodes and the like
var children = Array.prototype.filter.call(
container.childNodes,
function(node) {
return node.nodeType === 1;
}
);
// get references to the relevant children
var el1 = children[idx1];
var el2 = children[idx2];
var el2next = children[idx2 + 1];
// put the second element before the first
container.insertBefore(el2, el1);
// now put the first element where the second used to be
if (el2next) container.insertBefore(el1, el2next);
else container.appendChild(el1);
}
This starts by getting a list of all element child nodes, then uses insertBefore to rearrange them.
So I have a mini slide menu in my website there is a menu you can choose what you want to read. There are points to click, when u clicked it the point get a red background.
But there is a problem.
When i click one point and then an other point the first clicked point have to lose his background.
Here is my HTML:
<div id="slide_button" onClick="clicked(this);"><dir class="button_1"></dir></div>
<div id="slide_button" onClick="clicked(this);"><dir class="button_2"></dir></div>
<div id="slide_button" onClick="clicked(this);"><dir class="button_3"></dir></div>
<div id="slide_button" onClick="clicked(this);"><dir class="button_4"></dir></div>
<div id="slide_button" onClick="clicked(this);"><dir class="button_5"></dir></div>
Here is my JS:
function clicked(slide_button) {
slide_button.getElementsByTagName("dir")[0].style.backgroundColor="red";
}
HERE IS AN EXAMPLE ON FIDDLE.
My "QUESTION IS" what i have to do to solve that?
What should I pay attention?
First you need to fix your HTML becaue your id values aren't unique. In fact, you don't even need id values, so you should use "slide_button" as a class. You can then use it to select all the buttons:
<div onClick="clicked(this);" class="slide_button"><dir></dir></div>
<div onClick="clicked(this);" class="slide_button"><dir></dir></div>
<div onClick="clicked(this);" class="slide_button"><dir></dir></div>
<div onClick="clicked(this);" class="slide_button"><dir></dir></div>
<div onClick="clicked(this);" class="slide_button"><dir></dir></div>
The CSS needs to be changed now so "slide_button" is a class selector, instead of an id selector:
.slide_button {
display: inline-block;
}
As for clearing the background, clear all of them before coloring the selected one red:
function clicked(slide_button) {
var buttons = document.getElementsByClassName('slide_button');
for(var i = 0; i < buttons.length; i++) {
buttons[i].getElementsByTagName('dir')[0].style.backgroundColor = '';
}
slide_button.getElementsByTagName('dir')[0].style.backgroundColor = 'red';
}
jsfiddle
This uses just JavaScript with no JQuery, but if you are using JQuery, you might as well use it here. The code is a lot shorter and easier to follow.
Here's a JQuery version:
$(function() {
$('.slide_button').click(function() {
var $button = $(this);
$button.children(':first').css({ backgroundColor: 'red' });
$button.siblings().children(':first').css({ backgroundColor: '' });
});
});
Note: This registers a click-handler, so you can get rid of the "onclick" attirbutes.
jsfiddle
You have to select all other points and set their background to none.
Or remeber which point is selected and on select another just remove background on last and remeber current point, then set its background to red.
See fiddle: http://fiddle.jshell.net/399Dm/5/
At first id should be unique per element.
<div class="slide_button"><dir class="button"></dir></div>
<div class="slide_button"><dir class="button"></dir></div>
<div class="slide_button"><dir class="button"></dir></div>
<div class="slide_button"><dir class="button"></dir></div>
<div class="slide_button"><dir class="button"></dir></div>
Second, you should store reference of clicked element if you want later remove background color, and instead of inline event handlers or binding all elements would be better if you use event delegation.
Demonstration
(function () {
"use strict";
// getting parent node of divs, due to bind click event. then
var ele = document.querySelector(".slide_button").parentNode,
prev = null; // store previous clicked element
ele.addEventListener("click", clickHandler); // event handler.
function clickHandler(e) {
var t = e.target; // get target of clicked element
// filter by target node name and class. edit: removed class checking
if (t.nodeName.toLowerCase() === "dir") {
// checking value of prev !== null and it's not same element.
if (prev && prev !== t) {
prev.style.backgroundColor = "";
}
prev = t; // store clicked element
t.style.backgroundColor = "red";
}
}
}());
I have fixed the fiddle so that it works hopefully as you plan.
http://jsfiddle.net/399Dm/8/ There you go!
var forEach = function(ctn, callback){
return Array.prototype.forEach.call(ctn, callback);
}
function clear(element, index, array) {
element.getElementsByTagName("dir")[0].style.backgroundColor="";
}
function clicked(slide_button) {
forEach(document.getElementsByClassName("slide_button"), clear);
//.style.backgroundColor="";
slide_button.getElementsByTagName("dir")[0].style.backgroundColor="red";
}
I had a slightly different method than #atlavis but a similar result.
http://fiddle.jshell.net/2AGJQ/
JSFIDDLE DEMO
jQuery
$('.slide_button').click(function(){
$('.slide_button dir').css("background-color", "inherit");
$(this).find('dir').css("background-color", "red");
});
HTML - Your markup is invalid because you have duplicate ids. Make them classes as below instead.
<div class="slide_button" >
<dir class="button_1"></dir>
</div>
<div class="slide_button">
<dir class="button_2"></dir>
</div>
<div class="slide_button">
<dir class="button_3"></dir>
</div>
<div class="slide_button">
<dir class="button_4"></dir>
</div>
<div class="slide_button">
<dir class="button_5"></dir>
</div>
CSS change
.slide_button {
display: inline-block;
}
If you can look at the following jsfiddle, I used jQuery to get what you want.
UPDATED WITH THE CORRECT FIDDLE LINK
I have the following example: http://jsfiddle.net/gespinha/kRUym/52/
Every time you click an element of the array it logs to the console its position in the array and the position of the next element. What I'm trying to do is that when I click on the last element I want it to identify that the next element is actually the first (looping the array).
But when when I click on the last element it doesn't set the arrayPos variable (the number of the position in the array: articles) to zero (the first position in the array, it just continues to number 6, even though I have stated in the if argument that if it is bigger than the length of the array it should become zero.
Why is this happening?
Any suggestions?
HTML
<div class="item">index 0</div>
<div class="item">index 1</div>
<div class="item">index 2</div>
<div class="item">index 3</div>
<div class="item">index 4</div>
<div class="item">index 5</div>
JQUERY
var articles = [];
$('.item').each(function(){
var obj = $(this);
articles.push(obj);
});
for (var i = 0; i < articles.length; i++) {
$(articles[i]).data("index", i)
}
$('.item').on("click", function() {
var id = $(this).data("index");
console.log('NOW: '+id);
if(id < articles.length){
id++
} else {
id = 0;
}
console.log('NEXT: '+id);
});
How can I make this work?
I believe it's a 1 off issue...try
if (id < articles.length - 1)
You can simply use the jQuery index():
$('.item').click(function(){
alert( $(this).index() );
});
This will alert the index starting from 0.
This requires the items to be in a seperate div, the index is the index relative to the parent.
LIVE DEMO
$(function(){
var articles = [];
$('article').each(function(){
articles.push( this );
});
$(articles).click(function(){
console.log( $(this).index() );
});
});
Note that this way you'll just collect the indexable articles (every children will always be index 0). You can push the JS this element into a collection of elements and than on click reference their original index value by wrapping the JS elements into a jQuery Object Elements collection $(articles).