Jquery horizontal slide based on div width - javascript

I have jquery script where you can click a left and right button and it will scroll horizontally to show more content.
The content that needs to be scrolled are in a div with a width of 1296px, but i want to set my jquery code to automatically get the width of the div and when you press on one of the left or right scroll button it will scroll exactly 1296px.
I want to do it this way because I need to later on optimize the design for all screen size and this would be the easier way.
My code:
var $item2 = $('div.group'), //Cache your DOM selector
visible2 = 1, //Set the number of items that will be visible
index2 = 0, //Starting index
endIndex2 = ( $item.length ); //End index
$('#arrowR').click(function(){
index2++;
$item2.animate({'left':'-=1296px'});
});
$('#arrowL').click(function(){
if(index2 > 0){
index2--;
$item2.animate({'left':'+=18.5%'});
}
});

This Javascript should work:
var $item2 = $('div.group'), //Cache your DOM selector
visible2 = 1, //Set the number of items that will be visible
index2 = 0, //Starting index
endIndex2 = ( $item2.length ); //End index
var w = $("#group").width();
$('#arrowR').click(function(){
index2++;
$item2.animate({'left':'-=' + w + 'px'});
});
$('#arrowL').click(function(){
if(index2 > 0){
index2--;
$item2.animate({'left':'+=' + w + 'px'});
}
});
Check this fiddle. Basically we calculate the width initially to not do the same thing repeatedly and the reuse it whenever we need it.

Why not get the width of the visible container first, and then use that value later? Quick example:
var width = $('container').width();
And then during animations:
var left = $item2.css('left') + width;
$item.animate({'left',left});
As a note, innerWidth and outerWidth may be more beneficial than just width depending on how you've set everything up, so if values aren't quite right take a look at those documents.

I've created a fiddle that I think solves your problem:
http://jsfiddle.net/77bvnw3n/
What I did was to create another variable (called width) which on page load, dynamically gets the width of the container.
var width = $('.group-container').width(); //Container Width
This variable is also reset whenever the Next or Previous buttons are pressed (in case the window has been resized since the page loaded).
$('#arrowR').click(function(){
index2++;
//recheck container width
width = $('.group-container').width();
$item2.animate({'left':'-=' + width + 'px'});
});
Take a look and let me know if it helps.
Note: I replaced the 'Next' and 'Previous' images with coloured boxes in my Fiddle and I think you also had a typo in your code, should
endIndex2 = ( $item.length )
be changed to:
endIndex2 = ( $item2.length )

Related

jQuery each() function not working after if/else statement has been completed for both if and else outputs

I am using jQuery & javascript to switch the classes for images based on whether the viewport width is less than or greater than twice the width of the image.
I am using $(window).resize to detect when the widow is resized and then the each() function to iterate through all images of a certain class.
An if statement checks whether the width of the viewport is less than twice the width of the image and if so removes one class and adds another. The else statement does the reverse.
One page load it works fine for as many widow width changes as I do, until both the if and the else have been executed, then they stop working. Any suggestions would be greatly appreciated!
Thanks
Here's my code:
function updateViewportDimensions() {
var w = window,
d = document,
e = d.documentElement,
g = d.getElementsByTagName("body")[0],
x = w.innerWidth || e.clientWidth || g.clientWidth,
y = w.innerHeight || e.clientHeight || g.clientHeight;
return { width: x, height: y };
};
jQuery(window).resize(function() {
var viewport = updateViewportDimensions();
var viewport_width = viewport['width'];
console.log('Viewport width = ' + viewport_width);
jQuery(document).ready(function($) {
$('.alignright').each(function(i, obj){
// get the width of each image
var image_width = $(this).width();
// if the viewport width is less than twice the image width then switch the classes
if(viewport_width < (image_width * 2)) {
$(this).removeClass('alignright');
$(this).addClass('aligncenter');
console.log('Viewport is less than twice image width');
} else {
console.log('Viewport is more than twice image width');
$(this).addClass('alignright');
$(this).removeClass('aligncenter');
};
});
});
});
If I am reading this correctly, (this).removeClass('alignright'); is changing your dom. Because of this all the link to the class alignright is now new but your jquery is still looking for the instances that have been removed.
Update $('.alignright').each(function(i, obj){ to be one level higher than what is being altered.
if the code is
<div id="outer-wrapper">
<div class="alignright">
content
</div>
</div>
use $('#outer-wrapper .alignright').each(function(i, obj){

Detect when element on top of the screen

I have a task: on the page there are some specific blocks(div/sections, etc) with id and data-title. I need to detect when I scroll that one of these elements is on top of the screen and console.log its id and data-title. So, when the second element on the top I need second's element id and data-title in console, when third only third's data and until that element ends. How can I do that?
Here just an example of how it supposed to work, but now it detects when element is in view, but I need to detect when element is on top of the screen:
https://codepen.io/hamper/pen/NLWWjz?editors=0011
var titles = document.querySelectorAll('[data-title]');
$(window).scroll(function() {
$(titles).each(function () {
var $el = $(this),
id = "#" + $el.attr("id"),
elTopPosRelToWindow = $el.offset().top - $(window).scrollTop(),
elBottomPosRelToWindow = $el.offset().top - $(window).scrollTop() + $el.height(),
inView = ((elTopPosRelToWindow < $(window).height())
&& (elBottomPosRelToWindow > $(window).height()));
if(inView) {
console.log(this.id, this.dataset.title);
}
});
});
Check out the codepen https://codepen.io/anon/pen/bxGNjG?editors=0011
if(Math.abs($el.position().top - $(window).scrollTop()) < 5) {
console.log('On Top', Date.now())
}
Basically the logic is that find the difference between windows scroll position and the element. If value is less than a specific number, its at the top. I have set the value to 5. Depending on how accurate you want, you can increase or decrease the value. If you scroll fast, some scroll positions might be missed hence a range rather than a equals to in the conditional check

Efficiently Find Page Max Dimensions

I am currently running a script on a third-party page to determine the maximum dimensions of the page. At first, this may seem as if I could just use outerWidth() and outerHeight() on my parent wrapper, #base but the problem is that the page wrapper isn't sized from its children. So I might have a parent that is 0x0 and its child is 400x400 and a child inside of that which is 500x500. It seems they just allow overflow. I have tried some CSS tricks in attempt to force the parent #base to size itself correctly, but the children don't seem to drive this change and modifying their CSS causes actual alignment issues on the page. Additionally, there are many hidden items on the page that do not become visible until later or during page interaction so this further prevents me from just grabbing the outer dimensions of #base or something like that.
My current approach is to iterate through every single element on the page. I check to see where it is positioned and what its dimensions are. Based on those, I update my maximum dimensions. I also have to check for horizontal and vertical scrolling elements because those may be on the page too. If a wrapper is 500px wide and the child has a width of 1000px, but is scrolled, I wouldn't want that to affect my maximum dimensions. Anyways, this approach works but it's slow. Sometimes the page may have +15k elements. With these numbers, it takes 10 seconds on my machine. I might be able to optimize some of the conditional statements to use booleans instead of evaluating values, but I don't think this will make a significant difference. I'm hoping there is some process I'm completely overlooking. Below is my current code snippet and a demo showing how the page looks prior to running the code and after the code has been run.
Demo: https://p826ni.axshare.com/#g=1&p=without_code
$('#base *').not('script, style').each(function () {
currentElement = $(this);
// Initialize on first loop.
if (parentElementHorizontal === undefined && parentElementVertical === undefined) {
parentElementHorizontal = currentElement;
parentElementVertical = currentElement;
}
width = currentElement.outerWidth();
height = currentElement.outerHeight();
scrollWidthHidden = currentElement[0].scrollWidth;
scrollHeightHidden = currentElement[0].scrollHeight;
top = currentElement.offset().top;
left = currentElement.offset().left;
// Check if we're still within the parent containing horizontal-scrolling overflow.
if (!$.contains(parentElementHorizontal[0], currentElement[0])) {
hiddenWidth = false;
}
// Check if we're still within the parent containing vertical-scrolling overflow.
if (!$.contains(parentElementVertical[0], currentElement[0])) {
hiddenHeight = false;
}
// Check if we've found an element with horizontal-scrolling content.
if (!hiddenWidth) {
maxWidth = maxWidth < left + width ? left + width : maxWidth;
} else if (currentElement.width() > maxWidth) {
currentElement.addClass('redline-layer');
}
if (scrollWidthHidden > width && !hiddenWidth && width > 0) {
hiddenWidth = true;
parentElementHorizontal = currentElement;
}
// Check if we've found an element with vertical-scrolling content.
if (!hiddenHeight) {
maxHeight = maxHeight < top + height ? top + height : maxHeight;
} else if (currentElement.height() > maxHeight) {
currentElement.addClass('redline-layer');
}
if (scrollHeightHidden > height && !hiddenHeight && height > 0) {
hiddenHeight = true;
parentElementVertical = currentElement;
}
});

jQuery infinite scrolling scrolling in fixed div

Background
I am trying to create an infinite scrolling table inside a fixed position div. The problem is that all the solutions I come across use the window height and document scrollTop to calculate if the user has scrolled to the bottom of the screen.
Problem
I have tried to create a jQuery plugin that can calculate if a user has scrolled to the bottom of a fixed div with overflow: scroll; set.
My approach has been to create a wrapper div (the div with a fixed position and overflow: scroll) that wraps the table, I also place another div at the bottom of the table. I then try calculate if the wrapper.scrollTop() is greater than the bottom div position.top every time the wrapper is scrolled. I then load the new records and append them to the table body.
$.fn.isScrolledTo = function () {
var element = $(this);
var bottom = element.find('.bottom');
$(element).scroll(function () {
if (element.scrollTop() >= bottom.position().top) {
var tableBody = element.find("tbody");
tableBody.append(tableBody.html());
}
});
};
$('.fixed').isScrolledTo();
See Example http://jsfiddle.net/leviputna/v4q3a/
Question
Clearly my current example is not correct. My question is how to I detect when a user has scrolled to the bottom of a fixed div with overflow:scroll set?
Using the bottom element is a bit clunky, I think. Instead, why not use the scrollHeight and height to test once the scrollable area has run out.
$.fn.isScrolledTo = function () {
var element = this,
tableBody = this.find("tbody");
element.scroll(function(){
if( element.scrollTop() >= element[0].scrollHeight-element.height()){
tableBody.append(tableBody.html());
}
});
};
$('.fixed').isScrolledTo();
EDIT (12/30/14):
A DRYer version of the plugin might be much more re-usable:
$.fn.whenScrolledToBottom = function (cback_fxn) {
this.on('scroll',this,function(){
if( ev.data.scrollTop() >= ev.data[0].scrollHeight - ev.data.height()){
return cback_fxn.apply(ev.data, arguments)
}
});
};
Plugin Usage:
var $fixed = $('.fixed'),
$tableBody = $fixed.find("tbody");
$fixed.whenScrolledToBottom(function(){
// Load more data..
$tableBody.append($tableBody.html());
});
I have modified your code to handle the scroll event with a timer threshold:
$.fn.isScrolledTo = function () {
var element = $(this);
var bottom = element.find('.bottom');
$(element).scroll(function(){
if (this.timer) clearTimeout(this.timer);
this.timer=setTimeout(function(){
if( element.scrollTop() >= bottom.position().top){
var tableBody = element.find("tbody");
tableBody.append(tableBody.html());
}
},300);
});
};
$('.fixed').isScrolledTo();
The issue you are having is that as you scroll, new scroll event is being generated. Your code might have other issues, but this is a start.

automated scrolling text in div's

i saw a stack question posted already:
[question]: < Text in div - automated scrolling with jQuery - jsFiddle inside >
My question adding to this is, is it possible to have the text in each paragraph or separated divs highlighted (boldness, background color, etc.) once they are in main view, whilst the p's or div's leaving/entering the slider box are faded?
So like the jsfiddle referenced, you have a div container with say 4,5,6,... div's or p's inside of it and one div or p is visible whilst the div or p above and below it, only half would be visible (faded), whilst the remaining overflow is hidden.
thanks.
If I understand you correctly, you're looking for an effect like this:
http://jsfiddle.net/2RRWS/
My code assumes an html structure like:
<div id="scrollContainer">
<p>Some text</p>
<p>More text</p>
...
</div>
And some CSS to set the width/height of the containing div as appropriate. Also it assumes some classes for "dimmed" and "highlighted" paragraphs.
There's probably a cleaner way to do this, but this is just what I cobbled together and it seems to work, so...
var $container = $("#scrollContainer"),
$ps = $container.find("p"),
containerHeight = $container.height(),
contentHeight = 0,
scrollTop = 0;
// figure out the height of the content
$ps.each(function() {
contentHeight += $(this).outerHeight();
});
// add some blank space at the beginning and end of the content so that it can
// scroll in from the bottom
$("<div></div>").css("height", 400).appendTo($container).clone().prependTo($container);
setInterval(function() {
if (paused)
return;
// if we've gone off the end start again
if (scrollTop > contentHeight + containerHeight)
scrollTop = 0;
// scroll up slightly
$container.scrollTop(scrollTop++);
$ps.removeClass("highlighted") // for each paragraph...
.addClass("dimmed") // dim it
.each(function() { // unless it is in view
var $this = $(this),
top = $this.position().top,
height = $this.height();
if (top > 0 && top + height < containerHeight)
$(this).addClass("highlighted").removeClass("dimmed");
});
}, 20);
$container.hover(function() {
paused = true;
}, function() {
paused = false;
});
EDIT: Updated to implement "pause" feature as per comment. http://jsfiddle.net/2RRWS/8/

Categories