I am making a slider with divs:
<div class="slider">
<div class="panel"></div>
<div class="panel"></div>
<div class="panel"></div>
... A lot more panels hidden by css ...
</div>
The project required them to be spaced equally and fluid. Jquery is being used. I achieved this by:
.slider {
width: 100%;
text-align: justify;
height: fixed-height-here;
overflow: hidden
}
.panel {
display: inline-block
}
I am uncertain how to make them slide. There is a variable amount of elements, and the slider is variable width. I had the following idea:
... A lot more panels hidden by css ...
onclick:
$(".inner").css("width", page * 100); //expand the width
$(".inner").animate({"margin-left", -(page - 1) * $(".inner").innerWidth());
This works "ok" (but not quite idea) when it slides from page 1 to page 2, but it does not work sliding from page 2 to page 1.
How can I achieve the effect I am wanting?
Here's a real simple "slider" with some "animation" you can play with FIDDLE.
JS
var i = 1;
$( ".sliderholder img:nth-child(" + i + ")" ).show(1000);
$('#forward').on('click', function(){
$( ".sliderholder img:nth-child(" + i + ")" ).hide( "slide",
{direction: 'right'},
1000);
i = i+1;
if( i > $('.sliderholder img').length )
{ i = 1; }
$( ".sliderholder img:nth-child(" + i + ")" ).show(1000);
});//end on click
$('#back').on('click', function(){
$( ".sliderholder img:nth-child(" + i + ")" ).hide( "slide",
{direction: 'right'},
1000);
i = i-1;
if( i < 1 )
{ i = $('.sliderholder img').length; }
$( ".sliderholder img:nth-child(" + i + ")" ).show( 1000);
});//end on click
Related
I have a dynamic webpage where i use Jquery "draggable" & "droppable".
I'm trying to move one element from one "parent" to another.
When i do "console.log" i can see that the element has a new parent.
But When i later on add more HTML content to the DOM, the element won't move with it's new parent. It's stuck to the "document" offset position.
How can i solve this?
FIDDLE
https://jsfiddle.net/0apuqnxd/13/
JS
//Make elements Draggable
$('.elementsDiv').draggable({
revert: 'invalid',
});
var flakUpId = $('#1').attr('id');
$('#btnAddDropZone').on('click', function() {
flakUpId++;
var flakUp = "<div class='flakUp'>DropZone " + flakUpId + " </div>";
$('#dropZones').prepend(flakUp);
})
$('.flakUp, .flakDown').droppable({
accept: '.elementsDiv',
drop: function(event, ui) {
var droppable = $(this);
var draggable = ui.draggable;
//Detach element from DOM
draggable.detach();
//Append element to droped position and into new parent?
draggable.css({
"left": ui.offset.left,
"top": ui.offset.top,
"position": "absolute"
}).appendTo(droppable);
},
});
How about this?
//Make elements Draggable
$('.elementsDiv').draggable({
revert: 'invalid',
});
var flakUpId = $('#1').attr('id');
$('#btnAddDropZone').on('click', function() {
flakUpId++;
var flakUp = "<div class='flakUp'>DropZone " + flakUpId + " </div>";
$('#dropZones').prepend(flakUp);
registDroppable();
$(".flakUp .elementsDiv").each(function(e) {
$(this).css({"top": $(this).offset().top+$(".flakUp").height()});
});
})
function registDroppable() {
$('.flakUp, .flakDown').droppable({
accept: '.elementsDiv',
drop: function(event, ui) {
var droppable = $(this);
var draggable = ui.draggable;
// Move draggable into droppable
draggable.css({
"left": ui.offset.left,
"top": ui.offset.top,
"position": "absolute"
}).appendTo(droppable);
},
});
}
registDroppable();
https://jsfiddle.net/ChaHyukIm/0apuqnxd/15/
I just changed three things and it seems working:
1) added ID and class when you add new Div:
a)id="12" - Hardcoded to Test you can change later
b) class="ui-droppable" added
$('#btnAddDropZone').on('click', function() {
flakUpId++;
var flakUp = "<div id='12' class='flakUp ui-droppable '>DropZone " + flakUpId + " </div>";
$('#dropZones').prepend(flakUp);
})
2). I gave different ID=100 instead of 1.
Because i saw another div with id="1"
<div id="dropZones">
<div class='flakUp' id="100">DropZone 1</div>
</div>
Full Code:
HTML
<div class="row well">
<button class="btn btn-primary" id="btnAddDropZone">Add dropZone</button>
</div>
<div id="dropZones">
<div class='flakUp' id="100">DropZone 1</div>
</div>
<hr>
<div class="elementsDiv" id="1" style="width: 200px; height: 25px; background-color: #c2c2d6; cursor: move">Drag me 1</div>
<div class="elementsDiv" id="2" style="width: 150px; height: 35px; background-color: #c2c2d6; cursor: move">Drag me 2</div>
<div class="elementsDiv" id="3" style="width: 160px; height: 35px; background-color: #c2c2d6; cursor: move">Drag me 3</div>
Script
//Make elements Draggable
$('.elementsDiv').draggable({
revert: 'invalid',
});
var flakUpId = $('#1').attr('id');
$('#btnAddDropZone').on('click', function() {
flakUpId++;
var flakUp = "<div id='12' class='flakUp ui-droppable'>DropZone " + flakUpId + " </div>";
$('#dropZones').prepend(flakUp);
})
$('.flakUp, .flakDown').droppable({
accept: '.elementsDiv',
drop: function(event, ui) {
var droppable = $(this);
var draggable = ui.draggable;
// Move draggable into droppable
var offset = $(this).offset();
var relX = event.pageX - offset.left;
var relY = event.pageY - offset.top;
draggable.css({
"left": ui.offset.left,
"top": ui.offset.top,
"position": "absolute"
}).appendTo(droppable);
},
});
I guess you are wondering why did I even post this question as there tons of examples available out there. But somehow I cannot get this to work.
So my problem is. I have a jQueryfunction that loops through my divs and gets their ID's. So here is the loop
var linames =["Intro","1925","1935","1945","1955","1965","1975","1985","1995","2005","Now"];
var i = 0;
function getSectionIDs()
{
$("div.panel-grid-cell").children().each(function() {
if(linames[i] !== undefined) {
li += "<li><a href='#"+$(this).attr('id')+"'>"+linames[i]+"</a></li>";
}
i++;
});
$("ul.timeline-items").append(li);
}
And the following HTML structure.
<div class="panel-grid-cell">
<div id="panel-101-0-0-0">...</div>
<div id="panel-101-0-0-1">...</div>
<div id="panel-101-0-0-2">...</div>
...
<div id="panel-101-0-0-12">...</div>
</div>
So What I want to achieve is. Click on a li Items and have a smooth scroll to respective div. At the moment it just instantly jumps.
Tried about 10 different ways, and still no effect.
Here you are, a fully working demo.
$(function() {
var linames = ["Intro", "1925", "1935", "1945", "1955", "1965", "1975", "1985", "1995", "2005", "Now"];
function getSectionIDs() {
var li = "";
$("div.panel-grid-cell").children().each(function(index) {
if (linames[index] !== undefined) {
li += "<li><a href='#" + $(this).attr('id') + "'>" + linames[index] + "</a></li>";
}
});
$("ul.timeline-items").append(li);
$("ul.timeline-items li a").click(function(e) {
e.preventDefault();
var anchor_id = $(this).attr("href");
$('html,body').animate({
scrollTop: $('' + anchor_id + '').offset().top
}, 2000);
});
}
getSectionIDs();
});
.panel {
height: 900px;
width: 100%;
display: block;
}
.panel:nth-child(odd) {
background-color:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="timeline-items"></ul>
<div class="panel-grid-cell">
<div class="panel" id="panel-101-0-0-0">...</div>
<div class="panel" id="panel-101-0-0-1">...</div>
<div class="panel" id="panel-101-0-0-2">...</div>
</div>
I am trying to make a flowing-down div. I have the following jQuery code for them:
$(".centered-wrapper>main>.event").hoverIntent({
over: function() {
var pos = $(this).position();
$presentationEvent = $(this);
$fullEvent = $(this).clone();
$fullEvent.addClass("full");
$(this).css("visibility", "hidden");
$fullEvent.css({
position: "absolute",
top: pos.top,
left: pos.left
});
$(".centered-wrapper>main").append($fullEvent);
$fullEvent.find("main").slideDown(50, function() {
$fullEvent.find("footer").slideDown(50);
});
$fullEvent.animate({boxShadow: "0px 5px 5px 0px rgba(0,0,0,0.5);"}, 100);
console.log( $(".centered-wrapper>main>.event.full"));
$(".centered-wrapper>main>.event.full").on("mouseout", function() {
$(this).find("main, footer").slideUp(100);
$(this).remove();
$presentationEvent.css("visibility", "visible");
});
},
out: function() {}
});
Everything works well until I move my cursor up and down on that element, because, then it flickers and appears and disappears...
<div class="event">
<header>
<img class="photo" src="/res/users/events-photos/bal.jpg" alt=""/>
<div class="event-card">
<div class="date">
<!-- content -->
</div>
</header>
<main>
<!-- content -->
</main>
<footer>
<!-- content -->
</footer>
</div>
How can I solve this problem and where am I wrong?
You need to disable multiple queued animations. The best way to achieve this is to stop() it.
http://api.jquery.com/stop/
According to documentation:
$( "#hoverme-stop-2" ).hover(function() {
$( this ).find( "img" ).stop( true, true ).fadeOut();
}, function() {
$( this ).find( "img" ).stop( true, true ).fadeIn();
});
In your case:
$fullEvent.find("main").stop(true,true).slideDown(50, function() {
$fullEvent.find("footer").stop(true,true).slideDown(50);
});
and:
$(this).find("main, footer").stop(true,true).slideUp(100);
The visibility hidden code interferes with element hover and causes the flicker. Use another way to hide it. Like
.event:hover
{
opacity: 0;
}
To avoid events from firing use 'pointer-events: none;'
.event:hover
{
opacity: 0;
pointer-events: none;
}
I am using lazyYT to load youtube video's faster. The loaded lazyYT videos are then placed in the slick slider. What then happens is that the video's are sticking together instead of a nice margin between every video. So I manually added a class to the video div
<div class="js-lazyYT" id="video-slide" data-youtube-id="<?php echo $video['video_link']; ?>" data-width="500" data-height="425"></div>
and gave it a margin which is working fine until the first video comes loaded back again. They paste together until all three first video's are visible again.
#video-slide{
width: 500px !important;
height: 425px !important;
margin-right: 10px;
-webkit-border-radius: 15px;
-moz-border-radius: 15px;
border-radius: 15px;
}
It looks like the first 3 entries in the slider reload the slider again when they are visible. Any idea?
;(function ($) {
'use strict';
function setUp($el) {
var width = $el.data('width'),
height = $el.data('height'),
ratio = $el.data('ratio'),
id = $el.data('youtube-id'),
aspectRatio = ['16', '9'],
paddingTop = 0,
youtubeParameters = $el.data('parameters') || '';
if (typeof width === 'undefined' || typeof height === 'undefined') {
height = 0;
width = '100%';
aspectRatio = (ratio.split(":")[1] / ratio.split(":")[0]) * 100;
paddingTop = aspectRatio + '%';
}
$el.css({
'position': 'relative',
'height': height,
'width': width,
'padding-top': paddingTop,
'background': 'url(http://img.youtube.com/vi/' + id + '/hqdefault.jpg) center center no-repeat',
'cursor': 'pointer',
'background-size': 'cover'
})
.html('<p id="lazyYT-title-' + id + '" class="lazyYT-title"></p><div class="lazyYT-button"></div>')
.addClass('lazyYT-image-loaded');
$.getJSON('https://gdata.youtube.com/feeds/api/videos/' + id + '?v=2&alt=json', function (data) {
$('#lazyYT-title-' + id).text(data.entry.title.$t);
});
$el.on('click', function (e) {
e.preventDefault();
if (!$el.hasClass('lazyYT-video-loaded') && $el.hasClass('lazyYT-image-loaded')) {
$el.html('<iframe width="' + width + '" height="' + height + '" src="//www.youtube.com/embed/' + id + '?autoplay=1&' + youtubeParameters + '" style="position:absolute; top:0; left:0; width:100%; height:100%;" frameborder="0" allowfullscreen></iframe>')
.removeClass('lazyYT-image-loaded')
.addClass('lazyYT-video-loaded');
}
});
}
$.fn.lazyYT = function () {
return this.each(function () {
var $el = $(this).css('cursor', 'pointer');
setUp($el);
});
};
}(jQuery));
I was looking at the lazyYT site and found their example:
<div class="container">
<div class="js-lazyYT" data-youtube-id="_oEA18Y8gM0" data-width="560" data-height="315" data-parameters="rel=0"></div>
</div>
Given that, you might try:
.myclass {
margin-left: 5px;
}
<div class="container">
<div class="js-lazyYT myclass" data-youtube-id="_oEA18Y8gM0" data-width="560" data-height="315" data-parameters="rel=0"></div>
</div>
or
<div class="container">
<div class="js-lazyYT" data-youtube-id="_oEA18Y8gM0" data-width="560" data-height="315" data-parameters="rel=0"> style='margin-left: 5px'</div>
</div>
or
.myclass div {
margin-left: 5px;
}
<div class="container myclass">
<div class="js-lazyYT" data-youtube-id="_oEA18Y8gM0" data-width="560" data-height="315" data-parameters="rel=0"></div>
</div>
Basically I am just trying to do random jQuery stuff for educational purpose, and here is my very simple slider. I want it to work automatically and also with controls (little arrows to scroll to next/previous slider). The only problem that I have right now is that when you press the arrow, the function that automatically switches slides every 5 seconds is still counting these 5000 ms, so the next slide appears faster then desired. What I want is to make those arrows reset the timer, so you press the arrow -> next slide appears -> only after 5 seconds later the slide switches again.
Sorry for sloppy explanation, hope I made it clear enough.
Here's the jsfiddle: http://jsfiddle.net/cA9aW/
and here is the code
HTML
<body>
<div id="wrapper">
<header>
<h1>Simplest Sliding Image Slider</h1>
</header>
<div id="content">
<div id="slider_container">
<div id="slider">
<div class="slides" id="slide1">
<img src="http://s2.postimg.org/5uxqi0mgl/cats1.jpg" alt="" />
</div>
<div class="slides" id="slide2">
<img src="http://s2.postimg.org/66f6us2wl/cats2.jpg" alt="" />
</div>
<div class="slides" id="slide3">
<img src="http://s2.postimg.org/ai3sjs9th/cats3.jpg" alt="" />
</div>
</div>
</div>
</div>
<footer></footer>
</div>
</body>
JS
jQuery(document).ready(function($) {
// start slider function
startSlider();
// set width and step variables and add active class to first slider
var slideWidth = $('.slides').width();
$('#slide1').addClass('slides active');
// actual function
function startSlider() {
looper = setInterval(function() {
// remove and add class active
$('.active').removeClass('active').next().addClass('active');
// animation expression
$('.active').animate({'left': '-=' + (slideWidth) + 'px'}, 500);
$('.active').siblings().animate({'left': '-=' + (slideWidth) + 'px'}, 500);
// return to first slide after the last one
if($('.active').length == 0) {
$('#slide1').addClass('active');
$('.slides').animate({'left': 0}, 500);
}
}, 5000); // interval
// adding controls
$('.slides').append("<div class='controls'><a class='control_left' href='#'></a><a class='control_right' href='#'></a></div>");
// remove unnecessary controlls on first and last slides
$('.slides:nth-child(1) a.control_left').remove();
$(".slides:nth-child(" + $('.slides').length + ") a.control_right").remove();
// add functionality to controls
$('.control_left').on('click', function() {
$('.active').removeClass('active').prev().addClass('active');
$('.active').animate({'left': '+=' + (slideWidth) + 'px'}, 500);
$('.active').siblings().animate({'left': '+=' + (slideWidth) + 'px'}, 500);
});
$('.control_right').on('click', function() {
$('.active').removeClass('active').next().addClass('active');
$('.active').animate({'left': '-=' + (slideWidth) + 'px'}, 500);
$('.active').siblings().animate({'left': '-=' + (slideWidth) + 'px'}, 500);
});
}
});
Thx a lot in advance
Slideshow with prev/next buttons, autoslide, pause on hover
Instead of jQuery's .animate() and animating the left CSS property, use the GPU accelerated CSS transform: translateX for the animation on a common slides wrapper element
$(".SlideShow").each((i, EL) => {
const
$parent = $(EL),
$slides = $(".SlideShow-slides", EL),
$item = $(".SlideShow-item", EL),
$prevNext = $(".SlideShow-btn", EL),
tot = $item.length,
mod = (n, m) => ((n % m) + m) % m;
let
c = 0,
itv;
const prev = () => {c = mod(--c, tot); anim();};
const next = () => {c = mod(++c, tot); anim();};
const anim = () => $slides.css({transform: `translateX(-${c * 100}%)`});
const stop = () => clearInterval(itv);
const play = () => itv = setInterval(next, 4000);
$prevNext.on("click", (ev) => $(ev.currentTarget).is(".next") ? next() : prev());
$parent.hover(stop, play);
play(); // start
});
.SlideShow {
position: relative;
overflow: hidden;
width: 100%;
height: 180px;
}
.SlideShow-slides {
display: flex;
flex-flow: row-nowrap;
height: 100%;
width: 100%;
transition: transform 0.7s; /* Animation duration here */
}
.SlideShow-item {
min-width: 100%;
}
.SlideShow-item>img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
.SlideShow-btn {
position: absolute;
top: 0;
z-index: 1;
width: 50px;
height: 100%;
background: rgba(255, 255, 255, 0.5);
opacity: 0.5;
border: 0;
cursor: pointer;
}
.SlideShow-btn:hover {
opacity: 1;
}
.SlideShow-btn.next {
right: 0px;
}
<div class="SlideShow">
<div class="SlideShow-slides">
<div class="SlideShow-item"><img src="http://placehold.it/600x400/0bf?text=A" alt=""></div>
<div class="SlideShow-item"><img src="http://placehold.it/600x400/fb0?text=B" alt=""></div>
<div class="SlideShow-item"><img src="http://placehold.it/600x400/0fb?text=C" alt=""></div>
</div>
<button type="button" class="SlideShow-btn prev"></button>
<button type="button" class="SlideShow-btn next"></button>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
What you need to do it to clear the interval in the button clicks and start interval again.
function resetInterval(){ //add this method which wil reset the timer
window.clearInterval(looper); //clear current interval
looper = setInterval(autoSlide, 5000); //start auto slide again.
}
function autoSlide(){ //move this to a function from being anonymous
// remove and add class active
$('.active').removeClass('active').next().addClass('active');
// animation expression
$('.active').animate({
'left': '-=' + (slideWidth) + 'px'
}, 500);
$('.active').siblings().animate({
'left': '-=' + (slideWidth) + 'px'
}, 500);
// return to first slide after the last one
if ($('.active').length === 0) {
$('#slide1').addClass('active');
$('.slides').animate({
'left': 0
}, 500);
}
}
and
$('.control_left').on('click', function () {
resetInterval(); //reset it
....
$('.control_right').on('click', function () {
resetInterval(); //reset it
....
Demo