Getting SmoothDivScroll to start at the center of the scrollable area - javascript

I'm trying to get jQuery plugin SmoothDivScroll (http://www.smoothdivscroll.com/) to start at the center of its contained content so there are scrollbars to the left and right on load. I'm aware that there's a startAtElementId option, but this doesn't allow me to start at the center.
I've tried calculating the centerpoint and applying it to the appropriate elements, but the left scroll always stops before it's expected to and the right elements float underneath.
Tried using this Js with no luck:
$("div#scroller").smoothDivScroll();
var halfWayDoc = $(document).width() / 2;
var halfWayScrollArea = $("#scroller .scrollableArea").width() /2;
var halfWay = halfWayDoc - halfWayScrollArea;
var scrollArea = $("#scroller .scrollableArea").width();
var scrollAreaAdjust = scrollArea + halfWay;
$("#scroller .item:first-child").css("margin-left",halfWay);
$("#scroller .item:last-child").css("margin-right",halfWay);
$("#scroller .scrollableArea").width(scrollAreaAdjust);
HTML looks like this:
<div id="scroller">
<div class="scrollingHotSpotLeft"></div>
<div class="scrollingHotSpotRight"></div>
<div class="scrollWrapper">
<div class="scrollableArea">
<div class="item">
<img src="assets/images/detail/Erdem-A-W-11-B2-sml.jpg" alt="example"/>
</div>
...
<div class="item">
<img src="assets/images/detail/Erdem-A-W-11-B2-sml.jpg" alt="example"/>
</div>
</div>
</div>
</div>
Any help or pointers are appreciated.
Cheers,
Shaun

Here is the solution that I suggest :-)
// Element for Scroll
var scrollElement = $("div#scroller");
// Enable Smooth Div Scroll
scrollElement.smoothDivScroll();
// Find out Scrollable area's width
var halfWidth = $("div#scroller .scrollableArea").width()/2;
// Force scroller to move to half width :-)
scrollElement.data("scrollWrapper").scrollLeft(halfWidth);
I update the fiddle, so you can take a look at this update one:
http://jsfiddle.net/3A9Zy/
I hope this helps :-)

The basic sample in the site http://www.smoothdivscroll.com/index.html#quickdemo is having the functionality implemented. The animation starts from an image with ID "startAtMe"
$("div#makeMeScrollable").smoothDivScroll({ autoScroll: "onstart",
autoScrollDirection: "backandforth",
autoScrollStep: 1,
autoScrollInterval: 15,
startAtElementId: "startAtMe",
visibleHotSpots: "always" });
. Did you try by specifying an id to the element you want to start with and passing the startAtElementId: "startAtMe" to the smoothDivScroll function?

Related

Mouse move makes div move inverted smoothly

I'm trying to make my div move smoothly inverted with the "ease" effect.
When I hover over the div, I want the image to smoothly move away from the mouse, just like they did with the image of the two toys in the first section of toyfight.co's site.
I've inspected their code and wasn't able to find my answer.
Could any of you provide it?
I've managed to do having a slightly rough movement of the image with the code down below. Also a link to my project on Codepen. (More minimized here)
Answer
This plugin helped me achieve my goal
http://www.jqueryscript.net/animation/jQuery-Plugin-For-3D-Perspective-Transforms-On-Mousemove-LogosDistort.html
HTML
<div class="section-0">
<div class="phone-container" >
<div class="phone-front" id="layer-one"></div>
</div>
</div>
<section class="section-1 parallax parallax-1">
<div class="container" id="section-1">
<div class="text-block animation-element">
<h1>Gemaakt van het fijnste staal</h1>
<p>"The volks is the rare kind of phone that I can recommend without reservations."<br> — The Verge</p>
</div>
</div>
</section>
JQUERY
$.fn.smoothWheel = function () {
// var args = [].splice.call(arguments, 0);
var options = jQuery.extend({}, arguments[0]);
return this.each(function (index, elm) {
if(!('ontouchstart' in window)){
container = $(this);
container.bind("mousewheel", onWheel);
container.bind("DOMMouseScroll", onWheel);
currentY = targetY = 0;
minScrollTop = container.get(0).clientHeight - container.get(0).scrollHeight;
if(options.onRender){
onRenderCallback = options.onRender;
}
if(options.remove){
log("122","smoothWheel","remove", "");
running=false;
container.unbind("mousewheel", onWheel);
container.unbind("DOMMouseScroll", onWheel);
}else if(!running){
running=true;
animateLoop();
}
}
});
};
Try using .css() instead of .offset() on line 358.
So from:
$(target).offset({ top: y ,left : x });
to:
$(target).css({ top: y ,left : x });
The overall effect is a lot smoother. CodePen here.

How to check scroll position in front of div

I created one parent div that has scroll. It has children divs which have text content, I want to check if scroll is in front of one of the child divs.
I tried it by comparing top scroll position with
div.offset().top
but as I am scrolling down div will calculate only visible height from parent with offset top position and scroll will calculate it's top from starting of parent. I am checking scroll's position like so:
if(scrollPosition>div.offset().top && scrollPostion (div.offset.top+div.height) ) {//scroll present }
What is correct way of getting div's top position?
Blockquote
Thanks in advance.
You need to add the offsetTop of the parents elements.
var t = div.offsetTop;
var p = div;
while (p=p.offsetParent)
t += p.offsetTop;
suppose that two boxes and one has scroll named container and another is child named target:
<div id="container">
<div id="target"></div>
</div>
<script type="text/javascript">
var container = document.getElementById('container'),
target = document.getElementById('target');
if((container.scrollTop - target.offsetTop) > 0 && (container.scrollTop - target.offsetTop) < target.offsetHeight) {
console.log('in range');
}
</script>
target.offsetHeight is not contains margin.

Close and reopen HTML tags with jQuery

I'm pretty sure this isn't as easy as I wish, but looking for confirmation.
I want to replace an image with a closing div, the image, and the re-opened div.
Here is an example:
http://jsfiddle.net/fdCu5/1/
At the end of the day I want to take HTML that looks like this:
<div class="post">
<div class="constrained">
<p>Hello hello</p>
<img src="http://www.nicenicejpg.com/400/100">
<p>Some more text</p>
</div>
</div>
and make it look like this:
<div class="post">
<div class="constrained">
<p>Hello hello</p>
</div>
<img src="http://www.nicenicejpg.com/400/100">
<div class="constrained">
<p>Some more text</p>
</div>
</div>
Do I need to go up a level and work with it's parent?
http://jsfiddle.net/billymoon/fdCu5/4/
// get reference to the image
var img = $('img')
// get reference to the parent object
var parent = img.parent()
// clone and store parent (should have all same classes and attributes etc...)
var dolly = parent.clone()
// empty the clone
dolly.html("")
// move everything after the image into the clone
dolly.append(img.nextAll("*"))
// put the clone after the parent
parent.after(dolly)
// put the image after the parent (before the clone)
parent.after(img)
Advantage of keeping as objects when moving them round, as opposed to just copying as HTML, is that events should stay bound to the objects even after they are moved.
This method does not rely on prior knowledge of the outer container classes/attributes etc...
Try:
$('.constrained p').wrap('<div class="constrained" />').parent().unwrap();
jsFiddle example
The produces:
<div class="post">
<div class="constrained"><p>Hello hello</p></div>
<img src="http://www.nicenicejpg.com/400/100">
<div class="constrained"><p>Some more text</p></div>
</div>
Just to add another option, here's a merged solution of Billy Moon and j08691's answers. You can just modify the variables as needed to select the children you want to wrap - or you can hard-code it to condense your code.
var containerClass = '.constrained';
var childrenToWrap = '.constrained > *:not(img)';
var container = $(containerClass).clone().empty();
$(childrenToWrap).unwrap().wrap(container);
I figured out a solution that is pretty flexible:
/*
Wide Images
*/
$('img.size-wide').each(function(i,el){
// cache the element
var that = $(el);
// test to see if its a captioned image
if(that.parent().hasClass('wp-caption')) {
that = $(that.parent());
}
var parent = that.parent();
var parentHTML = parent[0].outerHTML;
var childHTML = that[0].outerHTML;
var newHTML = "</div>"; // close the .constrained div to break out
newHTML += childHTML;
newHTML += "<div class='constrained'>"; // open it back up again
parentHTML = parentHTML.replace(childHTML,newHTML);
parent.parent().html(parentHTML);
});

Scroll a container on initial load in an Angular app

I have a container which animates its scrollTop to the bottom whenever a new item is added. The markup looks something like this:
<div class="scrolly">
<div class="item" ng-repeat="item in items" ng-animate=" 'scroll-to-bottom' ">
{{item.value}}
</div>
</div>
This works great when adding new items, but on the initial page load, the container is scrolled to the top. I'd like to figure out the right way to have the scrollTop set to the bottom on initial page load.
Example jsFiddle: http://jsfiddle.net/bkad/JnwCP/
The trick is to add some delay when you populate the data like this :)
$timeout(function () {
for (var i = 0; i < 20; i++)
$scope.items.push({
value: i
})
}, 10);
Demo
I ended up using scrollGlue which implements this as a directive.

Dynamically positioning elements using jQuery

I am working om a menu bar, each menu bar item is an image, when user places mouse over menu item a div with submenu will appear.
I want to place div directly under the appropriate image item (no space, and div will hover above all elements), with right side alignment, meaning the right top corner of div should be under bottom right corner of image.
Because I can't and don't want to hard code position of divs, i want to do it dynamically.
For now I have this:
$('img').each(function(){
jQuery(this).mouseenter(function(){
var menuItem = $('#' + this.id + '_menu'); //get the needed div
var imgRight = this.offset() + this.width();
});
});
The offset() method has top and left properties, you need use them, example:
var imgRight = this.offset().left + this.width();
var imgTop = this.offset().top + this.height();
After that, you will have to give the absolute positioning to the DIVs to place them below the images:
menuItem.css({
position:'absolute',
top: imgTop,
left: imgLeft,
zIndex:5000
});
So your code becomes:
$('img').each(function(){
jQuery(this).mouseenter(function(){
var menuItem = $('#' + this.id + '_menu'); //get the needed div
var imgRight = this.offset().left + this.width();
var imgTop = this.offset().top + this.height();
menuItem.css({
position:'absolute',
top: imgTop,
left: imgLeft,
zIndex:5000
});
// now show the corresponding div
menuItem.show('slow');
});
});
More Info:
http://api.jquery.com/offset/
You shouldn't have to hard code or calculate the position of these items. Any of the following CSS rules should achieve your goal: position: relative; right: 0 or float: right:.
It'd be good to see some of your markup for additional testing. www.jsfiddle.net is a great resource for this.
There are 2 ways to do this: the correct-way or the cheat way...
The correct way: you need to get the top and client height of the actuating object - client heights no prob just call it - but the top means you must get the to of all the parent objects too - use this:
function J_pos(o)
{
var x,y;
y=o.offsetTop;
x=o.offsetLeft;
o=o.offsetParent;
while(o)
{
y+=o.offsetTop;
x+=o.offsetLeft;
o=o.offsetParent;
}
return [x,y];
};
Now the top and client height you do this:
<div style=top:"+(p[0]+obj.clientHeight)+";left:"+p[1]>
The cheat-way (not so dynamic - but quick):
put a tag like a <span> around the actuating (mouseover) object. Make it position-relative. Place a <div> inside it:
<div id="ABC" style="position:absolute;left:0;display:none">
Now on mouseover put document.getElementById("ABC").style.display="" and bottom:0 — boom baby dusted. Downside to this is you have to manually do it for each instance, but if you only have 3 or so well bingo.

Categories