I'm working on my portfolio and need help to #blind an element and change style property at bottom element at same time.
The idea is to exist a fixed space between the two elements, like this one EXAMPLE
If u see the example when you click, a bar appears and the space between two remains. Then if u click again the element hide and the space remains the same!!
"#contacts" -> element i want to blind
"#line" -> element i want change the top property
Im trying to resolve using jquery function called "blind":
$("#contacts").toggle("blind", {direction : "vertical"}, 500);
Then i get the top value of #line with if:
var line = $( "#line" );
var position = line.position();
var top = position.top;
if(top == value){
$("#line").animate({top:'100px'}, time);
} else { ... }
Please help!!
I'd do it without jQuery UI by using the top value and z-index
var contactTop = 85,
nextTop;
$(".oppen").click(function() {
nextTop = nextTop !== contactTop ? contactTop : 5;
$("#contacts").animate({top: nextTop}, 500);
.....
Demo
To stop the queuing you can apply the same technique on #line in addition to using jQuery's .stop
var contactTop = 85,
nextTop,
lineStart = 100,
lineEnd = 180,
lineTop = 100;
$(".oppen").click(function() {
nextTop = nextTop !== contactTop ? contactTop : 5;
$("#contacts").stop().animate({top: nextTop}, 500);
lineTop = lineTop !== lineStart ? lineStart : lineEnd;
$( "#line" ).stop().animate({top:lineTop}, 500);
});
Demo
Related
I want to have a custom scrollbar on my main div which has buttons to go to certain parts of the div, however anchor points don't seem to work when using the flexcroll plugin (I know i'm doing anchor points correctly because when I disable flexcroll on that div they work fine)
Is their any method I could use to set up the anchor points?
EDIT FOUND SOLUTION: On the buttons I want to click to go to the specific place in the document I can put onclick="Wrapper.fleXcroll.setScrollPos(false,0);"
I've used this function in the past. FYI, I don't know anything about flexcroll, so this is not tested with that:
var isInt = function(val) {
return (parseInt(val, 10) == val);
};
var scrollTo = function(node) {
var pNode = node.parentNode;
var offset = node.offsetTop - pNode.offsetTop;
var pHeight = pNode.clientHeight;
var height = node.clientHeight;
var scrollOffset = pNode.scrollTop;
var buffer = 10;
var scroll = null;
if (scrollOffset > offset) {
scroll = offset - buffer;
} else if (pHeight + scrollOffset < offset + height + buffer) {
scroll = offset + height + buffer - pHeight;
}
if (isInt(scroll)) {
pNode.scrollTop = scroll;
}
};
This is the pure JS version. (example)
Here is an example of a jQuery version, which animates the scroll event: jQuery version
I have created a parallax scroll, which seem to be working fine in firefox however in the chrome browser there's a slight jump on the body text when scrolling. click here scroll to the about section. I am not sure if t this is a css or JS issue.. below is a snippet i have incorporated into my parallax function
Does anyone know how i an fix this issue?
$(document).ready(function(){
// Cache the Window object
$window = $(window);
// Cache the Y offset and the speed of each sprite
$('[data-type]').each(function() {
$(this).data('offsetY', parseInt($(this).attr('data-offsetY')));
$(this).data('Xposition', $(this).attr('data-Xposition'));
$(this).data('speed', $(this).attr('data-speed'));
});
// For each element that has a data-type attribute
$('[data-type="background"]').each(function(){
// Store some variables based on where we are
var $self = $(this),
offsetCoords = $self.offset(),
topOffset = offsetCoords.top;
// When the window is scrolled...
$(window).scroll(function() {
// If this section is in view
if ( ($window.scrollTop() + $window.height()) > (topOffset) &&
( (topOffset + $self.height()) > $window.scrollTop() ) ) {
// Scroll the background at var speed
// the yPos is a negative value because we're scrolling it UP!
var yPos = -($window.scrollTop() / $self.data('speed'));
// If this element has a Y offset then add it on
if ($self.data('offsetY')) {
yPos += $self.data('offsetY');
}
// Put together our final background position
var coords = '50% '+ yPos + 'px';
// Move the background
$self.css({ backgroundPosition: coords });
$('[data-type="scroll-text"]', $self).each(function() {
var $text= $(this);
var pos = ($window.scrollTop()/10) * $text.data('speed');
var curP = $text.css('margin-top');
var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
if(is_chrome) {
$text.animate({
paddingTop: pos,
}, 200, 'linear', function() {
// Animation complete.
});
} else {
$text.css('padding-top', pos);
}
});
}; // in view
}); // window scroll
}); // each data-type
}); // document ready
Some suggestions:
1.) Use position: fixed to avoid any jitter, as you'll be taking the element out of the document flow. You can then position it using z-index.
2.) Cache as much as you can to ease processing time.
3.) Math.round may not be necessary, but try adding this CSS to your moving areas: -webkit-transform: translate3d(0,0,0); This will force hardware acceleration in Chrome, which may ease some of the jittering. (It looked smoother on my screen when I added this with Inspector, but it didn't get rid of the jumpiness with the scroll wheel.) Note: Don't do this on your entire document (e.g. body tag), as it might cause some issues with your current layout. (Your navigation bar didn't stick to the top of the window, for instance.)
4.) If you have any animations running as part of your parallax logic (tweening the margin into place or something along those lines), remove it - that would probably cause the jump you see.
Hope this helps. Best of luck.
I see the same jittering in FireFox and Chrome (Mac). Looking at your containers, one thing that's glaring at me is the pixel position that's being calculated/used.
Chrome: <div id="about-title" style="margin-top: 1562.3999999999999px;">
FireFox: <div id="about-title" style="margin-top: 1562.4px;">
Browsers aren't going to allow content to sit at 1/2 pixel, let alone 0.3999999 of a pixel. I think it's moving it, and trying to calculate whether to round up or round down. It jitters because it's calculating with every click of your mouse wheel.
Thus, I'd try adding Math.round() to your positions so that the containers are never being left in limbo.
Take a look at the code here: http://webdesigntutsplus.s3.amazonaws.com/tuts/338_parallax/src/index.html
Firebug some of the elements, and you'll see that their only fraction of a pixel is '0.5'. Most of them (the bulk) go to round number values.
You are going to have to change the way that the scrolling works (i.e. change how the spacing is computed), but this can be fixed by adding the position:fixed CSS element to the page elements that are scrolling. The problem is coming from the time that it takes for the JavaScript to process and then render.
For example, on your page you would set each of the <div> tags containing text to have a fixed position and then use the JavaScript/JQuery function to update the top: CSS element. This should make the page scroll smoothly.
Have you tried adding the preventdefault inside the scroll function?
$(window).scroll(function(e) {
e.preventDefault();
// rest of your code
}
In a previous question I created a fairly good parallax scrolling implementation. Jquery Parallax Scrolling effect - Multi directional You might find it useful.
Here's the JSFiddle http://jsfiddle.net/9R4hZ/40/ use the up/down arrows or scroll wheel.
Using padding and margin for the positioning are probably why you're experiencing rendering issues. While my code uses scroll or keyboard input for the effect you can loop the relavent portion and check the $moving variable until you reach the desired element on screen.
function parallaxScroll(scroll) {
// current moving object
var ml = $moving.position().left;
var mt = $moving.position().top;
var mw = $moving.width();
var mh = $moving.height();
// calc velocity
var fromTop = false;
var fromBottom = false;
var fromLeft = false;
var fromRight = false;
var vLeft = 0;
var vTop = 0;
if($moving.hasClass('from-top')) {
vTop = scroll;
fromTop = true;
} else if($moving.hasClass('from-bottom')) {
vTop = -scroll;
fromBottom = true;
} else if($moving.hasClass('from-left')) {
vLeft = scroll;
fromLeft = true;
} else if($moving.hasClass('from-right')) {
vLeft = -scroll;
fromRight = true;
}
// calc new position
var newLeft = ml + vLeft;
var newTop = mt + vTop;
// check bounds
var finished = false;
if(fromTop && (newTop > t || newTop + mh < t)) {
finished = true;
newTop = (scroll > 0 ? t : t - mh);
} else if(fromBottom && (newTop < t || newTop > h)) {
finished = true;
newTop = (scroll > 0 ? t : t + h);
} else if(fromLeft && (newLeft > l || newLeft + mw < l)) {
finished = true;
newLeft = (scroll > 0 ? l : l - mw);
} else if(fromRight && (newLeft < l || newLeft > w)) {
finished = true;
newLeft = (scroll > 0 ? l : l + w);
}
// set new position
$moving.css('left', newLeft);
$moving.css('top', newTop);
// if finished change moving object
if(finished) {
// get the next moving
if(scroll > 0) {
$moving = $moving.next('.parallax');
if($moving.length == 0)
$moving = $view.find('.parallax:last');
} else {
$moving = $moving.prev('.parallax');
if($moving.length == 0)
$moving = $view.find('.parallax:first');
}
}
// for debug
$('#direction').text(scroll + " " + l + "/" + t + " " + ml + "/" + mt + " " + finished + " " + $moving.text());
}
May not be related to your specifics, but I had a jumpy parallax scrolling problem, I was able to solve it adding the following CSS for the fixed portions of the page:
#supports (background-attachment: fixed)
{
.fixed-background
{
background-attachment: fixed;
}
}
Not sure of all the specifics, but found at Alternate Fixed & Scroll Backgrounds
Can I get some help with animating elements on a canvas? I would like to get the elements already drawn on the canvas and "move" them off the canvas and display the new elements. My functions are in javascript and work nicely. I would just like to add animation. TIA.
just have an event handler control the left of the style for that canvas's id and then specify a loop to have it change or move to the left/right based on time.
(function() {
var speed = 10,
movePic = function(moveBy) {
var el = document.getElementById("animationStyle"),
left = el.offsetLeft
if ((moveBy > 0 && left > 399) || (moveBy < 0 && left < 51)) {
clearTimeout(timer);
timer = setInterval(function () {
movePic(moveBy * -1);
}, speed);
}
el.style.left = left + moveBy + "px";
};
var timer = setInterval(function () {
movePic(3)
}, speed);
}());
This would move it back and forth, this is an example that should help you get started.
I want to calculate the total "height" of a div element considering the effect of collapsed margins because of child elements, that is, the total space that div element occupies in the document. I'm having a hard time thinking of the best algorithm / approach to do this.
Consider, for example, a div element with a margin-top of 10px and a height of 50px. This div element has a child <h2> element that has a margin-top of 20px. The div's margin will then collapse and the actual "height" of that div will be 70px. However, using jQuery methods, we are only able to get the height of the div without considering it's margins, or considering it's 10 pixel margin which would give us the wrong value:
$(elem).outerHeight() // 50
$(elem).outerHeight(true) // 60
To help illustrate my point, here is a jsfiddle I created with two examples.
My best guess at the moment is we have to iterate over all children of the div in some way and calculate the highest top and bottom margin.
According to what I understand from the W3C specification, we can skip this iteration for the top margin if the target div has a top-border-width or a top-padding. Ditto for the bottom margin.
Any help would be greatly appreciated. Thanks!
EDIT:
One (ugly) solution I thought about was wrapping the target div element in another div.
Then, we quickly add and remove a transparent borderTop and borderBottom to the wrapping div, measuring it's height in between. The borders will force the wrapping div's margin not to collapse with its children's margins. Something like this:
var collapsedHeight = function( target ) {
var $wrapper = $('<div />'),
$target = $(target);
$wrapper.insertAfter($target);
$target.appendTo($wrapper);
$wrapper.css({
borderTop: '1px solid transparent',
borderBottom: '1px solid transparent'
});
var result = $wrapper.outerHeight() - 2;
$target.insertAfter($wrapper);
$wrapper.remove();
return result;
};
I made a jsFiddle for it here.
Consider this hack:
$( elem ).wrap( '<div style="border:1px solid transparent;"></div>' ).parent().height()
The above expression returns 70 which is what you want, right?
So, the idea is to wrap your element in a DIV that has a transparent border set. This border will prevent the margins of your element to interfere with the margins of its previous and next sibling.
Once you get the height value, you can unwrap your element...
For a solution that doesn't involve DOM manipulation, you can achieve the same effect by adding padding to the element being measured and then removing it afterwards.
function getRealHeight(elementP) {
var
element = (elementP instanceof jQuery)? elementP : $(element),
padTop = parseInt(element.css('paddingTop')),
padBottom = parseInt(element.css('paddingBottom')),
offset,
height;
if (padTop == 0 || padBottom == 0) {
offset = 0;
if (padTop == 0) {
element.css('paddingTop', 1);
offset += 1;
}
if (padBottom == 0) {
element.css('paddingBottom', 1);
offset += 1;
}
height = (element.outerHeight(true) - offset);
if (padTop == 0) {
element.css('paddingTop', '');
}
if (padBottom == 0) {
element.css('paddingBottom', '');
}
} else {
height = element.outerHeight(true);
}
return height;
}
The bonus of this solution; you can sidestep the overhead of wrap/unwrap.
You can make it a jQuery plugin:
(function ($) {
$.fn.extend({
//plugin name - realHeight
realHeight: function (options) {
//Settings list and the default values
var defaults = {};
var options = $.extend(defaults, options);
function getRealHeight(elementP) {
var
element = (elementP instanceof jQuery) ? elementP : $(element),
padTop = parseInt(element.css('paddingTop')),
padBottom = parseInt(element.css('paddingBottom')),
offset,
height;
if (padTop == 0 || padBottom == 0) {
offset = 0;
if (padTop == 0) {
element.css('paddingTop', 1);
offset += 1;
}
if (padBottom == 0) {
element.css('paddingBottom', 1);
offset += 1;
}
height = (element.outerHeight(true) - offset);
if (padTop == 0) {
element.css('paddingTop', '');
}
if (padBottom == 0) {
element.css('paddingBottom', '');
}
} else {
height = element.outerHeight(true);
}
return height;
}
return getRealHeight($(this));
}
});
})(jQuery);
I'm wondering if there is a simple way to make use of JavaScript (probably jQuery too?) in order to make the contents of a fixed-height div element scroll infinitely up and down (top, bottom, top, bottom, etc) when the page loads and without any user input or manipulation?
Thanks ahead of time, any input is greatly appreciated as I am hardly mediocre with JavaScript.
With pure js you can do something like this:
var scroller = document.getElementById('scroller');
var delta = 15;
var lastSc;
//console.log(scroller.scrollTop, scrollHeight);
setInterval(function(){
var sc = scroller.scrollTop + delta;
scroller.scrollTop = sc;
if (scroller.scrollTop === lastSc){
delta = delta*(-1);
}
lastSc = scroller.scrollTop;
}, 10);
Here is demo
Edit: updated demo
Here is something I've just written, using jQuery:
var speed = 100; //smaller means faster
var offset = 5; //bigger means more text will be "scrolled" every time
function ScrollMyDiv() {
var myDiv = $("#MyDiv");
var direction = myDiv.attr("scroll_dir") || "";
var lastScrollTop = parseInt(myDiv.attr("last_scroll_top") || "0", 10);
if (direction.length === 0) {
myDiv.attr("scroll_dir", "down");
direction = "down";
}
var top = myDiv.scrollTop();
myDiv.attr("last_scroll_top", top + "")
if (direction === "down") {
if (top > 0 && lastScrollTop === top)
myDiv.attr("scroll_dir", "up");
top += offset;
} else {
if (top <= 0)
myDiv.attr("scroll_dir", "down");
top -= offset;
}
myDiv.scrollTop(top);
window.setTimeout(ScrollMyDiv, speed);
}
$(document).ready(function() {
ScrollMyDiv();
});
Live test case: http://jsfiddle.net/HmfNJ/1/
Basically, it will start by scrolling down (adding to the scrollTop) then when it identify it reached the bottom by seeing the scrollTop remains the same, it will change direction and start scroll up.
Thanks for the replies but I found my answer elsewhere. Here's what I ended up using: http://jsbin.com/onohan/3/edit#preview
It had a couple of small problems but I at least knew enough about basic JavaScript to fix them. Hopefully this will benefit someone in the future. :)
To get a smooth transition for scroll to bottom this is VanillaJS code that works well with me
var delta = 0.6, interval;
interval = setInterval(function(){
window.scrollBy(0, delta);
}, 20);
To clear the Interval you can run
clearInterval(interval);