jquery owl-carousel owl-dots class issue - javascript

I get some problem when I use owl-carousel in my Rails project.
when I go back to the cached page of my browsers which is using carousel class, I get too many carousel owl-dot classes in my page,this is my
JS code
function initScrollboxHobby() {
var owl = $(".owl-carousel");
owl.owlCarousel({
// loop: true,
items: 1,
nav: true
});
}
and issue HTML code
How to fix it ?

I guess you are using turboinks and when you go back the page is cached by it and when it loads it reruns the owl carousel init function.
The problem, básically, is that turbolinks doesn't play well with non-idempotent functions https://github.com/turbolinks/turbolinks#making-transformations-idempotent
I've managed to make a workaround for this problem with other js plugins, so it should work for you.
Básically, the idea is:
First, when the user enters the page for the first time, copy the content of the element with class .owl-carousel on itself as a data attribute
carousel = $('.owl-carousel');
carousel.data('originalHtml', carousel.html();
carousel.owlCarousel(....)
Then, when the users goes back, before initializing the carousel, check if it was initialized and cached, in that case, first replace the content with the original and remove classes
carousel = $('.owl-carousel');
if (carousel.hasClass('owl-loaded')) {
carousel.html(carousel.data('originalHTML')).removeClass('owl-theme owl-loaded owl-drag');
}
carousel.owlCarousel(....)
You can mix both steps into one:
$(function() {
const carousel = $('.owl-carousel');
if (carousel.hasClass('owl-loaded')) { //if it has the class then it means it's the cached view
carousel.html(carousel.data('originalHTML')).removeClass('owl-theme owl-loaded owl-drag');
} else { // else it's a fresh load of the page
carousel.data('originalHtml', carousel.html());
}
carousel.owlCarousel(....)
})
It's a little bit hacky, but the only way I found to use plugins that are not prepared to work with turbolinks without going through modifying those plugins.
Another option would be to just disable Turbolinks if you thing you just don't need it.

For arieljuod's help of problem reason and my own trying.
I coded like this now.
var owl = $(".owl-carousel");
var owl_navs = $('.owl-carousel .owl-nav');
var owl_dots = $('.owl-carousel .owl-dots');
var owl_cloned = $('.owl-carousel .owl-stage-outer .owl-stage .cloned');
if(owl.hasClass('owl-loaded'))
{
owl_navs.remove();
owl_dots.remove();
owl_cloned.remove();
}
owl.owlCarousel({
loop: true,
items: 1,
nav: true
});
It's tedious but worked well.
Now,I understanded reason.
When I go back to cached page,because I wrote javascript code in my ERB file,in that way, old HTML code may changed.
And then Turbolinks function will run the JS code in that CHANGED new HTML code,Turbolinks must do that,because when I visit cached page again,it will lose all the event binds.
So the whole carousel items will be messy.

Related

Fix double componentDidMount in React when add jQuery carousel

When I would like to add an old jQuery carousel (jCarousellite) into my React project I have faced with double componentDidMount update in case when I work within React component. Such behaviour of React produces by the dynamical insertion of additional tags (carousel items) into the carousel cause It needs It to some functionality like circular switching. So I have found only one working relatively good solution just to copy the embbed into the main container of the carousel tags to some local variable and use the variable in componentWillUnmount like this
import $ from "jquery"
window.jQuery = $;
require("jcarousellite/jcarousellite");
class Footer extends Component {
main_slider_items; //variable to copy the carousel items into
componentWillUnmount() {
$('.brand_slider ul').html(this.main_slider_items); //insert into the carousel saved during the first mount items
}
componentDidMount() {
this.main_slider_items = $('.brand_slider ul li'); //save items of the carousel here
$('.brand_slider').jCarouselLite({ //assign jQuery plugin to the element
btnNext: '.brand_slider_wrap .next',
btnPrev: '.brand_slider_wrap .prev',
mouseWheel: true,
visible: 4,
scroll: 1,
speed: 150,
circular: true
});
}
render() {
(
{/* some render code here */}
)
}
...
Either If I would like to use indicators functionality of my carousel for instance then I have to do the same trick with them otherwise they also would have been mounted twice and the second time It would be the wrong value. Unfortunalety that solution has at least one disadvantage - items switching within unpredictable movement sometimes but the order of the switching is right. I tried to suppress It somehow by decreasing the speed of the switching but nevertheless I just wonder If there another efficient solution cause sometimes I need to work with very legacy projects and plenty of old code such as various jQuery plugins those wouldn't be rewritten to React style immediately. Thank you.

Slick Carousel Blank

I set up an overlay slick carousel, so when you click on the image a larger carousel appears with the selected image as the initialSlide. However, Slick carousel is adding several blank slides after the initialSlide. The blanks only appear when you click next starting with the third slide. When you click on the previous button the blank slides do not appear. What am I doing wrong?
$("#sync1 .item").on("click", function() {
var index = $(this).attr("data-slick-index");
$(".overlay-carousel-container").css("display", "block");
$("body").css("overflow", "hidden");
$("#overlayCarousel").slick({
slidesToShow: 1,
slidesToScroll: 1,
fade: true,
initialSlide: index,
focusOnSelect: true
});
})
$(".close").on("click", function() {
$(".overlay-carousel-container").css("display","none");
$("body").css("overflow", "inherit");
$("#overlayCarousel").slick("unslick");
$("#executiveOverlay").slick("unslick");
});
The Jquery attr() function returns a string value. When you pass that into the slick constructor function it translates it to a different number.
Adding a simple Number() function to change the index to numeric should solve your problem. Just place the following middle line between the lines I placed it:
var index = $(this).attr("data-slick-index");
index = Number(index);
$(".overlay-carousel-container").css("display", "block");
This answer is for the people who are struggling slick carousal as I also faced a lot of problem with it, even though it seems very easy as mentioned but I found out that it has lots limitation.
Very old
To have exact same look like mentioned it needs CSS(SCSS) which is difficult to do in development which as a new user I realised it quite late. Or you don't get dots and arrows with the same exact look easily.
Several other issues like the one mentioned here and other I found over stack flow.
The best one I resorted to for similar process is the one mentioned here
it's latest
and comes with a simple tutorial as well
Recommended for new beginner developers.

iDangero Swiper using Worklight?

Is there an easy way to implement this? I am having trouble getting it to work properly. I tried following the instructions on the website to have it load at window.onload, but Worklight seems to fire that call before the DOM is even visible, so I couldn't do that. I have some initialization code and so I am calling the following method in that code:
function runSwiper(){
// iDangerous Swiper
var mySwiper = new Swiper('.swiper-container', {
pagination : '.pagination',
loop : true,
grabCursor : true,
simulateTouch : true,
paginationClickable : true
});
}
Yet, all I see in my carousel is just Text. I have two test slides in there currently, but the slide doesn't even seem to work on my Android emulator. Is there anything else I need to be doing for this to work properly? If not, is there something that works as nicely as this that will play nice with Worklight?
I am using worklight version 6.2. I am usingth is: http://www.idangero.us/sliders/swiper/api.php
What I am aiming to do is fade out one div that has information, and fade in another div that has more info and the Swiper present, so initially this swiper will be hidden.
I turns out, in my case, the easiest way to call the swiper to initialize was later on (being that it was in a hidden div) instead of at window.onload. In addition, I had some issues with slides disappearing, which I fixed by having the slides pre-defined in the HTML instead of adding them dynamically.

jQuery - bxSlider plugin reloadSlider issues

I'm using jQuery with the bxSlider plugin, here is the link to it just incase: http://bxslider.com/
I'm trying to reload the slider and my custom pager after I've removed certain slides from it.
Here is what I have tried:
$(function() {
var slider = $('#slider').bxSlider({
pagerCustom: '#bx-pager'
});
$('.list').on('click', '.delete', function() {
image = $(this).closest('li').find('[type="hidden"]');
// image.attr('id') contains a string: image-0, image-1, image-2, etc.
$('#slider, #bx-pager').find('.' + image.attr('id')).remove();
slider.reloadSlider({
pagerCustom: '#bx-pager'
}); // I have also tried: slider.reloadSlider();
});
});
It works partially. What happens is the slider gets reloaded just fine but it removes the pager completely when it runs the reload.
Thank you very much for any help.
As long as I see, this is a bug in bxSlider, in fact, when you call the reloadSlider method, internally are called the methods destroySlider and init.
In the destroySlider method the pagerEl element is destroyed, this is right if you are not using a custom one, because it is recreated programmatically in the init method, but if you are using a custom one it can't be recreated programmatically.
I ended up modifying the destroySlider method to check if a custom pager is used, in this case it must not be deleted.
Here is the before (line 1294):
if(slider.pagerEl) slider.pagerEl.remove();
And after:
if (slider.settings.pagerCustom === '') {
if(slider.pagerEl) slider.pagerEl.remove();
}
I'll post the bug on GitHub as soon as I have the time.

Javascript making text slide in from html

I am trying to make a text-slide-in effect on a web page. I am using the javascript slidesjs library because it seemed like the best fit. However, I cannot make it work when triggered by a web click.
I have a live example running at: http://107.22.173.10
Note that when you click the "GOTO" links nothing happens.
The basic code is as follows and it seems the page is supposed to automatically put '#' anchors in to trigger the slides. I can't make this work, or figure out how to debug this.
$(function(){
// Set starting slide to 1
var startSlide = 1;
// Get slide number if it exists
if (window.location.hash) {
startSlide = window.location.hash.replace('#','');
}
// Initialize Slides
$('#slides').slides({
preload: true,
preloadImage: 'img/loading.gif',
generatePagination: true,
//play: 5000,
//pause: 2500,
hoverPause: true,
// Get the starting slide
start: startSlide,
animationComplete: function(current){
// Set the slide number as a hash
window.location.hash = '#' + current;
}
});
});
Does anyone see what's going wrong here?
What is the best way to debug this problem?
Is there a better way or library I should be using?
Any advice is appreciated. Thanks!!
You're not following the example from slidesjs.com. See "Basic HTML structure". You're putting only one element in the #slides_container div, and assign all sorts of weird absolute positioning to it, which of course won't work with the animation code.
Copy paste the example first, then start adding your own tweaks concerning style.

Categories

Resources