Im trying to create a slider that uses an increment/decrement to move and then hide or show the buttons depending on the max number of images in the row. It uses a div within a div, with an overflow of hidden that should move until the max number of images is hit, this is when the arrow should be hidden so the person cannot just keep going into the white space created by the overflow. However, the hide/shows do not work and the person can just keep incrementing because the arrow is still visible even after the max number of images has been reached.
How do I get the left and right arrows to hide when they hit the respective numbers?
Edit: i know the .css is messed-up, i just want to get the arrows to hide/ show first, thanks
var pressCounter = 0;
var maxImgCounter = $('.carousel-image').length; // gain the max amount of images
var maxSlide = maxImgCounter - 4;// - the amount of images visible on the screen so it does notshow white space
if ( pressCounter < maxSlide){
$('#right').show();
}else{
$('#right').hide();
}
if (pressCounter > 0){
$('#left').show();
}else{
$('#left').hide();
}
/* Left arrow */
$('#left').click(function(){
$( '.slide' ).css({
"position": "relative",
"right": -280 * pressCounter
});
pressCounter--;
return pressCounter;
});
/* Right arrow */
$('#right').click(function(){
$( '.slide' ).css({
"position": "relative",
"right": 280 * pressCounter
});
pressCounter++;
return pressCounter;
});
if ( pressCounter < maxSlide){
$('#right').show();
}else{
$('#right').hide();
}
if (pressCounter > 0){
$('#left').show();
}else{
$('#left').hide();
}
Consider what happens when the value is less than maxslide and presscounter is greater than zero. Pretty much, this condition will always be true the way you have it written so both if statements are firing each time - one after the other. The result is that your left and right arrows will always be displayed - allowing users to keep clicking past the last slide.
Related
So what I want to happen is that when viewing the Span the text is normal but as you scroll down it starts moving until it looks like such:
Before the effect:
While the effect occurs:
The header is represented by spans for each letter. In the initial state, the top pixel value for each is 0. But the idea as mentioned is that that changes alongside the scroll value.
I wanted to keep track of the scroll position through JS and jQuery and then change the pixel value as needed. But that's what I have been having trouble with. Also making it smooth has been another issue.
Use the mathematical functions sine and cosine, for characters at even and odd indices respectively, as the graphs of the functions move up and down like waves. This will create a smooth effect:
cos(x) == 1 - sin(x), so in a sense, each character will be the "opposite" of the next one to create that scattered look:
function makeContainerWiggleOnScroll(container, speed = 0.01, distance = 4) {
let wiggle = function() {
// y-axis scroll value
var y = window.pageYOffset || document.body.scrollTop;
// make div pseudo-(position:fixed), because setting the position to fixed makes the letters overlap
container.style.marginTop = y + 'px';
for (var i = 0; i < container.children.length; i++) {
var span = container.children[i];
// margin-top = { amplitude of the sine/cosine function (to make it always positive) } + { the sine/cosine function (to make it move up and down }
// cos(x) = 1 - sin(x)
var trigFunc = i % 2 ? Math.cos : Math.sin;
span.style.marginTop = distance + distance * trigFunc(speed * y)/2 + 'px';
}
};
window.addEventListener('scroll', wiggle);
wiggle(); // init
}
makeContainerWiggleOnScroll(document.querySelector('h2'));
body {
height: 500px;
margin-top: 0;
}
span {
display: inline-block;
vertical-align: top;
}
<h2>
<span>H</span><span>e</span><span>a</span><span>d</span><span>e</span><span>r</span>
</h2>
Important styling note: the spans' display must be set to inline-block, so that margin-top works.
Something like this will be the core of your JS functionality:
window.addEventListener('scroll', function(e) {
var scrl = window.scrollY
// Changing the position of elements that we want to go up
document.querySelectorAll('.up').forEach(function(el){
el.style.top = - scrl/30 +'px';
});
// Changing the position of elements that we want to go down
document.querySelectorAll('.down').forEach(function(el){
el.style.top = scrl/30 +'px';
});
});
We're basically listening in on the scroll event, checking how much has the user scrolled and then act upon it by offsetting our spans (which i've classed as up & down)
JSBin Example
Something you can improve on yourself would be making sure that the letters wont go off the page when the user scrolls a lot.
You can do this with simple math calculation, taking in consideration the window's total height and using the current scrollY as a multiplier.
- As RokoC has pointed out there is room for performance improvements.Implement some debouncing or other kinds of limiters
I am having a few more issues with a script. I am trying to achieve a responsive slide out div script for a "meet the team" page. The way I see it working is that when the persons image is clicked, it slides out their bio. I am running into a few issues though.
1) Script works fine until you click the 3rd or 4th image in the row:
When the 3rd image is clicked, it slides out the div fine, but creates a blank space on the next row (i'm assuming it is pushing the image onto a new line but also adding a margin...)
When the 4th image is clicked, it is creating the bio outside of the container. The only way I can see a fix for this would be to have it slide the opposite way for every 4th item in a row. I can add a counter class to the divs dynamically using my CMS, just not sure how to reference this in the javascript.
2) I'm unsure how to make it work responsively. I am dropping the container from 1/4 to 1/2 on tablet and mobile. So I need to basically double the margin and size of the bio container. How can I declare this in the script?
Many thanks in advance for any help. Credit to Trim Kadrui who helped me with the script so far.
JS Fiddle:
http://jsfiddle.net/QrfzA/21/
Script code:
$(document).ready(function() {
$('.team-photo').click(function() {
var teamBio = $(this).next();
var nextBlock = $(this).parent().next();
if(teamBio.width() > 0){
teamBio.animate({width: 0, opacity: 0});
nextBlock.animate({marginLeft: '0%'});
}
else {
teamBio.css("display", "inline-block");
teamBio.animate({width: '100%', opacity: 100});
nextBlock.animate({marginLeft: '25%'});
}
});
});
$(document).ready(function() {
$('.team-photo').click(function() {
var teamBio = $(this).next();
var nextBlock = $(this).parent().next();
if(teamBio.width() > 0){
nextBlock.css("clear", "none");
teamBio.animate({width: 0, opacity: 0});
nextBlock.animate({marginLeft: '0%'});
}
else {
teamBio.css("display", "inline-block");
teamBio.animate({width: '100%', opacity: 100});
if(nextBlock.position().left>10) {
nextBlock.animate({marginLeft: '25%'});
if(!nextBlock.next().length || nextBlock.next().position().left<10) {
nextBlock.animate({marginLeft: '0'});
nextBlock.css("clear", "both");
}
}
}
});
});
if(nextBlock.position().left>10) does the trick,basically it checks if the there are more than 10 pixels to the left of the nextBlock and then applies the margin left property.
I've checked to see if nextBlock.position().left is greater than 10,you can set it to suite your needs.
EDIT: nextBlock.next().position().left<10 was also needed to be checked in case,the image is last but one in that line. CSS property clear:both was used to send the nextblock to the new line instead of using a margin.
Here is the updated JSFiddle.
I have this :
<div id="randomp" style="position:absolute;top:3px;left:3px;width:165px;height:29px;background:url(/logo2.png) no-repeat;background-size: 165px;"></div>
I want that the propierty "top" and "left" change every time you enter into the page. I mean that some times it appear on the right top corner, right bottom corner, left top corner and left bottom corner..
Here it is what i have tryied:
http://redzer.com.mx/tabla.html
I would probably start with the div styled as position:fixed and with display:none:
<div id="randomp" style="display:none;position:fixed;width:165px;height:29px;background:url(/logo2.png) no-repeat;background-size: 165px;"></div>
Then use jQuery to determine the position CSS to set and turn on visibility
$(document).ready(function() {
// get jQuery object for the div
var $randomp = $('#randomp');
// determine whether to show top or bottom, left or right
var top = Math.round(Math.random()); // generate 0 or 1 value
if (top === 1) {
$randomp.css('top', '3px');
} else {
$randomp.css('bottom', '3px');
}
var left = Math.round(Math.random());
if (left === 1) {
$randomp.css('left', '3px');
} else {
$randomp.css('right', '3px');
}
// show the div
$randomp.show();
});
Of course, you could also use server-side code to do this, but since you asked specifically about javascript/jquery in your tags, I suggested this solution.
I think i got exactly what you need.
EXAMPLE
With javascript i am generating random numbers for the top and left positioning of your image every time you visit the page.
Right now i set them up to get a random number between 0 and 100 but you can change that to whatever you want.
var random1 = Math.ceil(Math.random() * 100);
var random2 = Math.ceil(Math.random() * 100);
$(document).ready(function () {
$('#randomp').css('top', random1);
$('#randomp').css('left', random2);
});
I have 20 different divs.
5 class="icon",
5 class="rainskin",
4 class="schoolproject",
4 class="wallpaper", &
2 class="miscellaneous".
Each div has one div with class=".type". I have the header portion (about 27 pixels) of the .type div showing, but the rest of it is hidden. When someone hovers over the .type div, it slides up (by changing the margin-top: to 0px). When the mouse no longer hovers it, it goes back down to its original spot (margin-top: 110px).
Here's my fiddle. and java code.
(function ($) {
var original = [];
$('.type').each(function (i) {
original.push($(this).css('margin-top'));
});
$('.type').hover(function (e) {
$(this).stop().animate(
{"margin-top" : (
$(this).parent().outerHeight() -
$(this).outerHeight()
)},
250
);
}, function (i){
var i = $('.type').index($(this));
$(this).stop().animate(
{"margin-top": original[i]},
250
);
});
}(jQuery));
It works perfectly fine, UNLESS someone hovers over one .type div, and goes to hover over another .type div BEFORE the first .type div slides back down. THEN the .icon, .rainkin, .schoolproject, etc. div is moved down a bit. Go to my fiddle and check it out yourself. I don't know why it's doing it.
when you use "margin-top" you're actually messing with the flow of the css divs, so if you use "top" rather , the position just applies to that div, you also need to set .type as "relative". One other thing, your original position can just be "0", and the amount to pull up can be the size of your .type div.
Check this modification out:
(Test here: http://jsfiddle.net/gfefN/9/ )
(function ($) {
var original = [];
$('.type').each(function (i) {
original.push(0);
});
$('.type').hover(function (e) {
$(this).stop().animate(
{"top" : -(
$(this).height()
)},
250
);
}, function (i){
var i = $('.type').index($(this));
$(this).stop().animate(
{"top": original[i]},
250
);
});
}(jQuery));
How would I prevent a div from scrolling further left when the style 'left' of that div reached '0' or '0px'? Right now I am using the animate custom effect to scroll a div left and right to display hidden overflows but when the div reaches '0' or '0px' on style: left, I want the user to be prevented from scrolling further left where there is no content, just empty space. I currently have the following code which doesn't seem to be working the way I want:
$(document).ready(function(){
if ($("#ajax-matched-results").css('left') == '0' || '0px') {
$("#scrollLeft-results").click(function() {
$(".matched-results-items").animate({"left": "0px"}, "slow");
});
$("#scrollRight-results").click(function() {
$(".matched-results-items").animate({"left": "-=547px"}, "slow");
});
} else {
$("#scrollLeft-results").click(function() {
$(".matched-results-items").animate({"left": "+=547px"}, "slow");
});
$("#scrollRight-results").click(function() {
$(".matched-results-items").animate({"left": "-=547px"}, "slow");
});
}
});
Thanks for any help!
first of all, shouldn't the if statement be INSIDE the click event? I don't see how this would execute at all, or at most once.
also, your first if statement will always be true. what you want is
if ($("#ajax-matched-results").css('left') == '0' || $("#ajax-matched-results").css('left') == '0px')
also, i'm not 100% sure that the "-=547px" and such will work as expected either. do you want to increment them by that value every time it is clicked, or do you want to set them to that value. I'm going to assume you want to increment it every time.
Here is more or less what you should have:
$(function(){
// this actually eliminates the need for the above if statement
// assuming you only have one thing you're going to animate
var position = 0;
// move object right 547px regardless of current position
$('#scrollRight-results').click(function(){
// animate regardless?
// unless you're setting right side bounds as well
position += 547;
$('id').animate({'left': position}, 'slow');
});
// move object left 547px if not already at 0
$('#scrollLeft-results').click(function(){
if (position != 0){
position -= 547;
$('id').animate({'left': position}, 'slow');
}
});
})
I can almost guarantee you that this code will break if you keep clicking the button because you are not checking the animation so it will keep going as long as it isnt. so you should do something like:
if($("selector").is(":animated")){
return false;
}