I am using AOS to show html elements on scroll. It works well alone, but when I use it on the pages that contains Slick slider, the elements on which is AOS applied are not showing. Elements are hidden and if there is a lot scroll, it looks like the browser gives wrong information to AOS about current scrolling position and some elements are shown latter.
There is no specific code that makes this problems, any usage of slick on the same page with AOS makes AOS not working.
Did anyone solved this problem, I saw some pending questions on other websites and didn't find any solution?
You have to initiate Aos after the slider is initiate.
I think you have to take in account all the previous sliders.
// On init event
$('#productsCarousel').on('init', function(event, slick){
console.log('#productsCarousel init');
AOS.init({
easing: 'ease-out-back',
duration: 1000
});
});
$('#productsCarousel').slick({
centerMode: true,
centerPadding: '8%',
prevArrow: '<span class="slick-prev slick-btn"><span class="p-3"><span class="icon-prev"></span></span></span>',
nextArrow: '<span class="slick-next slick-btn"><span class="p-3"><span class="icon-next"></span></span></span>',
slidesToShow: 4,
responsive: [
{
breakpoint: 768,
settings: {
arrows: false,
centerMode: true,
centerPadding: '40px',
slidesToShow: 3
}
},
{
breakpoint: 480,
settings: {
arrows: false,
centerMode: true,
centerPadding: '40px',
slidesToShow: 1
}
}
]
});
In my case, I put AOS refresh after slick initializations
$(window).on('load', function() {
AOS.init({
duration: 600,
once: true
});
$('.section-product-container').slick({
dots: true,
infinite: true,
slidesToShow: 3,
slidesToScroll: 3,
});
$('.slide-container').slick({
dots: true,
infinite: true,
slidesToShow: 1,
slidesToScroll: 1,
arrows: true,
speed: 300,
autoplay: true,
fade: true,
cssEase: 'linear',
customPaging : function(slider, i) {
var number = (i+1);
if ((i+1) < 10)
number = '0'+(i+1);
return '<a>'+ number +'</a>';
}
});
$('.section-customer-container').slick({
dots: true,
infinite: true,
slidesToShow: 5,
slidesToScroll: 5,
customPaging : function(slider, i) {
if ((i+1) < 10)
return '<a>0'+(i+1)+'</a>';
return '<a>'+ i +'</a>';
}
});
AOS.refresh();
});
$(document).ready(function () {
$('#hero-slider').on('init', function (e, slick) {
var$firstAnimatingElements = $('div.hero-slide:first-child').find('[data-animation]');
doAnimations($firstAnimatingElements);
});
$('#hero-slider').on('beforeChange', function (e, slick, currentSlide, nextSlide) {
var$animatingElements = $('div.hero-slide[data-slick-index="' + nextSlide + '"]').find('[data-animation]');
doAnimations($animatingElements);
});
$('#hero-slider').slick({
// autoplay: true,
// autoplaySpeed: 10000,
dots: true,
fade: true
});
functiondoAnimations(elements) {
varanimationEndEvents = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend';
elements.each(function () {
var$this = $(this);
var$animationDelay = $this.data('delay');
var$animationType = 'animated ' + $this.data('animation');
$this.css({
'animation-delay': $animationDelay,
'-webkit-animation-delay': $animationDelay
});
$this.addClass($animationType).one(animationEndEvents, function () {
$this.removeClass($animationType);
});
});
}
});
I finally found solution for this problem.
I managed to make animation work on first slide, but it didn't work on other slides, so I used slick events beforeChange and afterChange. In the first I removed, and in second I added the "aos-animate" class. I tried with AOS.refresh() and AOS.refreshHard() but it didn't help
This is my solution
$('#homeslider')
.on('beforeChange', function() {
$('.slider_title').removeClass("aos-animate");
$('.slider_subtitle').removeClass("aos-animate");
$('.small_cta').removeClass("aos-animate");
$('.big_cta').removeClass("aos-animate");
// AOS.refreshHard(); this didn't work
})
.on('afterChange', function(event, slick, currentSlide) {
$('.slider_title').addClass("aos-animate");
$('.slider_subtitle').addClass("aos-animate");
$('.small_cta').addClass("aos-animate");
$('.big_cta').addClass("aos-animate");
// AOS.refreshHard(); this didn't work
});
These classes are a part of each slide and each of them has class like this
<div class="slider_title" data-aos="zoom-in" data-aos-delay="300"></div>
And one more thing, I added AOS.init(); after slick initialization
Related
I'm trying to test a gallery for the first time with Cypress but I'm having trouble trying to get the mouse events to work:
cy.get("img#front").should("be.visible");
cy.get("img#front")
.trigger("mousedown", { which: 1, pageX: 600, pageY: 100 })
.trigger("mousemove", { which: 1, pageX: -600, pageY: 100 })
.trigger("mouseup");
});
The image is visible on the page but when I do mouse down and mouse move on it nothing is happening. What I'm trying to do is press the mouse down and drag it left so the image changes to the next one in the gallery.
Using XY coordinates,
This is a simple example with the Cypress custom command, which I tried and it works for me,
* This reusable method is used to handle React drag and drop within cypress test.
*/
Cypress.Commands.add("dragAndDrop", (subject, target, dragIndex, dropIndex) => {
cy.get(subject).should("be.visible", { timeout: 2000 });
Cypress.log({
name: "DRAGNDROP",
message: `Dragging element ${subject} to ${target}`,
consoleProps: () => {
return {
subject: subject,
target: target
};
}
});
const BUTTON_INDEX = 0;
const SLOPPY_CLICK_THRESHOLD = 10;
cy.get(target).eq(dropIndex).then($target => {
let coordsDrop = $target[0].getBoundingClientRect();
cy.get(subject).eq(dragIndex).then(subject => {
const coordsDrag = subject[0].getBoundingClientRect();
cy.wrap(subject)
.trigger("mousedown", {
button: BUTTON_INDEX,
force: true
})
.trigger("mousemove", {
button: BUTTON_INDEX,
clientX: coordsDrag.x,
clientY: coordsDrag.y,
force: true
})
.wait(1000);
cy.get('body')
.trigger("mousemove", {
button: BUTTON_INDEX,
clientX: coordsDrop.x + SLOPPY_CLICK_THRESHOLD,
clientY: coordsDrop.y,
force: true
});
cy.get('body')
.trigger("mousemove", {
button: BUTTON_INDEX,
clientX: coordsDrop.x,
clientY: coordsDrop.y + SLOPPY_CLICK_THRESHOLD,
force: true
})
.wait(1000);
cy.get(target)
.trigger("mouseup");
});
});
});
in your cypress spec
cy.dragAndDrop(dragloc, droploc, 0, 0);
You can also try with a few changes
extracted from https://github.com/cypress-io/cypress/issues/3942
Click and drag within an image or canvas element has been the bane of my work-existence for a while. To be honest, I stumbled onto this post explicitly because I'm looking for something that will work in my current situation.
Do not be deterred, friend. I have a few examples that have worked for me in the past, hopefully this helps:
cy.get(".canvas-wrap > canvas")
.trigger("mousedown", 715, 155, {
button: 0,
force: true,
eventConstructor: "MouseEvent"
})
.trigger("mousemove", 100, 100, {
button: 0,
force: true,
eventConstructor: "MouseEvent"
})
.trigger("mouseup", 100, 100, {
button: 0,
force: true,
eventConstructor: "MouseEvent"
});
or
cy.get(".canvas-wrap")
.trigger("mousedown", 200, 200, { button: 0 })
.trigger("mousemove", { clientX: -250, clientY: -200 })
.trigger("mouseup", { force: true });
Anyway, I'd recommend experimenting with passing in button or event options, or just trying force: true and seeing if that gets you anywhere.
All the best
I wanted to create a Tippy with a button in it:
let tippyActions = function() {
var tippys = document.querySelectorAll('*[id^="tippy"]');
tippys.forEach(tpy => tippy(tpy, {content: tippyContent(tpy),
placement: "left",
trigger: 'click',
allowHTML: true,
hideOnClick: false,
interactive: true,
//zIndex: 99999,}))
}
let tippyContent = function ( tpy) {
let buttonsDiv = document.createElement("div")
let btn1 = document.createElement("a")
btn1.href = `/go/${tpy.url}`
buttonsDiv.appendChild(btn1);
return buttonsDiv.innerHTML;
}
But as soon as I set the interactive flag to true the tippys body disappears:
After reading a bit I first thought I have a zIndex problem, but that apparently was not it.
Turns out that I missed to read a part of the FAQ section in the documentary, where it states that adding appendTo: document.body can solve the problem, which it did in my case:
let tippyActions = function() {
var tippys = document.querySelectorAll('*[id^="tippy"]');
tippys.forEach(tpy => tippy(tpy, {content: tippyContent(tpy),
placement: "left",
trigger: 'click',
allowHTML: true,
hideOnClick: false,
appendTo: document.body, // <---
interactive: true}))
}
This is my actual slick gallery, I added an 'click' event listener on the "?" button... but when the gallery hits the breakpoint, slick will remove all the event listeners... how can i prevent that?
$('.qmark-btn').click(function(e) {
e.preventDefault();
// var img = $(this);
alert('test');
});
$('.img-gallery').slick({
slidesToShow: 6,
slidesToScroll: 3,
arrows: false,
rows: 3,
infinite: false,
responsive: [
{
breakpoint: 1200,
settings: {
slidesToShow: 5,
slidesToScroll: 3,
}
},
{
breakpoint: 992,
settings: {
slidesToShow: 4,
slidesToScroll: 3,
}
},
{
breakpoint: 768,
settings: {
slidesToShow: 3,
slidesToScroll: 3,
}
},
{
breakpoint: 600,
settings: {
slidesToShow: 2,
slidesToScroll: 1,
}
}
]
});
I experienced the same problem and fixed it with a small tweak to the cleanUpRows function within slick.js.
Slick.prototype.cleanUpRows = function() {
var _ = this, originalSlides;
if(_.options.rows > 1) {
originalSlides = _.$slides.children().children().clone(true);
originalSlides.removeAttr('style');
_.$slider.empty().append(originalSlides);
}
};
Simply add ".clone(true)".
This copies eventlisteners to originalSlides.
This fixed my issues with Slick when a responsive break was hit.
The problem with cloning is that it only keeps jquery related handlers and will not preserve things like vanilla js events and references to the old node that may exist in your code. To keep all of this, we want to avoid cloning the elements AND avoid using the empty() jquery function which removes all jquery handler, so one solution would be to replace this function by emptying the content with a simple use of innerHTML:
Slick.prototype.cleanUpRows = function() {
var _ = this, originalSlides;
if(_.options.rows > 1) {
originalSlides = _.$slides.children().children().clone(true);
originalSlides.removeAttr('style');
_.$slider.get(0).innerHTML = '';
_.$slider.append(originalSlides);
}
};
or use a documentFragment:
Slick.prototype.cleanUpRows = function() {
var _ = this, originalSlides;
if(_.options.rows > 0) {
originalSlides = _.$slides.children().children()
originalSlides.removeAttr('style');
var fragment = document.createDocumentFragment();
_.$slides.children().each(function(i, element) {
while(element.firstChild) {
fragment.appendChild(element.firstChild);
}
element.parentNode.replaceChild(fragment, element);
})
}
};
I use fullCalendar 2.6 and I only want one allday event per day.
I use this :
eventOverlap: false
It works if I put an event and move it on a day which has already an event : they won't overlap.
But if I click on a day which has already an event, it overlaps and I get 2 events (or more) at the same date...
I use this too on my select function :
overlap: false
which does not do the trick..
What can I do ? any idea ?
And another issue is when I use ajax to send start/end dates, it only works when I click to add an event but not when I move it using arrows when I put my cursor on the edge of the event to change its size...
My code :
function renderCalendar() {
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay',
},
defaultDate: dateNow,
defaultView: 'month',
lang: 'fr',
height: 'auto',
editable: true,
allDaySlot: true,
weekNumbers: false,
timeFormat: 'H:mm',
slotEventOverlap: false,
weekends: true,
selectable: true,
selectHelper: true,
eventOverlap: false,
select: function(start, end) {
var title = 'Occupé';
var eventData;
if (title) {
eventData = {
title: title,
start: start,
end: end,
allDay: true,
overlap: false,
color: '#bf0000',
textColor: '#ffffff',
};
$('#calendar').fullCalendar('renderEvent', eventData, true);
}
$('#calendar').fullCalendar('unselect');
alert(start);
alert(end);
}
});
Thanks for your help !
well.. selectOverlap set to "false" is the solution :)
for the second problem, the solution must be eventResizeStop but I didn't find it yet
Try this.
select: function(start, end) {
var title = 'Occupé';
var eventData;
var sameDayEvents = $('#calendar').fullCalendar( 'clientEvents' ,function(event) {
if (event.start.format('YYYY-mm-dd') == start.format('YYYY-mm-dd')) {
return true;
} else {
return false;
}
});
if (!sameDayEvents.length && title) {
eventData = {
title: title,
start: start,
end: end,
allDay: true,
overlap: false,
color: '#bf0000',
textColor: '#ffffff',
};
$('#calendar').fullCalendar('renderEvent', eventData, true);
}
$('#calendar').fullCalendar('unselect');
alert(start);
alert(end);
}
I have a jqplot line graph with this line:
`var line = [[1,0.493],
[1,1.286],
[2,0.305],
[2,0.516],
[2,0.551],
[2,0.595],
[2,0.609],
[2,0.644],
[2,0.65],
[2,1.249],
[2,1.265],
[4,0.443],
[5,0.288],
[5,0.477],
[5,0.559],
[5,0.562],
[6,0.543],
[7,0.513],
[7,0.549],
[8,0.442],
[8,0.467],
[8,0.468],
[8,0.597],
[8,0.857]];`
Im using tooltipContentEditor to display the x and y values of the point on hover. I need the values displayed to be exact.
Here is the code Im using: http://jsfiddle.net/ZQh38/1/
The problem:
Sometimes, the x and y values displayed are incorrect. For example, the last points at (6, 0.5) and (7, 0.5)
The values are only displayed with 1 decimal, which needs to be 3.
So, the question is, how do I get the exact y values?
Ive also tried to use the pointIndex, which does NOT match with the values in the line.
Thanks for your help!
Here is the solution to your problem: jsFiddle example
I made changes to your highlighter option.
/*
Drawing graphs
*/
var Statistics = {
scatter: false,
trendline: false,
enableLabels: true,
showAverage: false,
colour: null,
//Graph properties
scatterPlot: function(on){
Statistics.scatter = on;
},
showTrendline: function(on){
$.jqplot.config.enablePlugins = on;
Statistics.trendline = on;
},
disableLabels: function(yes){
Statistics.enableLabels = (!yes);
},
shouldDrawScatter: function(){
return (!Statistics.scatter);
},
useLabels: function(){
return Statistics.enableLabels;
},
getTrendline: function(){
return Statistics.trendline;
},
//Drawing
drawLabels: function(){
document.getElementById('ylabel').innerHTML = Statistics.ylabel;
document.getElementById('xlabel').innerHTML = Statistics.xlabel;
},
generateGraph: function(){
var line = [[1,0.493],
[1,1.286],
[2,0.305],
[2,0.516],
[2,0.551],
[2,0.595],
[2,0.609],
[2,0.644],
[2,0.65],
[2,1.249],
[2,1.265],
[4,0.443],
[5,0.288],
[5,0.477],
[5,0.559],
[5,0.562],
[6,0.543],
[7,0.513],
[7,0.549],
[8,0.442],
[8,0.467],
[8,0.468],
[8,0.597],
[8,0.857]];
var plot = $.jqplot('chart', [line], {
animate: true,
grid:{backgroundColor: 'white'},
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: [1, 2, 3, 4, 5, 6, 7],
tickOptions: {
fontFamily: '"Helvetica", cursive',
fontSize: '12pt'
}
},
yaxis: {
tickOptions: {
fontFamily: '"Helvetica", cursive',
fontSize: '12pt'
},
max: 2,
min: 0
}
},
series:[{
color: "#594A42",
lineWidth: 2.5,
shadow: false,
fillColor: "#594A42",
markerOptions: {
style:'filledCircle',
color: "#594A42",
shadow: false,
size: 10
},
showLine: false,
trendline: {
color: '#999'
},
rendererOptions:{
animation: {
speed: 2000 //Speeding up animation
}
}
}],
highlighter: {
show: true,
fadeTooltip: true,
sizeAdjust: 6,
tooltipContentEditor: function(str, pointIndex, index, plot){
var splitted = plot._plotData[1][index];
var x = splitted[0];
var y = splitted[1];
return x + ", " + y;
}
}
});
},
//Checks if the graph will be a straight line
straightLine: function(lineArray){
if(typeof lineArray != 'undefined' && lineArray.length > 0) {
for(var i = 1; i < lineArray.length; i++)
{
if(lineArray[i] !== lineArray[0])
return false;
}
}
return true;
},
};
Statistics.generateGraph();