I have a carousel which can be moved by Ion.RangeSlider. Slider width depends on number of carousel items.
Carousel itself also can be moved by mouse drag. I want to also update slider position when carousel is dragged so I initialized update for slider.
But when I update slider, it lost style attribute. So i made it to calculate this again. But also slider position appears to be not in the center at expected point, it moves to right.
Maybe it's easier to understand when viewing demo:
JSFIDDLE
Try to drag carousel to the end and you will see what the problem is.
jQuery(document).ready(function($){
var itemsNum = 0;
var owl = $('.owl-carousel');
owl.on('initialized.owl.carousel', function(event) {
var itemCount = event.item.count;
var size = event.page.size;
var dragLength = 100 / (itemCount/size);
$("#range").ionRangeSlider({
type: "single",
min: 1,
max: itemCount - (size - 1),
keyboard: true,
step: 1,
onChange: function (data) {
//owl.trigger('changed.owl.carousel', [???]);
owlTo = (data.from) - 1;
owl.trigger('to.owl.carousel', [owlTo, 500, true]);
}
});
$('.irs-slider.single').css('width', dragLength + "%")
});
//Слайдер
owl.owlCarousel({
loop:false,
margin:10,
nav:false,
dots: false,
slideBy:1,
items: 8,
responsiveClass:true,
responsive:{
0:{
items:2
},
500:{
items:3
},
600:{
items:4
},
700:{
items:5
},
800:{
items:6
},
900:{
items:7
},
1000:{
items:8
}
}
});
owl.on('dragged.owl.carousel', function(event) {
var itemCount = event.item.count;
var size = event.page.size;
var curItem = event.item.index + 1;
var dragLength = 100 / (itemCount/size);
console.log(curItem);
$("#range").data("ionRangeSlider").update({from: curItem});
$('.irs-slider.single').css('width', dragLength + "%");
});
owl.on('resized.owl.carousel', function(event) {
var itemCount = event.item.count;
var size = event.page.size;
var curItem = event.item.index + 1;
var dragLength = 100 / (itemCount/size);
$("#range").data("ionRangeSlider").update({
max: itemCount - (size - 1),
from: curItem
});
$('.irs-slider.single').css('width', dragLength + "%");
});
})
.owl-carousel .owl-item {
background-color: #ccc;
text-align: center;
}
.irs-bar, .irs-bar-edge, .irs-min, .irs-max, .irs-from, .irs-to, .irs-single{opacity: 0;}
.irs-slider.single {
transition: all 0.3s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.0.0-beta.3/assets/owl.theme.default.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.0.0-beta.3/owl.carousel.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.0.0-beta.3/assets/owl.carousel.min.css" rel="stylesheet"/>
<link href="http://ionden.com/a/plugins/ion.rangeSlider/static/css/ion.rangeSlider.skinHTML5.css" rel="stylesheet"/>
<script src="http://ionden.com/a/plugins/ion.rangeSlider/static/js/ion-rangeSlider/ion.rangeSlider.js"></script>
<link href="http://ionden.com/a/plugins/ion.rangeSlider/static/css/ion.rangeSlider.css" rel="stylesheet"/>
<div class="owl-carousel">
<div class="item"><h4>1</h4></div>
<div class="item"><h4>2</h4></div>
<div class="item"><h4>3</h4></div>
<div class="item"><h4>4</h4></div>
<div class="item"><h4>5</h4></div>
<div class="item"><h4>6</h4></div>
<div class="item"><h4>7</h4></div>
<div class="item"><h4>8</h4></div>
<div class="item"><h4>9</h4></div>
<div class="item"><h4>10</h4></div>
<div class="item"><h4>11</h4></div>
<div class="item"><h4>12</h4></div>
</div>
<div style="position: relative; padding: 20px 100px;">
<div><input type="text" id="range" value="" name="range" /></div>
</div>
The script is almost correct.
In the part where you update the ionRangeSlider after you dragged the owl.carousel there is:
var curItem = event.item.index + 1;.
That should be:
var curItem = event.item.index - 1;.
Check this fiddle:
http://jsfiddle.net/broezer/mwams6g2/28/
This only applies to a gallery of 4 items in a row.
update
However I do notice some quirks with the responsiveness.
So i reckon, it has to do something with that part of the script.
After some testing I found that changing values of items & the update function on the drag are related to each other. So be aware of this quirk.
You can set breakpoints in your drag function to change var curItem according to the breakpoints you defined in you owl.owCarousel settings
Related
I tried making jQuery slider, which will pause on current image for couple of seconds and then move images horizontally. Also, when slider presents the last image in collection, slider should slowly get back to first image, or when marginLeft attribute reaches value of -200vw(it decreases gradually for -100vw after every image). Most of the time slider works perfectly, but there are also moments when slider ignores my if and goes above -200vw(sometimes up to -3000vw), resulting in showing no images. The only thing that I noticed in this situation is that this problem can occur after around 5-10 minutes spent on other browser tabs.
P.S I apologize for a lack of precise details, because these are the only thing I have noticed with this problem
jQuery/Javascript
$(document).ready(function() {
let delay = 5300;
let currentSlide = 1;
let $carousel = $('#carousel')
let $slideContainer = $carousel.find('.slides');
let $width = 100;
let $slides = $slideContainer.find('.slide')
var interval = setInterval(function() {
$slideContainer.animate({
'marginLeft': '-=' + $width + 'vw'
}, 1000, function() {
currentSlide++;
var abc = $slideContainer.width();
if (currentSlide == $slides.length) {
setTimeout(function() {
$slideContainer.animate({
'marginLeft': '+=' + ($width + 100) + 'vw'
}, 1000, function() {
currentSlide = 1;
$slideContainer.css({
'marginLeft': 0 + 'vw'
})
})
}, (delay / 2.5))
}
})
}, delay);
});
HTML
<section id="carousel">
<div class="slides">
<div class="slide">
<img src="../javaskript/images/slider/gaming1.jpg" style="height:100vh" alt="Introduction image 2 - slider" />
</div>
<div class="slide">
<img src="../javaskript/images/slider/gaming2.jpg" style="height:100vh" alt="Introduction image 2 - slider">
</div>
<div class="slide">
<img src="../javaskript/images/slider/scorn.jpg" style="height:100vh" alt="Introduction image 2 - slider">
</div>
</div>
</section>
CSS
#carousel {
overflow : hidden;
white-space : nowrap;
width : 300vw;
height : 100vh;
}
.slides {
display : flex;
width : 300vw;
margin : 0;
padding : 0;
}
.slide {
width : 100vw;
overflow : hidden;
}
In my project I'm using this drag and drop library called gridstack. You can see their documentation on github here. When you hardcode elements inside the dom and initialize the gridstack, those elements are draggable. But when the elements are created dynamically with a forloop, they are not draggable even if they have the proper draggable classes. How can I make this work?
//initialize grid stack
var grid = GridStack.init({
minRow: 5, // don't collapse when empty
cellHeight: 70,
acceptWidgets: true,// acceptWidgets - accept widgets dragged from other grids or from outside (default: false).
dragIn: '.newWidget', // class that can be dragged from outside
dragInOptions: { revert: 'invalid', scroll: false, appendTo: 'body', helper:'clone' }, // clone or can be your function
removable: '#trash', // drag-out delete class
});
//gridstack on change
grid.on('added removed change', function(e, items) {
let str = '';
items.forEach(function(item) { str += ' (x,y)=' + item.x + ',' + item.y; });
console.log(e.type + ' ' + items.length + ' items:' + str );
});
//dynamic elemenets
const arr = ["Bruh cant drag me!", "Nope me neither", "Me too mouhahaha"];
//loop
for (let i = 0; i < arr.length; i++) {
var div = document.createElement('div');
var el = "<div class='newWidget grid-stack-item ui-draggable ui-resizable ui-resizable-autohide'> <div class='grid-stack-item-content' style='padding: 5px;'> "+arr[i]+"</div></div>";
div.innerHTML = el;
$('.dynamic').append(div);
}
.grid-stack-item-removing {
opacity: 0.8;
filter: blur(5px);
}
#trash {
background: rgba(255, 0, 0, 0.4);
padding: 5px;
text-align: center;
}
.grid-stack-item{
background: whitesmoke;
width: 50%;
border: 1px dashed grey;
}
.grid-stack {
background : #F0FFC0;
}
<!-- jquery -->
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<!-- gridstack-->
<link rel="stylesheet" href="https://gridstackjs.com/node_modules/gridstack/dist/gridstack-extra.min.css"/>
<script src="https://gridstackjs.com/node_modules/gridstack/dist/gridstack-h5.js"></script>
<!-- body-->
<body>
<div id="trash"><span>drop here to remove</span> </div>
<br>
<div class="dynamic"></div>
<div class="newWidget grid-stack-item ui-draggable ui-resizable ui-resizable-autohide">
<div class="grid-stack-item-content" style="padding: 5px;">
<div>
</div>
<div>
<span>I'm original domster! Drag and drop me!</span>
</div>
</div>
</div>
<br>
<div class="grid-stack"></div>
</body>
This issue was raised here. The grid does not automatically track external changes so the grid needs to be re-initialize for the dragIn option to notice the new dynamic widgets
GridStack.setupDragIn()
Full code
//initialize grid stack
var grid = GridStack.init({
minRow: 5, // don't collapse when empty
cellHeight: 70,
acceptWidgets: true,// acceptWidgets - accept widgets dragged from other grids or from outside (default: false).
dragIn: '.newWidget', // class that can be dragged from outside
dragInOptions: { revert: 'invalid', scroll: false, appendTo: 'body', helper:'clone' }, // clone or can be your function
removable: '#trash', // drag-out delete class
});
//gridstack on change
grid.on('added removed change', function(e, items) {
let str = '';
items.forEach(function(item) { str += ' (x,y)=' + item.x + ',' + item.y; });
console.log(e.type + ' ' + items.length + ' items:' + str );
});
//dynamic elemenets
const arr = ["Bruh cant drag me!", "Nope me neither", "Me too mouhahaha"];
//loop
for (let i = 0; i < arr.length; i++) {
var div = document.createElement('div');
var el = "<div class='newWidget grid-stack-item ui-draggable ui-resizable ui-resizable-autohide'> <div class='grid-stack-item-content' style='padding: 5px;'> "+arr[i]+"</div></div>";
div.innerHTML = el;
$('.dynamic').append(div);
}
GridStack.setupDragIn(
'.newWidget',
);
.grid-stack-item-removing {
opacity: 0.8;
filter: blur(5px);
}
#trash {
background: rgba(255, 0, 0, 0.4);
padding: 5px;
text-align: center;
}
.grid-stack-item{
background: whitesmoke;
width: 50%;
border: 1px dashed grey;
}
.grid-stack {
background : #F0FFC0;
}
<!-- jquery -->
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<!-- gridstack-->
<link rel="stylesheet" href="https://gridstackjs.com/node_modules/gridstack/dist/gridstack-extra.min.css"/>
<script src="https://gridstackjs.com/node_modules/gridstack/dist/gridstack-h5.js"></script>
<!-- body-->
<body>
<div id="trash"><span>drop here to remove</span> </div>
<br>
<div class="dynamic"></div>
<div class="newWidget grid-stack-item ui-draggable ui-resizable ui-resizable-autohide">
<div class="grid-stack-item-content" style="padding: 5px;">
<div>
</div>
<div>
<span>I'm original domster! Drag and drop me!</span>
</div>
</div>
</div>
<br>
<div class="grid-stack"></div>
</body>
I'm using multiple number elements on my site which are counting up after hitting the visible area of the viewport.
That part works until the user manually scrolls the page. If the user scrolls up or down, the animation stops for a second and repeats when the user don't scroll anymore. It looks very buggy.
If I try to replicate the problem in a fiddle, the same code always works without the "stuttering"?
jQuery(function($) {
$(function($, win) {
$.fn.inViewport = function(cb) {
return this.each(function(i, el) {
function visPx() {
var H = $(this).height(),
r = el.getBoundingClientRect(),
t = r.top,
b = r.bottom;
return cb.call(el, Math.max(0, t > 0 ? H - t : (b < H ? b : H)));
}
visPx();
$(win).on("resize scroll", visPx);
});
};
}(jQuery, window));
$(".fig-number").inViewport(function(px) {
// if px>0 (entered V.port) and
// if prop initNumAnim flag is not yet set = Animate numbers
if (px > 0 && !this.initNumAnim) {
this.initNumAnim = true; // Set flag to true to prevent re-running the same animation
$(this).prop('Counter', 0).animate({
Counter: $(this).text()
}, {
duration: 10000,
step: function(now) {
$(this).text(Math.ceil(now));
}
});
}
});
});
html,
body {
height: 100%;
}
.spacer {
height: 100%;
width: 100%;
display: block;
background: red;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="spacer">
scroll down
</div>
<div class="number-box">
<h1 class="fig-number">1000</h1>
<h1 class="fig-number">1500</h1>
</div>
<div class="spacer">
scroll down
</div>
<div class="number-box">
<h1 class="fig-number">2000</h1>
<h1 class="fig-number">2500</h1>
</div>
<div class="spacer">
scroll down
</div>
<div class="number-box">
<h1 class="fig-number">3000</h1>
<h1 class="fig-number">3500</h1>
</div>
The working fiddle (same code): https://jsfiddle.net/JSCray/r7g0vn93/3/
I have a one page site with few sections.. Bootstrap template. One of the sections cause a bug after few refreshes of the site. There are no errors in the console.. nothing and I just don't know how to trace and find the problem.
This is the html part of this section
<section id="portfolio" class="section portfolio padding-large text-center" data-section-name="portfolio">
<div class="container margin-bottom-medium">
<div class="row margin-bottom-medium wow fadeInUp">
<h2> Portfolio </h2>
<div class="line main-bg"></div>
</div>
</div>
<div class="portfolio-wrapper margin-bottom-medium">
<div class="portfolio-item">
<div class="portfolio" style="margin-left:5px;"><a href="#" data-lightbox-gallery="portfolio"><img src="img/portfolio/release02-360x360.jpg" alt="">
<div class="portfolio-overlay hvr-rectangle-out">
<h2 class="margin-bottom-small">
<strong class="white-color bold-text" style="font-size: 20px;">Portfolio</strong>
</h2>
<div class="button">Check item</div>
</div>
</a>
</div>
</div>
</div>
<div class="button light margin-top-medium margin-bottom-medium hvr-grow"><i class="icon-reload"></i> Check All</div>
</section>
This is what I have in main.js from the portfolio section
var container = $('.portfolio-wrapper'); // portfoolio container
container.isotope({
itemSelector: '.portfolio-item',
animationEngine: 'best-available',
animationOptions: {
duration: 200,
queue: false
},
layoutMode: 'fitRows'
});
// Split columns for different size layout
function splitColumns() {
var windowWidth = $(window).width(),
columnNumber = 1; // default column number
if (windowWidth > 1200) {
columnNumber = 4;
} else if (windowWidth > 767) {
columnNumber = 3;
} else if (windowWidth > 600) {
columnNumber = 2;
}
return columnNumber;
}
// Set width for portfolio item
function setColumns() {
var windowWidth = $(window).width(),
columnNumber = splitColumns(),
postWidth = Math.floor(windowWidth / columnNumber);
container.find('.portfolio-item').each(function() {
$(this).css({
width: postWidth + 'px'
});
});
}
// initialize isotope
function initIsotope() {
setColumns();
container.isotope('layout');
}
container.imagesLoaded(function() {
setColumns();
});
$(window).bind('resize', function() {
initIsotope();
});
initIsotope();
Here are two images in normal state and when it's crashed. Normal behavior
Here is when it crashed
I really don't have an idea of what can be the issue since there are no errors at all. I think that may be a js problem but again I'm not sure.
Edit: Here are the JS which are included in footer in this order:
<script src="js/vendor/jquery-1.11.1.js"></script>
<script src="js/vendor/jquery-migrate-1.2.1.min.js"></script>
<script src="js/vendor/bootstrap.js"></script>
<script src="js/wow.min.js"></script>
<script src="js/twitterFetcher_min.js"></script>
<script src="js/jquery.easing.min.js"></script>
<script src="js/appear.js"></script>
<script src="js/jquery.circliful.min.js"></script>
<script src="js/owl.carousel.min.js"></script>
<script src="js/nivo-lightbox.min.js"></script>
<script src="js/isotope.pkgd.min.js"></script>
<script src="js/imagesloaded.pkgd.min.js"></script>
<script src="js/main.js"></script>
<script src="js/scrollify.js"></script>
Edit2: Wrapping like this?
// initialize isotope
function initIsotope() {
setColumns();
container.isotope('layout');
}
container.imagesLoaded(function() {
setColumns();
});
$(window).bind('resize', function() {
initIsotope();
});
//initIsotope();
setTimeout(function(){ initIsotope(); }, 0);
From having a look at similar masonry issues. I would suspect one of these two would solve your issue -
$(window).load(function(){
initIsotope()
});
// or
setTimeout(function(){ initIsotope(); }, 0);
Both these are masking the core issue - you should really be reading the section around unloaded media here - http://isotope.metafizzy.co/v1/docs/help.html
I would suggest your content is not fully loaded sometimes and isotope gets confused. Specifying the dimensions lets isotope render correctly despite the images not loading quickly enough. You need to follow this pattern so that slow connections work. Setting timeouts has its uses, but you should fix the underlying issue.
I am very new to AngularJs, I have written a slider function in jQuery. Now I want to convert thih function into Angular. Here is my code below::
<div class="slide-container">
<div class="slide-scroller" style="left: 0px;">
<div class="slideContent" style="background-color: #f00;">one</div>
<div class="slideContent" style="background-color: #0f0;">two</div>
<div class="slideContent" style="background-color: #00f;">three</div>
</div>
</div>
<input type="button" id="left">
<input type="button" id="right">
.slide-container {height: 100px; overflow: hidden; position: relative;}
.slide-scroller { height: 100px; overflow:hidden; position: absolute; top: 0px;}
.slide-scroller .slideContent { height: 100px; overflow: hidden; float: left;}
function slider() {
var slideWidth, speed, sc, slideScroller, scSlide, totalSlide, scrollerWidth, maxLeft;
slideWidth = $(window).width(); // [ get the device width ]
speed = 0.6; // [ control speed 1 = 1s]
sc = $(".slide-container"); // [ getting the container ]
slideScroller = $('.slide-scroller'); // [ getting slider scroller ]
scSlide = $('.slideContent'); // [ getting slide contetnts ]
totalSlide = $(scSlide).length; // [ total slide contents ]
scrollerWidth = totalSlide * slideWidth; // [ slide scroller width ]
maxLeft = -parseInt(scrollerWidth) + parseInt(slideWidth); // [maxmimum left slide value]
// adding some initial attributes
$(sc && scSlide).css({width: slideWidth});
$(slideScroller).css({width: scrollerWidth});
$(slideScroller).css('transition', 'all ease '+speed+'s');
// left click function
$("#left").click(function () {
var xvalue = $(slideScroller).css('left'); //console.log('left :: ', xvalue);
var newvalue = parseInt(xvalue) - parseInt(slideWidth); // console.log('newValue :: ', newvalue);
if (newvalue >= maxLeft) {//console.info('no more left left');
$(slideScroller).css('left', newvalue);
}
else {
return false;
}
});
// right click function
$("#right").click(function () {
var xvaluetwo = $(slideScroller).css('left'); console.log('lefttwo :: ', xvaluetwo);
var newvaluetwo = parseInt(xvaluetwo) + parseInt(slideWidth); console.log('newValuetwo :: ', newvaluetwo);
if (newvaluetwo <= 0) {//console.info('no more right left');
$(slideScroller).css('left', newvaluetwo);
}
else {
return false;
}
});
}
$(document).ready(function () {
slider();
});
I have linked jQuery.min library and called the function in document.ready
Please help me how to make in AngularJS
in HTML:
<div class="slide-container" ng-init="initSlider()">
<div class="slide-scroller" ng-repeat="item in sliderList" style="left: 0px;">
<div class="slideContent" style="background-color: {{item.bgColor}}">{item.content}</div>
</div>
</div>
<input type="button" id="left">
<input type="button" id="right">
in Controller:
$scope.initSlider = function(){
slider()
}