How to prevent owlcarousel from destroying custom dots? - javascript

I am making a simple carousel using OwlCarousel 2.2.1 and I have run into a problem with custom dots. I have my custom list of categories which I wanted to behave like dots in carousel.
<ul class="category-list">
<li class="category-list__item active" data="1">
<span class="icon icon--red category-list__bg-icon"><svg>svg stuff here</svg></span>
<span class="icon icon--white category-list__main-icon"><svg>svg stuff here</svg></span>
<span class="category-list__title">Category 1</span>
</li>
...
<li class="category-list__item active" data="5">
<span class="icon icon--red category-list__bg-icon"><svg>svg stuff here</svg></span>
<span class="icon icon--white category-list__main-icon"><svg>svg stuff here</svg></span>
<span class="category-list__title">Category 5</span>
</li>
</ul>
My html:
<div class="vote-project__holder js-carousel-vote" data-owl-min-width="960">
<div class="row vote-project__duel">Content of slide 1</div>
...
<div class="row vote-project__duel">Content of slide 5</div>
</div>
In my carousel options I have binded them as dots using dotsContainer. This is my require.js part handling the carousel:
define(["jquery", "owlCarousel"], function($, owlCarousel) {
var OwlCarouselVote = {
init: function() {
var _this = this,
mainCarousel = $('.js-carousel-vote'),
minWidth = mainCarousel.data('owl-min-width') ? mainCarousel.data('owl-min-width') : 0;
if (window.matchMedia('(min-width: '+minWidth+ 'px)').matches) {
_this.initCarousel();
}
$(window).on('resize', function() {
if (mainCarousel.data("owlCarousel") !== "undefined") {
if (window.matchMedia('(min-width: '+minWidth+ 'px)').matches) {
_this.initCarousel();
} else {
_this.destroyCarousel();
}
}
});
},
destroyCarousel : function() {
jQuery('.js-carousel-vote').trigger('destroy.owl.carousel').removeClass("owl-carousel owl-loaded");
},
initCarousel: function () {
$('.js-carousel-vote').each(function() {
var $elm = $(this);
options = {
items: 1,
loop: false,
callbacks: true,
URLhashListener: true,
autoplay: false,
responsive: true,
margin: 50,
nav: true,
navSpeed: 500,
dots: true,
dotsContainer: '.category-list',
};
$elm.addClass("owl-carousel");
jQuery('.owl-carousel').owlCarousel(options);
});
//upon clicking on a category the carousel slides to corresponding slide
$('.category-list').on('click', 'li', function(e) {
jQuery('.owl-carousel').trigger('to.owl.carousel', [$(this).index(), 250]);
});
},
updateOnDomScan: function() {
this.init();
},
initOnDomScan: function() {
this.init();
}
};
return OwlCarouselVote;
});
The first part just decides wheter I am on mobile or desktop and then inits or destroys the carousel accordingly.
It works like a charm here, but on mobile, when I destroy the carousel like this jQuery('.js-carousel-vote').trigger('destroy.owl.carousel').removeClass("owl-carousel owl-loaded");, it destroys the whole .category-list list which I obviously need intact.
The reinitialization works fine because it leaves the inside of the carousel intact, but dots are missing because for some reason, the owlcarousel destroys them. I have no idea why it destroys HTML which does not belong to the carousel itself. I imagined when I binded the dots to my custom list that there is simply a reference to it and upon destroying the carousel, it would destroy just the reference.

To anyone interested, I haven't found a way to preserve native dots when destroyed. However I used a workaround so I created my own custom dots and used those.
I set dots: false in the carousel options and then binded my own list of dots to the carousel events like this
// This method listens to sliding and afterwards sets corresponding category to active
jQuery('.owl-carousel').on('translated.owl.carousel', function(event) {
$('.category-list li.active').removeClass('active');
//You have to set your li data attribute to the position it has in carousel
$('.category-list li[data-slide="'+ event.item.index +'"]').addClass("active");
});
//This method moves to corresponding slide upon clicking a category
$('.category-list').on('click', 'li', function(e) {
jQuery('.owl-carousel').trigger('to.owl.carousel', [$(this).index(), 250]);
});

Related

Splide.js text animation between slides with animate.css classes

I use splide.js carousel and i want to animate text caption between slides using animate.css.
I use splide events:
https://splidejs.com/guides/events/
This is the code i use:
document.addEventListener( 'DOMContentLoaded', function () {
var splide = new Splide( '.slider', {
type: 'fade',
perPage: 1,
autoplay: true,
focus: 'center',
trimSpace: false,
rewind: true,
} ).mount();
splide.on( 'active', function() {
const element = document.querySelector('.title');
element.classList.add('animate__animated', 'animate__fadeInRight');
} );
splide.on( 'inactive', function() {
const element = document.querySelector('.title');
element.classList.remove('animate__animated', 'animate__fadeInRight');
} );
});
Codepen example:
https://codepen.io/haralake/pen/YzQObEK
The first slide get the class but others don't. I guess i'm using events the wrong way, but i don't know where the issue is.
I use splide on my own site which is the only reason I'm familiar with it, but their documentation is horrible. The event callback functions have an event object that contain the slide index triggering the event (such as becoming active or inactive). Yes the active event does run every time a slide changes, but look at what element you're querying. You grab the first element with class 'title' regardless of what's active. The following should do what you want.
splide.on( 'active', function(e) {
const element = document.querySelectorAll('.title');
element[e.index].classList.add('animate__animated', 'animate__fadeInRight');
});
splide.on( 'inactive', function(e) {
const element = document.querySelectorAll('.title');
element[e.index].classList.remove('animate__animated', 'animate__fadeInRight');
});

Fancybox with owl carousel misses CSS

I'm building a fancybox modal(v3) with inside it two owl carousels(v2). It's used as a product quick view function.
The problem I'm facing is that the second carousel (used for the thumbs) doesn't have core css styles applied, while the carousel is actually initialized.
So the two carousels are initialized but one just won't use styling from the actual owl-carousel.css stylesheet.
I'm completly confused.
I've created a fiddle here with the actual problem.
My html
<div id="quick-shop-modal" class="cd-quick-view" style="display:none;">
<div class="product-images-slider">
<div class="slider-container"></div>
<div class="thumbnail-slider-container"></div>
</div>
</div>
Quick shop
Jquery
$(document).ready(function() {
$(".quick_view").on('click', function() {
var url = 'some-url'
$.fancybox.open({
touch: false,
src: '#quick-shop-modal',
type: 'inline',
beforeShow: function() {
quick_shop(url)
}
});
});
});
function quick_shop(url) {
var $modal = $('#quick-shop-modal');
$.getJSON(url, function(data) {
$modal.data('product', data.product);
var product = data.product;
var images = '';
$.each(product.images, function(index, image_id) {
images += '<div class="item"><div class="content"><img src="https://via.placeholder.com/350x150" class="img-responsive"></div></div>';
});
$modal.find('.slider-container').html('<div id="slider" class="slider owl-carousel">' + images + '</div>')
$modal.find('.thumbnail-slider-container').html('<div id="thumbnailSlider" class="thumbnail-slider">' + images + '</div>')
$modal.find('.slider').owlCarousel({
loop: false,
nav: false,
items: 1
}).on('changed.owl.carousel', function(e) {
$modal.find('.thumbnail-slider').trigger('to.owl.carousel', [e.item.index, 300, true]);
});
$modal.find('.thumbnail-slider').owlCarousel({
loop: false,
margin: 10,
nav: false,
items: 3,
stagePadding: 40
}).on('click', '.owl-item', function() {
$modal.find('.slider').trigger('to.owl.carousel', [$(this).index(), 300, true]);
}).on('changed.owl.carousel', function(e) {
$modal.find('.slider').trigger('to.owl.carousel', [e.item.index, 300, true]);
});
});
}
1) I do not think that anyone would be able to help you without seeing live demo and probably no-one will spend time to create it for you.
2) From you code, it seems that changing one slider would trigger change callback on both sliders. IF that is true, than that could cause the issues.
3) It is not possible to tell what role of fancybox is here just by looking at those pieces of code (e.g., what is webdinge_quick_shop doing; if #webdinge-quick-shop-modal exists, then fancybox should work fine)
Edit & Answer to updated question -
Your 2nd own carousel is missing owl-carousel classname, simply add .owl-carousel to .thumbnail-slider element, see http://jsfiddle.net/zLfnmrx1/

Replace jQuery animation with Angular animation

One of my ng-views has a next structure
<div class="container-fluid wrapper">
<aside ng-if="asideMenu">
<div ng-include src="'html/partials/stats/aside.html'"></div>
</aside>
<section>
<div ng-include src="'html/partials/stats/grid.html'"></div>
<div ng-include src="'html/partials/stats/tabs.html'"></div>
</section>
where I have a grid and tabs as a major content and if user wants he can open aside bar. The function to open aside bar is
$scope.asideMenu = false;
$scope.aside = function () {
getTree();
var section = document.getElementsByTagName("section");
var aside = document.getElementsByTagName("aside");
$scope.asideMenu = !$scope.asideMenu;
if ($scope.asideMenu == true) {
$(section).animate({
'width': '84%'
}, 500, function () {
$(aside).animate({
'width': '15%'
});
});
}
else {
$(aside).animate({
'width': '0%'
}, 1000, function () {
$(section).animate({
'width': '100%'
});
});
}
};
So currently I'm using jQuery animation to open aside menu and shrink major content.
The question is simple, what is the best way to replace jQuery animation to Angular & CSS animation (without any additional dependencies and libs)??
This is simple example of my page

ng-animate to created a slideIn / slideOut transition

I am struggle to execute a simple slide transition using angular, i know how to do this perfectly using jquery, however i am trying make use of angular and it's tools. This here provides an example of what have done thus farClick Here for example - click on the link shop..
<div id="wrapper">
<header ng-app="menu" id="main-nav">
<ul id="nav" ng-controller="subNavController">
<li>search</li>
<li>
<a class="hiddenMenu" ng-click="navMenu = !navMenu">shop</a>
<div ng-show="navMenu" class="block"></div>
</li>
<li>Join LYB</li>
<li>LYB Mix Series</li>
<li>Help</li>
<li>Sign In</li>
<li>English</li>
</ul>
</header>
</div>
controller
var app = angular.module("menu", []);
app.controller("subNavController", function ($scope){
$scope.menu = function (){
$scope.navMenu = ! $scope.navMenu;
};
$scope.navMenu = false;
});
Does anyone know how to achieve a slide in effect using angular
Here is how I achieved a similar effect, but in my case it was sliding the div in from the top. You should be able to switch the few references to top to suit your case. This requires angular-animate, jQuery, and the class specified as the name of the animation to be applied to the element (.loading in my example).
app.animation('.loading', function() {
return {
addClass : function(element, className, done) {
if(className == 'ng-hide') {
jQuery(element).animate({
top: '-100px'
}, 1000, done);
}
else {
done();
}
},
removeClass : function(element, className, done) {
if(className == 'ng-hide') {
element.css('top','-100px');
/* remove it early so you can animate on it since
it is not possible using element.css() to set
a style using !important */
element.removeClass('ng-hide');
jQuery(element).animate({
top:0
}, 0, done);
}
else {
done();
}
}
};
});

jQuery - How do I change view based on mouseOver?

I made the home page of my site so that when you mouse over the different service offerings that the related image would also display. However when Malsup's hosting of Cycle came off github the function was lost.
Here is the code I am using that worked before but no longer works correctly. The slideshow still cycles through, but the mouseover function does not work correctly.
<script type="text/javascript">
$(document).ready(function() {
$('#slideshow').cycle({
fx: 'fade',
pager : '#slideshow-nav',
pagerEvent: 'mouseover',
pauseOnPagerHover: true,
speed: 1000,
delay: 3000,
timeout: 9000,
pagerAnchorBuilder: function(idx, slide) {
// return sel string for existing anchor
return '.features ul li:eq(' + (idx) + ') a';
},
allowPagerClickBubble: true
});
});
</script>
What changes do I need to make to get it working again?
Thanks.
Try this 'command' of the plugin libary, it will do the trick.
<script type="text/javascript">
$(document).ready(function(){
$("#skills li").click(function(){
id = $(this).attr('id');
imgIndexToJump = id.substr(1); //extracting number as index from id
imgIndexToJump = parseInt(imgIndexToJump, 10);
$('.slideshow').cycle('goto', imgIndexToJump);
});
});
</script>
assign ids to ur list in skills like this and it will work.
<ul id="skills">
<li id="a0">
a1-data
</li>
<li id="a2">
a1-data
</li>
</ul>

Categories

Resources