My javascript is only working for the first class name - javascript

https://jsfiddle.net/joel081112/fctL5z2u/15/
I'm not sure how to fix it since I'm new to JavaScript but I've tried some for-each statements and got nowhere. Here is a fiddle with 3 elements with the class-name bodymovianim but only the first element is appearing. How can I alter this js to show it in each div?
let iconMenu = document.querySelector('.bodymovinanim');
let animationMenu = bodymovin.loadAnimation({
container: iconMenu,
renderer: 'svg',
loop: false,
autoplay: false,
path: "https://raw.githubusercontent.com/thesvbd/Lottie-examples/master/assets/animations/menu.json"
});
var directionMenu = 1;
iconMenu.addEventListener('click', (e) => {
animationMenu.setDirection(directionMenu);
animationMenu.play();
directionMenu = -directionMenu;
});

Related

Lottie animations and hovers: simpler way?

I am new to coding, and trying to learn as much as i can while working on real projects.
I have 8 divs, and each div has it's individual lottie animation (each animation has its .json file). I want to play the respective div's animation on hover.
so my html looks like this
var containerHorloge = document.getElementById("anim-horloge");
var containerBalance = document.getElementById("anim-balance");
var containerOrdi = document.getElementById("anim-ordi");
var containerFamille = document.getElementById("anim-famille");
var containerLunettes = document.getElementById("anim-lunettes");
var containerBonhomme = document.getElementById("anim-bonhomme");
var containerCoupes = document.getElementById("anim-coupes");
var containerPinpoint = document.getElementById("anim-pinpoint");
var animHorloge = bodymovin.loadAnimation({
container: containerHorloge,
renderer: 'svg',
autoplay: false,
loop: true,
path : '/wp-content/uploads/svg/anim-horloge.json'
});
var animBalance = bodymovin.loadAnimation({
container: containerBalance,
renderer: 'svg',
autoplay: false,
loop: true,
path : '/wp-content/uploads/svg/anim-balance.json'
});
var animation = bodymovin.loadAnimation({
container: containerOrdi,
renderer: 'svg',
autoplay: false,
loop: true,
path : '/wp-content/uploads/svg/anim-ordi.json'
});
var animation = bodymovin.loadAnimation({
container: containerFamille,
renderer: 'svg',
autoplay: false,
loop: true,
path : '/wp-content/uploads/svg/anim-famille.json'
});
var animation = bodymovin.loadAnimation({
container: containerLunettes,
renderer: 'svg',
autoplay: false,
loop: true,
path : '/wp-content/uploads/svg/anim-lunettes.json'
});
var animation = bodymovin.loadAnimation({
container: containerBonhomme,
renderer: 'svg',
autoplay: false,
loop: true,
path : '/wp-content/uploads/svg/anim-bonhomme.json'
});
var animation = bodymovin.loadAnimation({
container: containerCoupes,
renderer: 'svg',
autoplay: false,
loop: true,
path : '/wp-content/uploads/svg/anim-coupes.json'
});
var animation = bodymovin.loadAnimation({
container: containerPinpoint,
renderer: 'svg',
autoplay: false,
loop: true,
path : '/wp-content/uploads/svg/anim-pinpoint.json'
});
$(".section-cases .vc_col-sm-3.div-horloge").on('mouseenter', function(event) {
event.preventDefault();
onEnter:animHorloge.play();
})
<div class="vc_col-sm-3 div-horloge"></div>
<div class="vc_col-sm-3"></div>
<div class="vc_col-sm-3"></div>
<div class="vc_col-sm-3"></div>
<div class="vc_col-sm-3"></div>
<div class="vc_col-sm-3"></div>
<div class="vc_col-sm-3"></div>
<div class="vc_col-sm-3"></div>
(For the example, i just gave one div a specific class, but every div would have it's own specific class.. maybe. lol)
Now i know i could just call each animation on each div separately, but i'm trying to figure out if there's a cleaner / shorter way to do this? A loop? I thought of a forEach loop, but i don't even know how i would associate each animation with each div. Maybe arrays ?
Again, i am fairly new to coding, and know some basics, but not much of loop, arrays, etc..
Thanks a lot!
EDIT
So this is how i got it to work (thanks to #sam-osb's answer)
var lottiePlayer = document.getElementsByTagName("lottie-player");
$(lottiePlayer).on('mouseenter', function(event) {
console.log(this);
this.setDirection(1)
this.play()
}).on('mouseleave', function(event) {
this.setDirection(-1)
this.play()
});
<div class="box">
<lottie-player src="/wp-content/uploads/svg/SOURCE_HERE.json"></lottie-player>
<p>Lorem ipsum</p>
</div>
<div class="box">
<lottie-player src="/wp-content/uploads/svg/SOURCE_HERE.json"></lottie-player>
<p>Lorem ipsum</p>
</div>
The problem is that i want to hover on the PARENT (.box div...)
So i've tried:
$(lottiePlayer).closest(".box")on('mouseenter', function(event) {
$(this).find(lottiePlayer).play();
})
// or
$(lottiePlayer).closest(".box")on('mouseenter', function(event) {
this.find(lottiePlayer).play();
})
// or even
$(lottiePlayer).closest(".box")on('mouseenter', function(event) {
lottiePlayer.play();
})
// and then
$(".box")on('mouseenter', function(event) {
this.find(lottiePlayer).play();
})
And it always returns that .play() is not a function...
i know i'm doing something stupidly wrong, but don't know what LOL
You can use this library with the 'hover' attribute to play animations on hover, and let it load the animations for you so you could remove all the bodymovin calls:
https://github.com/LottieFiles/lottie-player
Just include the CDN in the head of your HTML file:
<script src="https://unpkg.com/#lottiefiles/lottie-player#latest/dist/lottie-player.js"></script>
then declare your element:
<lottie-player src="URL" hover></lottie-player>
So after getting very useful answers here and in other questions, the correct way to do this:
var lottiePlayer = document.getElementsByTagName("lottie-player");
$(".vc_col-sm-3").on('mouseover', function(event) {
$(this).find(lottiePlayer)[0].play();
});

Appending content of a variable to a div with appendTo()

Hi I'm working on a project where I have a multi-image slider.
Each image needs to have a legend.
I'm getting the alt tag from the image and storing it in a p tag with a legend of legend--text.
I've then created a function that plays when I change slides. This is where I'm having a problem.
I'm setting a variable that gets the active slide, and another one that gets the legend from the active slide - this works fine.
I then tried to use the appendTo() function to copy the content from the legend variable to a div tag with a class of .project__information.
I understand that this is not working because it's not a DOM element, but I've looked for solutions and can't really find any.
Here's my code:
// For each active slide get the alt attribute and store it in <p>
$('.is--legend').each(function() {
var $this = $(this);
$this.append('<p class="legend--text">' + $this.parent().find('img').attr('alt') + '</p>');
});
// Set splide slider
var elms = document.getElementsByClassName('splide');
for (var i = 0, len = elms.length; i < len; i++) {
var splide = new Splide(elms[i], {
type: 'loop',
drag: 'free',
focus: 'center',
perPage: 3,
autoWidth: 'true',
breakpoints: {
767: {
perPage: 1,
}
}
}).mount();
}
function slideChange() {
// Gets active slide
var activeSlide = $(".splide__slide.is-active:not(.splide__slide--clone)");
console.log('Passing through the', activeSlide);
// Gets the legend
var myLegend = activeSlide.find('.legend--text').text();
console.log('Getting the new', myLegend);
myLegend.appendTo('.project__information');
}
splide.on("move", function() {
slideChange();
});
slideChange();
If anyone has an idea as to how I could achieve this, some related documentation about how to proceed, please let me know

Javascript: change functions parameters on click

I have a simple code that is using the library Lottie for SVG animations.
There are 2 animations. I need to make one first on load and the second start when user click on the button. At the same time when the second animation starts second animation replace the first.
So in my expectations I will need to change the parameter of JS function.
Is there any option how can I change path parameter in lottie function and start the second animation than replace the first animation with the second?
HTML:
<div id="element">
<button onclick="myFunction()">Click me</button>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.7.3/lottie.min.js" integrity="sha512-35O/v2b9y+gtxy3HK+G3Ah60g1hGfrxv67nL6CJ/T56easDKE2TAukzxW+/WOLqyGE7cBg0FR2KhiTJYs+FKrw==" crossorigin="anonymous"></script>
JS:
var element = document.getElementById("element");
var animPath = 'anim/data-1.json'
lottie.loadAnimation({
container: element, // the dom element that will contain the animation
renderer: 'svg',
loop: false,
autoplay: true,
path: animPath // the path to the animation json
});
function myFunction() {
var animPath = 'anim/data-2.json'
}
Put your animation code in a function and call it with a default path when the page load. Create a click event and call it with a different path.
function runAnimation(animPath) {
lottie.loadAnimation({
container: element, // the dom element that will contain the animation
renderer: 'svg',
loop: false,
autoplay: true,
path: animPath // the path to the animation json
});
}
runAnimation("anim/data-1.json");
let element = documment.querySelector("clicked element selector");
element.addEventListener("click", () => {
runAnimation("anim/data-2.json");
})

How to wait 1 second to move another slider after click using swiperjs api?

I am having difficulty to figure out how to wait or delay slider about 1 second before move to another slider. The below is JavaScript. I am not sharing the html code because its too lengthy and my question will look messy. I hope some of you have idea. I really appreciate your help.
Js code
var swiper = new Swiper('.swiper-container', {
autoHeight: true, //enable auto height
mousewheelControl: false,
touchRatio: 0,
allowTouchMove: false,
shortSwipes: false,
speed:2000,
navigation: {
nextEl: '.swiper-button-next',
},
});
I am having difficulty to figure out how to wait or delay [...] about 1 second
If you wish to delay script execution, you need setTimeout.
Anatomy of setTimeout:
setTimeout( [CALLBACK FUNCTION], [TIME DELAY] );
Working Example:
const myButton = document.getElementsByTagName('button')[0];
const clickButton = () => {
setTimeout(() => {
let myParagraph = document.createElement('p');
myParagraph.textContent = 'You clicked the button.';
document.body.appendChild(myParagraph);
}, 1000);
}
myButton.addEventListener('click', clickButton, false);
<button type="button">Click Me</button>
<p>A second after you click the button above, more text will appear...</p>

How to dynamically create multiple jQuery sliders?

I am working on a WordPress site that turns a custom post type into a slider on a page. I am using Sequence.js for my slider and I can manually create multiple sliders no problem with the following:
//sequence slider options to be used by slider1
var options0 = {
sartingFrameID: 1,
cycle: true,
autoPlay: false,
nextButton: '.next0',
prevButton: '.prev0',
fallback: {
theme: "fade",
speed: 100
}
}
//slider1
var sequence0 = $(".slideContainer0").sequence(options0).data("sequence");
//sequence slider options to be used by slider2
var options1 = {
sartingFrameID: 1,
cycle: true,
autoPlay: false,
nextButton: '.next1',
prevButton: '.prev1',
fallback: {
theme: "fade",
speed: 100
}
}
//slider2
var sequence1 = $(".slideContainer1").sequence(options1).data("sequence");
How can I streamline this? And also make it dynamic so a slider is created for each post that is made? Any help would be greatly appreciated.
edited - added working answer
I used the answer from Cymen below for the first part by turning the options output into a function and simply calling the function with a counter for each sequence instance. Then used the second part of his answer to initialize each sequence slider and it works a treat.
This is what I have working now:
function options(number) {
return {
startingFrameID: 1,
cycle: true,
autoPlay: false,
nextButton: '.next' + number,
prevButton: '.prev' + number,
fallback: {
theme: "fade",
speed: 100
}
};
}
var count = 0;
$('.slideContainer').each(function() {
var sequence = $(this);
sequence.sequence(options(count)).data('sequence');
count++;
});
I haven't used sequence but from your post I am guessing you want to be able to recreate the options object with an increment of the number. So you could do something like this:
function options(number) {
return {
startingFrameID: 1,
cycle: true,
autoPlay: false,
nextButton: '.next' + number,
prevButton: '.prev' + number,
fallback: {
theme: "fade",
speed: 100
}
};
}
Then use it like so:
$(target).sequence(options(0)).data("sequence");
Or in your specific example:
//slider1
var sequence0 = $(".slideContainer0").sequence(options(0)).data("sequence");
//slider2
var sequence1 = $(".slideContainer1").sequence(options(1)).data("sequence")
And to do what you are talking about how about giving all the sequences the same class like say custom-sequence and then do something like this:
var count = 0;
$('.custom-sequence').each(function() {
var sequence = $(this);
sequence.sequence(options(count)).data('sequence');
count++;
});
That may or may not work -- it isn't quite clear to me what the .data('sequence') is doing.

Categories

Resources