I have a click slide that goes back and forward through the images,
But it doesnt scale or act responsive when on smaller window because obviously the width is set absolutely with pixels in the CSS and as the variable in my function.
If i change this I'm not sure how it'll work though as it slides back and forth the width of each img (607px)
Anyone got ideas?? Or a better way to do this??
HTML:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="slider">
<ul class="slides">
<li class="slide"><img src="images/banner1.jpg" class="img-responsive"></li>
<li class="slide"><img src="images/banner2.jpg" class="img-responsive"></li>
<li class="slide"><img src="images/banner3.jpg" class="img-responsive"></li>
<li class="slide"><img src="images/banner1.jpg" class="img-responsive"></li>
</ul>
</div>
CSS:
#slider {
width: 607px;
height: 248px;
overflow: hidden;
}
#slider .slides {
display: block;
width: 6000px;
height: 248px;
margin: 0px;
padding: 0px;
}
#slider .slide {
float: left;
list-style-type: none;
}
JS:
(function() {
var width = 607;
var slideSpeed = 300;
var currentSlide = 1;
var $slider = $('#slider');
var $slideContainer = $slider.find('.slides');
var $slides = $slideContainer.find('.slide');
var totalLength = $slides.length;
$('#button-next').on('click', function(){
$slideContainer.animate({'margin-left': '-='+width}, slideSpeed, function(){
currentSlide++;
if(currentSlide === $slides.length) {
currentSlide = 1;
$slideContainer.css('margin-left', '0');
}
});
});
$('#button-prev').on('click', function(){
if(currentSlide === 1) {
var pos = -1 * (width * ($slides.length -1));
$slideContainer.css('margin-left', pos);
$slideContainer.animate({'margin-left': '+='+width}, slideSpeed);
currentSlide = $slides.length - 1;
} else {
$slideContainer.animate({'margin-left': '+='+width}, slideSpeed);
currentSlide--;
}
});
});
In order to make the slider you have posted responsive you will need to set your fixed dimensions in your CSS to fluid width.
Like this:
.slider {
position: relative;
padding: 10px;
}
.slider-frame {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
white-space: nowrap;
}
.slide {
width: 100%;
display: inline-block;
}
.control {
width: 49%;
}
A wrote a very simple demo slider that hardly has any functionality just to serve the purpose of this explanation:
http://codepen.io/nicholasabrams/pen/aOLoYM
Resize your screen. The slides stay the width of the screen because the .slide and .slider are both set to 100% of the screens width.
Dont forget to add your own functionality for next and prev that adjusts each slide progression distance according to the width of the slides in the slider.
Also see here:
How to make a image slider responsive?
And this is a good tutorial with somewhat quality code used. The slide comes out usable as well!
http://www.barrelny.com/blog/building-a-jquery-slideshow-plugin-from-scratch/
Hope this helps!
UPDATE:
Since the OP stated that the issue is with the js I dug up a simple slider I wrote a while back, here is the javascript/jQuery:
$(function(){
$.fn.someCustomSlider = function (autoplay, velocity){
var sliderProps = [
// props n methods, accessible through data-slider-* attributes
{
settings : {
invokeBecause : $('[data-widget~="slider"]'),
autoplay : autoplay,
speed : velocity,
},
bindings : {
slideRail : $('[data-function~="slide-rail"]'),
nextButton : $('[data-function~="next"]'),
prevButton : $('[data-function~="prev"]'),
playButton : $('[data-function~="play"]'),
pauseButton : $('[data-function~="pause"]'),
stopButton : $('[data-function~="stop"]')
// attach this functionality to the DOM
},
methods : {
slideNext : function(){ slideRail.animate({left: '-=100%'}, velocity) },
slidePrev : function(){ slideRail.animate({left: '+=100%'}, velocity) },
slideRestart : function(){ slideRail.animate({left: '0%'}, velocity) },
pause : function(){ window.sliderTimer = setInterval(slideNext, velocity) }
}
}
]
$.each(sliderProps, function(){
// iterate through all of the slider objects properties
window.SliderProps = this;
// set slider props to be accessible to the global scope
});
// slider props stored as vars
var slideRail = SliderProps.bindings.slideRail;
var play = SliderProps.bindings.playButton;
var next = SliderProps.bindings.nextButton;
var prev = SliderProps.bindings.prevButton;
var pause = SliderProps.bindings.pauseButton;
var stop = SliderProps.bindings.stopButton;
var i = 0;
function slideNext(){
var slideNext = SliderProps.methods.slideNext();
}
function slidePrev(){
var slidePrev = SliderProps.methods.slidePrev();
}
function slideStop(){
/*slideRail.stop(); */
window.clearInterval( sliderTimer )
}
function slideRestart(){
var slidePrev = SliderProps.methods.slideRestart();
slideRail.stop();
window.clearInterval( sliderTimer )
}
function autoPlay(){
SliderProps.methods.pause()
}
// elemen -> event delegation -> function()
next.click(slideNext)
prev.click(slidePrev)
stop.click(slideRestart)
pause.click(slideStop)
play.click(autoPlay)
} // close function slider()
someCustomSlider(true, 1000);
});
http://codepen.io/anon/pen/eytrh
This was a basic version that I eventually extended but for simplicity sake, this should be just perfect I imagine.
When working with responsive design, thinking in terms of pixels is a bad practice.
Give your slider and each slide a width of 100vw instead of 607px. That would make it equivalent to one "viewport width". In your JavaScript try modifying the width variable to be the string 100vw as well. Make sure to include the unit.
For more information on CSS units refer here.
Related
I'm newbie of Javascript and Jquery.
I am learning img animation and I have a question.
If I want to move the image from bottom left to the top right in window. Is there any better way than my code?
My code doesn't' work then I expected.
here is my code
$(document).ready(function () {
function startMoving() {
var img = $("#imageId");
var imgWidth = img.width();
var imgHeight = img.height();
var screenWidth = $(window).innerWeight();
var screenHeight = $(window).innerHeight();
var c = Math.sqrt((screenWidth*screenWidth+screenHeight*screenWidth));
var movement = c/10 // This is for the step of movement
var zScale = (screenWidth+screenHeight)/2;
var imgZScale = (imgHeight+imgWidth)/2;
console.log(zScale);
console.log(imgHeight);
img.animate({
"left": "+="+movement,
"top": "-="+movement
},"slow");
}
setInterval(function(){
startMoving();
},1000)
});
If the image at the corner how can I restart image movement again from bottom left?
Thank you in advance!
You can simplify things using CSS transitions instead of JQuery animate(). This feature is easy to manage and with less code.
I've just created an initial CSS state and a final stage (.end), using jQuery to toggle the class to switch from initial/final position.
$(document).ready(function () {
setInterval(function(){
$("#imageId").toggleClass("end");
},2000);
});
img{
position: absolute;
width: 5vw;
height: 5vw;
top: 95vh;
left: 0;
transition: linear 1s;
}
img.end{
top: 0;
left: 95vw;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<img id="imageId" class="start" width="48" height="48">
I am working on a project where I need to set the height dynamically, means when the page loads the height must be set to itself and it's a responsive box, so when the browser window resizes the height increases but I am unable to fix it. I shared the script below. It's not something to calculate with window height or else, it should set and change the height based on window resizes. Any help?
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
var itemHeight = $('.item').height();
$('.item').each(function() {
$(this).css({
height: itemHeight + 'px'
});
});
$(window).on('resize', function(event) {
$('.item').each(function() {
$(this).css({
height: itemHeight + 'px'
});
});
});
Please see the jsfiddle:
https://jsfiddle.net/rj1xy1ue/
I will suggest you to use % instead of px. px will fix the value, but % will automatically compute the values based on the available viewport.
var itemHeight = 20; //Sample value
$('.item').each(function () {
$(this).css({
height: itemHeight + '%'
});
});
Simply, find the perfect value of itemHeight which is ideal for your case and then assign it. No need for extra resize event handler.
In your current code, in resize event you are assigning same value again which doesn't make any difference to the dimension. Hence you are not able to see the difference on resize.
Try this:
var itemHeight = $('.item').height();
function resizer() {
$('.item').each(function () {
$(this).css({
height: itemHeight + 'px'
});
});
}
$(window).on('resize', function (event) {
itemHeight = 350 //any different value
resizer();
});
Sample Demo: http://jsfiddle.net/lotusgodkk/GCu2D/822/
Note: Make sure you change the value of itemHeight in resize handler
What you are describing is called Responsive design.
A key idea in responsive design is to use percentages in place of px.
See these references:
WebDesignerWall on Responsive Design
CSS-Tricks question
for some ideas.
Note that using percentages for height is not as important as for width. You might also want to check out
Responsive Layouts with flexbox
On the jQuery side, you can use something like this:
var win = $(window);
$(function() {
win_size_recalc();
$(window).on('resize', function(){
win_size_recalc();
});
}); //end document.ready
function win_size_recalc(){
ww = win.width();
//EXAMPLE OF USE:
if (ww <= 550){
$('#header').css({'height':'50px'});
$('nav').css({'height':'55px'});
$('#headerstuff').css({'width':'98%'});
}else if (ww <= 650){
$('#headerstuff').css({'width':'98%'});
$('nav').css({'width':'98%'});
}else if (ww <= 770){
$('#headerstuff').css({'width':'90%'});
$('nav').css({'width':'90%'});
}else if (ww <= 850){
$('#headerstuff').css({'width':'90%'});
$('nav').css({'width':'90%'});
}else if (ww <= 900){
//etc etc
}
You might also want to check out CSS media queries, which is the CSS way of doing what we just did above using jQuery:
https://css-tricks.com/css-media-queries/
https://css-tricks.com/snippets/css/media-queries-for-standard-devices/
and more
I am not sure if I am able to understand your question correctly but I'll give a try based on what I could understand anyway.
You want the .item objects to resize on resize event of window object such that you want to start with whatever .height() these .item objects have, and then scale proportionally to the window height on resize.
If this is what you wanted, the solution is pretty simple. You calculate the difference in .height() of window object, and you add (or remove) that difference to the default .height() of .item objects.
Take a look at this jsFiddle and resize the height of the result panel to observe the difference in height of the .item objects. And tell me if this is what you were expecting the result to be.
The JavaScript used in the example is as below:
var items = $('.item');
var windowObject = $(window);
var defaultWinHeight = windowObject.height();
var defaultItemHeight = items.height();
items.css({ height: defaultItemHeight + 'px' });
windowObject.on('resize', function (event) {
var currWinHeight = windowObject.height();
var difference = currWinHeight - defaultWinHeight;
var itemHeight = defaultItemHeight + difference;
items.css({ height: itemHeight + 'px' });
});
Apologies if this is not what you were looking for. Hope it helps in some way though.
Update #1:
And here is another resulting jsFiddle of the same experiment but involving calculating percentages.
JavaScript:
var items = $('.item');
var windowObject = $(window);
var defaultWinHeight = windowObject.height();
var defaultItemHeight = items.height();
items.css({ height: defaultItemHeight + 'px' });
windowObject.on('resize', function (event) {
var currWinHeight = windowObject.height();
var currWinPercent = (currWinHeight/defaultWinHeight)*100;
var itemHeight = (currWinPercent/100)*defaultItemHeight;
items.css({ height: itemHeight + 'px' });
});
As others have noted, the main problem is you're only calculating itemHeight once. This fiddle shows a more modern way to use jQuery to achieve your goals (use on instead of bind):
http://jsfiddle.net/sean9999/7j4sz3wv/6/
$(function(){
"use strict";
var resizeBoxes = function(){
var padding = 25;
var parentHeight = $('body').height() - padding;
$('#debug').html( 'parent height = ' + parentHeight );
$('.item').css('height',parentHeight);
};
$(window).on('resize',resizeBoxes);
resizeBoxes();
});
body {
position: absolute;
height: 100%;
width: 100%;
margin: 0;
padding: 0;
background-color: #FED;
}
#debug {
width: 50%;
float: right;
height: 100%;
margin-top: 25%;
font-weight: bold;
color: navy;
}
.item {
min-width: 25px;
border: 2px solid blue;
background-color: silver;
min-height: 100px;
float: left;
margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div id="debug"></div>
In my layout I have created the following jsfiddle-hosted resizable sticky footer. However, on the resize it overlaps the content. Is there anyway to make it responsive on all browsers?
http://jsfiddle.net/9aLc0mg2/
$(function () {
$('.footer').resizable({
handles: 'n, s'
}).bind('resize', function(){
$(this).css("top", "auto");
});
});
<div class="footer">
<p> footer content here </p>
</div>
CSS:
.footer {
color: #ffffff;
position: fixed !important;
bottom: 0;
width: 100%;
/* Set the fixed height of the footer here */
z-index: 1000;
height: 60px;
background-color: #333333;
}
Does it need to be resizable back down ? Triedd the disable method but it does not work for some reason. Got it to stop at the content above it though. Is this any good ?
JS FIDDLE
$(function () {
var topheight = $('#top').height();
var topoffset = $("#top").offset();
var topbottom = topoffset.top + topheight;
$('.footer').resizable({
handles: 'n, s'
}).bind('resize', function(){
$(this).css("top","auto");
var footeroffset = $(this).offset();
var footerheight = $(this).height();
var footerBottom= footeroffset.top + footerheight;
$("#res").html(topbottom+" "+footeroffset.top);
if(topbottom + 50 >= footeroffset.top){
$('#res').html("should disable");
$('.footer').resizable("destroy");
}
});
});
I was able after digging more in research to solve it by adding the following function
var bumpIt = function() {
$('body').css('margin-bottom', $('.footer').height());
},
didResize = false;
bumpIt();
$(window).resize(function() {
didResize = true;
});
setInterval(function() {
if(didResize) {
didResize = false;
bumpIt();
}
}, 250);
http://jsfiddle.net/v71tsx97/
Also could be done this way: http://jsfiddle.net/mnuxohoj/
But still any other methods with better performance are welcome.
Trying create an image carousel whose speed relies upon mouse positioning (i.e. if the mouse is close to the edge of the screen it moves fast, directly in the middle it doesn't move etc.) My issue right now being that the image carousel doesn't move at all. Could be a variety of reasons for it not working, but I am not really sure as to why it isn't working or even if this is a 'good' carousel algorithm.
Created a speed function which I am positive needs work, but I will only be able to know that once I see the image carousel actually moving.
Fiddle
JQuery
$(document).ready(function(){
$('.carousel').mousemove(function(e) {
var mpos = e.pageX;
var speed = $(this).getSpeed(mpos);
var dir = $(this).getDir(mpos);
var $ul = $(this).children('ul');
var cwidth = $ul.width();
$('#speed').html(speed);
if(speed != 0) {
if(dir == -1){
$ul.animate({
left: 0
}, speed, 'linear');
}
if(dir == 1){
$ul.animate({
left: -cwidth
}, speed, 'linear');
}
}
});
});
$.fn.getSpeed = function(mpos){
var width = $(this).width();
var center = width/2;
var ps = (mpos-center)/10;
var speed = ps * ps - (width % 100);
if(speed >= 0) return speed;
else return 0;
};
$.fn.getDir = function(mpos){
var width = $(this).width();
var center = width/2;
if(mpos > center) return 1;
else return -1;
};
HTML
<div class="carousel">
<ul>
<li><img src="http://placehold.it/200x200"/></li>
<li><img src="http://placehold.it/200x200"/></li>
.
.
.
<li><img src="http://placehold.it/200x200"/></li>
</ul>
</div>
<div id="speed"></div>
You have to fix your code to actually do what you want, but the main problem of not animating is fixed if you add the following css:
.carousel ul {
position:relative;
left:0px;
always check the documentation if you run into trouble:
http://api.jquery.com/animate/
There are several problems you have here.
First problem you got is, that position "relative" or "absolute" are missing on the ul.
carousel {
position: relative;
width: 100%;
overflow: hidden;
height: 200px;
}
.carousel ul {
position: absolute;
display: block;
list-style: none;
white-space: nowrap;
}
Then you need to stop your animations before starting another:
$ul.stop().animate
But the biggest problem is, that your "speed" is not a real speed at all.
If your speed is "100", it is very fast. This means that the animation will be done within 100 milliseconds! Thats so fast that you cannot see the animation.
So if you are moving your mouse near to the middle of you gallery it's moving fast and on the edges outside it's moving slow.
You could fix your speed by subtracting your actual mpos-value from a maximum-speed:
var speed = ps * ps - (width % 100);
// SPEED FIX
speed = 5000 - (speed * 2);
Here is the fiddle:
http://jsfiddle.net/56rwR/1/
BUT!! this is buggy as hell because is has not a real speed.. only this animation time which is proportional to the ul-width..
I would recommend you to use a script like this here:
http://bxslider.com/examples/ticker
and write an hover event which increases/decreases the speed.
http://jsfiddle.net/2RE3f/6/embedded/result/
I'm trying to make a responsive js slider and I can't seem to figure out the break point glitch when going between media queries.
For instance, if you look at my jsFiddle, and set your window to the iPad size (1024px wide for screen size), and then pull out to 1200px wide, the slider breaks and there's a margin being applied to the new grid size (highlighted in red), off-setting the slider. However, if you pull back to the iPad size, then it then slider doesn't apply a margin to the right off-setting it and works normally. If load up the grid at the 1200px width, the slider works normal, but it when you size down to the iPad size, it adds a margin to the right when you hit the right arrow.
For some reason, I can't figure out how and why its adding this padded margin to the grid.
You'll have to use arrow keys (right left, to navigate between two grid galleries). There's more code in the jsFiddle but it doesn't apply to the rwd.
This is the css
#media screen (max-width: 1400px) {
#portfolio img {
height: 400px;
width: 400px;
}
#slider ul li {
width: 1200px;
}
}
#media screen and (max-width: 1030px) {
.uni_con {
width: 1024px
}
.shell {
width: 1024px;
}
.container {
width: 1024px;
}
#portfolio img {
height: 512px;
width: 512px;
}
#slider ul li {
width: 1024px;
}
#slider .caption {
width: 512px;
height: 512px;
}
#slider .caption::before {
width: 514px;
height: 514px;
line-height: 508px;
}
#slider .caption::after {
width: 512px;
}
#slider .caption:hover::before {
width: 512px;
height: 512px;
}
#slider .caption:hover::after {
width: 512px;
}
}
The Jquery
jQuery(function ($) {
var $sl = $('#slider'),
$ul = $('ul', $sl),
$li = $('li', $ul),
slideCount = $li.length,
c = 0, // current
slideWidth = $li.width(),
slideHeight = $li.height(),
sliderUlWidth = slideCount * slideWidth;
$sl.css({
width: slideWidth,
height: slideHeight
});
$ul.css({
width: sliderUlWidth
});
function move() {
if (c == slideCount) {
c = slideCount - 1;
// fade out #next btn
$('#next').stop().fadeTo(200, 0.5);
}
if (c == slideCount - 1) {
$('#next').stop().fadeTo(200, 0.5);
$('#back').fadeTo(200, 1);
} else if (c < 0) {
c = 0;
$('#back').stop().fadeTo(200, 0.5);
} else {
$('#next').fadeTo(200, 1);
$('#back').fadeTo(200, 0.5);
}
$ul.stop().animate({
left: -c * slideWidth
}, 500);
}
$('#back, #next').click(function () {
return move(this.id == 'next' ? c++ : c--);
});
$(document).keydown(function (e) {
var k = e.which;
if (k == 39 || k == 37) {
e.preventDefault();
return move(k == 39 ? c++ : c--);
}
});
});
On the second LI (using right key), this margin keeps getting added and pushing the grid off from being inline with the container.
Thanks.
seems to be I have found the solution. The reason you were seeing that strange red margin at the right side was that you were controlling the width and height of the slider ul element using your javascript code. On window resize or a change in screen resolution, the media queries were changing other elements sizes, but this (ul sider width and height) remained the same.
I added the code to handle this problem, with comments, here is the jSFiddle:
http://jsfiddle.net/2RE3f/12/embedded/result/
And here is the updated JS Code:
$(document).ready(function(e) {
jQuery(function ($) {
var $sl = $('#slider'),
$ul = $('ul', $sl),
$li = $('li', $ul),
slideCount = $li.length,
c = 0; // current
var slideWidth; // global so can be used in move()
// wrap the slider width and height settings in a function
function slider_fit()
{
slideWidth = $li.width(),
slideHeight = $li.height(),
sliderUlWidth = slideCount * slideWidth;
$ul.css({
width: sliderUlWidth
});
$sl.css({
width: slideWidth,
height: slideHeight
});
}
slider_fit(); // call slider_fit on window load also
// below is the function to make sure window resizing has been done
$(window).resize(function() {
if(this.resizeTO) clearTimeout(this.resizeTO);
this.resizeTO = setTimeout(function() {
$(this).trigger('resizeEnd');
}, 250);
});
// once window is resized and media queries (if any) have been applied
// we can fit our slider elements to this new size
$(window).bind('resizeEnd', function() {
slider_fit(); // fit slider widths and heights due to screen size change
move(); // make adjustments to the left margins of ul
});
function move() {
//alert(slideWidth);
if (c == slideCount) {
c = slideCount - 1;
// fade out #next btn
$('#next').stop().fadeTo(200, 0.5);
}
if (c == slideCount - 1) {
$('#next').stop().fadeTo(200, 0.5);
$('#back').fadeTo(200, 1);
} else if (c < 0) {
c = 0;
$('#back').stop().fadeTo(200, 0.5);
} else {
$('#next').fadeTo(200, 1);
$('#back').fadeTo(200, 0.5);
}
$ul.stop().animate({
left: -c * slideWidth
}, 500);
}
$('#back, #next').click(function () {
return move(this.id == 'next' ? c++ : c--);
});
$(document).keydown(function (e) {
var k = e.which;
if (k == 39 || k == 37) {
e.preventDefault();
return move(k == 39 ? c++ : c--);
}
});
});
});
I hope this helps :)
I think I got it! There was a some weird styles being applied to the #slider.
#slider {
overflow: hidden;
position: relative;
margin: 0 auto;
}
The overflow:hidden; was cutting off the image and the margin:0 auto; was pushing the images across.
I think these styles were being added by the jquery and inherited from #portfolio.
Solution was adding this to the css:
#slider { /* ADDED SOLUTION*/
margin:0 !important;
overflow:visible !important;
}
View it here: http://jsfiddle.net/2RE3f/10/
Test the solution here: http://jsfiddle.net/2RE3f/10/show/light/# using: View Port Resizer Bookmarklet (Give it a google cause I can't post more than two links)
This will let you test the sizes for all devices using your browser.
You still have a problem where a thin gap is applied in between the images and on the top or bottom on some width and when you hover over some images.. Not sure what is going on there but it is minor.