Javascript loop over getElementsByClassName - javascript

I try to iterate using getElementsByClassName, but the effect i try to achieve affect all the items at once.
How can I make it work 1 item per swipe?
HTML:
<div id="recog" class="cr-wrap">
<div id="slide">
<div class="card item"><img src="mc.svg"></div>
<div class="card item"><img src="paypal.svg"></div>
<div class="card item"><img src="visa.svg"></div>
</div>
</div>
js:
var wrap = document.getElementById('recog');
var swiper = new Hammer(wrap);
swiper.on('swipeleft', function(){
var items = document.getElementsByClassName('item');
for ( var i=0; i < items.length ; i++ ){
items[i].classList.add('gone');
}
});

Maybe this would be better, using querySelectorAll, where you can narrow the hit list even more.
var wrap = document.getElementById('recog');
var swiper = new Hammer(wrap);
swiper.on('swipeleft', function(){
var items = wrap.querySelectorAll('.item');
for ( var i=0; i < items.length ; i++ ){
items[i].classList.add('gone');
}
});
To be noted: By using wrap.querySelectorAll('.item');, it target only item's inside the recog element
Update
If you want only 1 item per swipe, do like this
var wrap = document.getElementById('recog');
var swiper = new Hammer(wrap);
swiper.on('swipeleft', function(){
var item = wrap.querySelector('.item');
item.classList.add('gone');
});
Update 2
If you want only the swiped item, you should be able to do like this but it depends on how hammer pass the target forward.
var wrap = document.getElementById('recog');
var swiper = new Hammer(wrap);
swiper.on('swipeleft', function(e){
e.target.classList.add('gone');
});
If this won't work, you likely need to add a swiper on each item.

Related

In pure JS, I am trying to set two similar classes but with different numbers or to set the same class to two different elemnts

I tried to set the same class imagens-giratorias to two elements or to set imagens-giratorias and imagens-giratorias-2. The class worked in first element, and the same class stopped of animating in the second element.
[I provide the JSFiddle at the end.]
Check the #rafaelcastrocouto's original code at https://stackoverflow.com/a/59524483/8041366. If you prefer reading the complete code here, here is the code taken from there, but with a bit modified:
var counter = 1;
var div = document.querySelector('.imagens-giratorias');
var imagens = document.querySelectorAll('.imagens-giratorias img');
var showNext = function () {
counter++;
if (counter > 3) counter = 1;
div.classList.remove('imagem1', 'imagem2', 'imagem3')
div.classList.add('imagem'+counter);
};
for (var img of imagens) {
img.addEventListener('animationend', showNext);
}
And small CSS snippet:
<div class="section-2">
<div class="item-2">
<div class="imagens-giratorias imagem1">
</div>
</div>
</div>
<div class="section-3">
<div class="item-2">
<div class="imagens-giratorias imagem1">
</div>
</div>
Or
<div class="section-3">
<div class="item-2">
<div class="imagens-giratorias-2 imagem1">
</div>
</div>
1st solution, that same original code above I am referring.
2nd solution:
var div = document.querySelector('.imagens-giratorias, .imagens-giratorias-2');
var imagens = document.querySelectorAll('.imagens-giratorias img, .imagens-giratorias-2 img');
3rd solution
var div = document.querySelector('[class^=imagens-giratorias]');
var imagens = document.querySelectorAll('[class^=imagens-giratorias] img');
4th solution
const contador = 1;
const div = document.querySelector('.imagens-giratorias');
const imagens = document.querySelectorAll('.imagens-giratorias img');
I also tried to use from multiple selectors with document.querySelectorAll. No luck.
But all these solutions did not work.
JSFiddle
Please pay attention to two elements. While one element will always animate, another will stop of animating.
https://jsfiddle.net/gusbemacbe/mbp84u6r/2/
If I understand you correctly you're trying to grab elements that have a class name starting with imagens-giratorias. If that's the case, use the ^ attribute selector as shown below:
document.querySelectorAll("[class^="imagens-giratorias"]")
Update:
Based on your update it appears that only one of your two divs' images is animating but in reality they're stacked on top of each of other. Feel free to use whatever layout method you want but for demonstration's sake I floated one left and the other right. Other that it was a matter of looping through your divs and assigning your function to their child images as so:
var divs = document.querySelectorAll('.imagens-giratórias');
var contador = 1;
var mostrarPróximo = function(div) {
contador++;
if (contador > 3) contador = 1;
div.classList.remove('imagem1', 'imagem2', 'imagem3')
div.classList.add('imagem' + contador);
};
Array.from(divs).forEach(function(div, index) {
var images = div.querySelectorAll('img');
Array.from(images).forEach(function(img) {
img.addEventListener('animationend', mostrarPróximo.bind(null, div));
});
});
https://jsfiddle.net/1r6yjf5s/

How access second div with same id using querySelectorAll javascript?

Here, I have two div on my webpage both div have almost same data.
accept type attribute.
My first div attribute have type="timeline".
and Second div attribute type ="slideshow".
When my page load it only detects the first div.
But I have a condition if my div type equal to slideshow then my code run but it detects only first div.
Here is my code.
<div type='timeline' id='slide'>
<section>
<header>Title One</header>
<article>Content</article>
</section>
<section>
<header>Title Two</header>
<article>Content</article>
</section>
<section>
<header>Title Three</header>
<article>Content</article>
</section>
<section>
<header>Title Four</header>
<article>Content</article>
</section>
</div>
var divSlide = document.querySelectorAll('#slide');
var myNodeList = divSlide.length;
for(i = 0; i < myNodeList.length; i++) {
var divMain = document.getElementById("slide");
console.log(divMain);
var align = divMain.getAttribute("type");
console.log(align);
console.log(myNodeList)
if(align=='slideshow'){
console.log("my working code");
}
}
What should i do.
Help will be appreciated.
You have a few of mistakes in your code that we need to fix first.
First, you shouldn't use the same id value more than once in your code so you need to replace the id with a class (even though our code can still work with id here).
Second mistake - in your for loop you are using the wrong variable "myNodeList.length", myNodeList variable already is the length so it does not have a length property. you should instead use the divSlide variable like this:
for(i = 0; i < divSlide.length; i++)
Third mistake- in order to access the current item that is being looped over you should use the variable that holds the list (which is divSlide here)and then add to it i in brackets to indicate the current index in use, like this
var divMain = divSlide[i];
// instead of this: var divMain = document.getElementById("slide");
Fourth - you should in most cases use triple = signs to check for values. so instead of == you should use ===
this is how the code will look like finally:
var divSlide = document.querySelectorAll('#slide');
var myNodeList = divSlide.length;
document.addEventListener("DOMContentLoaded", functionName)
function functionName(){
for(i = 0; i < divSlide.length; i++) {
var divMain = divSlide[i];
var align = divMain.getAttribute("type");
if(align ==='slideshow'){
console.log("my working code");
}
}
}
and this is codepen example
You can get div by type attribute like this:
HTML
<div type='timeline' id='slide'>
this is timeline
</div>
<div type='slideshow' id='slide'>
this is slideshow
</div>
JS
$('#slide[type=slideshow]') // get div that has id='slide' and type='slideshow'
Online Demo (jsFiddle)

Close a div and start a new one

I have a list of items that I want to be inside multiple columns. These columns can be arbitrary based on a series of factors so there's some other stuff going on. Unfortunately I'm getting tricked up on how to close the containing div.
Let's say I have a structure like this:
<div class="col-md-4 JS-columnGrid">
<li>one</li>
<li>two</li>
<li>three</li>
<!--</div>-->
<!--<div class="col-md-4">-->
<li>four</li>
</div>
I want to close the col-md-4 div after the third list element, and wrap the fourth list element in another div class="col-md-4">
This would create two columns.
Here's some javascript that would grab each list, throw it into an array and then my intention is that I can use that array to decide where I'm going to cut the column.
var cutoffArray = [];
$(".JS-columnGrid > li").each(function(){
cutoffArray.push(this);
console.log(cutoffArray);
});
$(cutoffArray[3]).before("</div><div class='col-md-3'>");
Unfortunately this is the output HTML after this:
<div class="col-md-4 JS-columnGrid">
<li>one</li>
<li>two</li>
<li>three</li>
<div class="col-md-3"></div>
<li>four</li>
</div>
Where am I going wrong?
// select and remove all the elements you want to re-package
var $lis = $(".col-md-4.JS-columnGrid li").remove(),
i,
divs = [];
$(".outer-container").empty();
// slice into packs of three and append each pack to container
for (i = 0; i < $lis.length; i += 3) {
$("<div class='col-md-3'></div>")
.append( $lis.slice(i, i + 3) )
.appendTo(".outer-container");
}
You can try this:
$(function(){
var cutoffArray = [],
$col = $('<div class="col-md-3"></div>');
$(".JS-columnGrid > li").each(function(){
cutoffArray.push(this);
});
$('.JS-columnGrid').after($col);
$(cutoffArray[3]).appendTo($col);
});
Working fiddle
Updated answer:
if you want to add more li's change the above to this:
var $col = $('<div class="col-md-3"></div>');
$('.JS-columnGrid').after($col);
$(".JS-columnGrid > li").each(function(index){
if(index > 2) {
$col.append($(this));
}
});
updated fiddle
despite the fact that you have <li> elements in the "wrong" place, browsers wont just ignore them and you can still manipulate them
var div = document.querySelector('.col-md-4.JS-columnGrid');
var lis = div.querySelectorAll('li');
var newDiv = document.createElement('div');
newDiv.className = 'col-md-3';
for (var i = 3; i < lis.length; i++) {
newDiv.appendChild(lis[i]);
}
div.parentElement.insertBefore(newDiv, div.nextElementSibling);
That will do what you want
You can't use "</div><div>" in .before() etc, since the argument is expected to be one or more properly formatted HTML elements (or plain text). You're working on the DOM here, not plain text, and the textual HTML representation of the argument is purely convenience.
You could instead simply move the elements:
var els = $('.JS-columnGrid > li');
var x = $( "<div class='col-md-4 JS-columnGrid'></div>" );
els.parent().after( x );
for (var i = 0; i < els.length; i ++ )
if ( i >= 3 )
x.append( els[i] );

Jquery previous object selector

I have an issue about prev object on jquery it doesnt give me position ...
I have divs with ".post-image"
$(".post-image").each(function(){
var div = $(this);
var index = div.index();
var odd = index % 2;
if(odd == 1){
var sibling = div.next();
sibling.css({
margin:"15px",
marginTop:"-165px"
})
var bElement= div.prev(".post-image");
console.log(bElement)
})
HTML:
<div class="post">
<div class="post-header"></div>
<div class="post-content"></div>
</div>
<div class="post-image">
<div class="post-header"></div>
<div class="post-content"></div>
</div>
I cant select prev as an object
As for the jQuery docs:
.prev( [selector ] ) Get the immediately preceding sibling of each element in the set of matched elements, optionally filtered by a selector.
Reference
Your <div class="post-image"> element has no immediately preceding element with the same class. The element preceding it is <div class="post">
[EDIT]
You can go this way:
// declare bElement variable:
var bElement;
$(".post-image").each(function(){
var div = $(this);
var index = div.index();
var odd = index % 2;
if(odd == 1){
var sibling = div.next();
sibling.css({
margin:"15px",
marginTop:"-165px"
});
// make sure that previous element with class '.post-image' exists :
if(bElement !== undefined){
var prevElemPosition = bElement.position().top;
// do something ...
}
}
// set latest .post-image element (so that it will be the previous on next iteration):
bElement = div;
});

Change DIV order with jquery

I'm working on a client's HTML based site and need to randomly order a set of Divs on refresh of a page. I would normally handle this through PHP and a database call, but it's a static site.
So, I'm wondering if anyone knows how to randomly display a set of div's using jquery?
Here's an example:
<div class="myItems">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
and on refresh, it might change to:
<div class="myItems">
<div class="item">2</div>
<div class="item">3</div>
<div class="item">1</div>
</div>
Anyone know how to do that?
This willl do it
function reorder() {
var grp = $(".myItems").children();
var cnt = grp.length;
var temp,x;
for (var i = 0; i < cnt; i++) {
temp = grp[i];
x = Math.floor(Math.random() * cnt);
grp[i] = grp[x];
grp[x] = temp;
}
$(grp).remove();
$(".myItems").append($(grp));
}
Actually it's pretty simple:
$(".myItems").html($(".myItems .item").sort(function(){
return Math.random()-0.5;
}));
That's it!
Enjoy.
Another simple way is ...
1. create an array
2. generate a random number and check if it is Odd or Even
3. If odd, add your div to the top (shift method). If even, add your div to the bottom (push method).
4. So this way you will have your divs arranged randomly in the array.
5. Now simple join the array and append it to your Page.
var divArray = [];
for(var i=0; i<divs.length; i++){
//generate random number
if(rand_num == odd)
divArray.push( div[i] );
else
divArray.shift( div[i] );
}
$(myElem).html( divArray.join("") );

Categories

Resources