I am creating a chat using Ajax requests and I'm trying to get messages div to scroll to the bottom without much luck.
I am wrapping everything in this div:
#scroll {
height:400px;
overflow:scroll;
}
Is there a way to keep it scrolled to the bottom by default using JS?
Is there a way to keep it scrolled to the bottom after an ajax request?
Here's what I use on my site:
var objDiv = document.getElementById("your_div");
objDiv.scrollTop = objDiv.scrollHeight;
This is much easier if you're using jQuery scrollTop:
$("#mydiv").scrollTop($("#mydiv")[0].scrollHeight);
Try the code below:
const scrollToBottom = (id) => {
const element = document.getElementById(id);
element.scrollTop = element.scrollHeight;
}
You can also use Jquery to make the scroll smooth:
const scrollSmoothlyToBottom = (id) => {
const element = $(`#${id}`);
element.animate({
scrollTop: element.prop("scrollHeight")
}, 500);
}
Here is the demo
Here's how it works:
Ref: scrollTop, scrollHeight, clientHeight
using jQuery animate:
$('#DebugContainer').stop().animate({
scrollTop: $('#DebugContainer')[0].scrollHeight
}, 800);
Newer method that works on all current browsers:
this.scrollIntoView(false);
var mydiv = $("#scroll");
mydiv.scrollTop(mydiv.prop("scrollHeight"));
Works from jQuery 1.6
https://api.jquery.com/scrollTop/
http://api.jquery.com/prop/
alternative solution
function scrollToBottom(element) {
element.scroll({ top: element.scrollHeight, behavior: 'smooth' });
}
smooth scroll with Javascript:
document.getElementById('messages').scrollIntoView({ behavior: 'smooth', block: 'end' });
If you don't want to rely on scrollHeight, the following code helps:
$('#scroll').scrollTop(1000000);
Java Script:
document.getElementById('messages').scrollIntoView(false);
Scrolls to the last line of the content present.
My Scenario: I had an list of string, in which I had to append a string given by a user and scroll to the end of the list automatically. I had fixed height of the display of the list, after which it should overflow.
I tried #Jeremy Ruten's answer, it worked, but it was scrolling to the (n-1)th element. If anybody is facing this type of issue, you can use setTimeOut() method workaround. You need to modify the code to below:
setTimeout(() => {
var objDiv = document.getElementById('div_id');
objDiv.scrollTop = objDiv.scrollHeight
}, 0)
Here is the StcakBlitz link I have created which shows the problem and its solution : https://stackblitz.com/edit/angular-ivy-x9esw8
If your project targets modern browsers, you can now use CSS Scroll Snap to control the scrolling behavior, such as keeping any dynamically generated element at the bottom.
.wrapper > div {
background-color: white;
border-radius: 5px;
padding: 5px 10px;
text-align: center;
font-family: system-ui, sans-serif;
}
.wrapper {
display: flex;
padding: 5px;
background-color: #ccc;
border-radius: 5px;
flex-direction: column;
gap: 5px;
margin: 10px;
max-height: 150px;
/* Control snap from here */
overflow-y: auto;
overscroll-behavior-y: contain;
scroll-snap-type: y mandatory;
}
.wrapper > div:last-child {
scroll-snap-align: start;
}
<div class="wrapper">
<div>01</div>
<div>02</div>
<div>03</div>
<div>04</div>
<div>05</div>
<div>06</div>
<div>07</div>
<div>08</div>
<div>09</div>
<div>10</div>
</div>
You can use the HTML DOM scrollIntoView Method like this:
var element = document.getElementById("scroll");
element.scrollIntoView();
Javascript or jquery:
var scroll = document.getElementById('messages');
scroll.scrollTop = scroll.scrollHeight;
scroll.animate({scrollTop: scroll.scrollHeight});
Css:
.messages
{
height: 100%;
overflow: auto;
}
Using jQuery, scrollTop is used to set the vertical position of scollbar for any given element. there is also a nice jquery scrollTo plugin used to scroll with animation and different options (demos)
var myDiv = $("#div_id").get(0);
myDiv.scrollTop = myDiv.scrollHeight;
if you want to use jQuery's animate method to add animation while scrolling down, check the following snippet:
var myDiv = $("#div_id").get(0);
myDiv.animate({
scrollTop: myDiv.scrollHeight
}, 500);
I have encountered the same problem, but with an additional constraint: I had no control over the code that appended new elements to the scroll container. None of the examples I found here allowed me to do just that. Here is the solution I ended up with .
It uses Mutation Observers (https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) which makes it usable only on modern browsers (though polyfills exist)
So basically the code does just that :
var scrollContainer = document.getElementById("myId");
// Define the Mutation Observer
var observer = new MutationObserver(function(mutations) {
// Compute sum of the heights of added Nodes
var newNodesHeight = mutations.reduce(function(sum, mutation) {
return sum + [].slice.call(mutation.addedNodes)
.map(function (node) { return node.scrollHeight || 0; })
.reduce(function(sum, height) {return sum + height});
}, 0);
// Scroll to bottom if it was already scrolled to bottom
if (scrollContainer.clientHeight + scrollContainer.scrollTop + newNodesHeight + 10 >= scrollContainer.scrollHeight) {
scrollContainer.scrollTop = scrollContainer.scrollHeight;
}
});
// Observe the DOM Element
observer.observe(scrollContainer, {childList: true});
I made a fiddle to demonstrate the concept :
https://jsfiddle.net/j17r4bnk/
Found this really helpful, thank you.
For the Angular 1.X folks out there:
angular.module('myApp').controller('myController', ['$scope', '$document',
function($scope, $document) {
var overflowScrollElement = $document[0].getElementById('your_overflow_scroll_div');
overflowScrollElement[0].scrollTop = overflowScrollElement[0].scrollHeight;
}
]);
Just because the wrapping in jQuery elements versus HTML DOM elements gets a little confusing with angular.
Also for a chat application, I found making this assignment after your chats were loaded to be useful, you also might need to slap on short timeout as well.
Like you, I'm building a chat app and want the most recent message to scroll into view. This ultimately worked well for me:
//get the div that contains all the messages
let div = document.getElementById('message-container');
//make the last element (a message) to scroll into view, smoothly!
div.lastElementChild.scrollIntoView({ behavior: 'smooth' });
small addendum: scrolls only, if last line is already visible. if scrolled a tiny bit, leaves the content where it is (attention: not tested with different font sizes. this may need some adjustments inside ">= comparison"):
var objDiv = document.getElementById(id);
var doScroll=objDiv.scrollTop>=(objDiv.scrollHeight-objDiv.clientHeight);
// add new content to div
$('#' + id ).append("new line at end<br>"); // this is jquery!
// doScroll is true, if we the bottom line is already visible
if( doScroll) objDiv.scrollTop = objDiv.scrollHeight;
Just as a bonus snippet. I'm using angular and was trying to scroll a message thread to the bottom when a user selected different conversations with users. In order to make sure that the scroll works after the new data had been loaded into the div with the ng-repeat for messages, just wrap the scroll snippet in a timeout.
$timeout(function(){
var messageThread = document.getElementById('message-thread-div-id');
messageThread.scrollTop = messageThread.scrollHeight;
},0)
That will make sure that the scroll event is fired after the data has been inserted into the DOM.
This will let you scroll all the way down regards the document height
$('html, body').animate({scrollTop:$(document).height()}, 1000);
You can also, using jQuery, attach an animation to html,body of the document via:
$("html,body").animate({scrollTop:$("#div-id")[0].offsetTop}, 1000);
which will result in a smooth scroll to the top of the div with id "div-id".
Scroll to the last element inside the div:
myDiv.scrollTop = myDiv.lastChild.offsetTop
You can use the Element.scrollTo() method.
It can be animated using the built-in browser/OS animation, so it's super smooth.
function scrollToBottom() {
const scrollContainer = document.getElementById('container');
scrollContainer.scrollTo({
top: scrollContainer.scrollHeight,
left: 0,
behavior: 'smooth'
});
}
// initialize dummy content
const scrollContainer = document.getElementById('container');
const numCards = 100;
let contentInnerHtml = '';
for (let i=0; i<numCards; i++) {
contentInnerHtml += `<div class="card mb-2"><div class="card-body">Card ${i + 1}</div></div>`;
}
scrollContainer.innerHTML = contentInnerHtml;
.overflow-y-scroll {
overflow-y: scroll;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="d-flex flex-column vh-100">
<div id="container" class="overflow-y-scroll flex-grow-1"></div>
<div>
<button class="btn btn-primary" onclick="scrollToBottom()">Scroll to bottom</button>
</div>
</div>
Css only:
.scroll-container {
overflow-anchor: none;
}
Makes it so the scroll bar doesn't stay anchored to the top when a child element is added. For example, when new message is added at the bottom of chat, scroll chat to new message.
Why not use simple CSS to do this?
The trick is to use display: flex; and flex-direction: column-reverse;
Here is a working example. https://codepen.io/jimbol/pen/YVJzBg
A very simple method to this is to set the scroll to to the height of the div.
var myDiv = document.getElementById("myDiv");
window.scrollTo(0, myDiv.innerHeight);
On my Angular 6 application I just did this:
postMessage() {
// post functions here
let history = document.getElementById('history')
let interval
interval = setInterval(function() {
history.scrollTop = history.scrollHeight
clearInterval(interval)
}, 1)
}
The clearInterval(interval) function will stop the timer to allow manual scroll top / bottom.
I know this is an old question, but none of these solutions worked out for me. I ended up using offset().top to get the desired results. Here's what I used to gently scroll the screen down to the last message in my chat application:
$("#html, body").stop().animate({
scrollTop: $("#last-message").offset().top
}, 2000);
I hope this helps someone else.
I use the difference between the Y coordinate of the first item div and the Y coordinate of the selected item div. Here is the JavaScript/JQuery code and the html:
function scrollTo(event){
// In my proof of concept, I had a few <button>s with value
// attributes containing strings with id selector expressions
// like "#item1".
let selectItem = $($(event.target).attr('value'));
let selectedDivTop = selectItem.offset().top;
let scrollingDiv = selectItem.parent();
let firstItem = scrollingDiv.children('div').first();
let firstItemTop = firstItem.offset().top;
let newScrollValue = selectedDivTop - firstItemTop;
scrollingDiv.scrollTop(newScrollValue);
}
<div id="scrolling" style="height: 2rem; overflow-y: scroll">
<div id="item1">One</div>
<div id="item2">Two</div>
<div id="item3">Three</div>
<div id="item4">Four</div>
<div id="item5">Five</div>
</div>
Related
Im creating a fixed header where on load, the logo is flat white. On scroll, it changes to the full color logo.
However, when scrolling back to the top, it stays the same colored logo instead of going back to white.
Here's the code (and a pen)
$(function() {
$(window).scroll(function() {
var navlogo = $('.nav-logo-before');
var scroll = $(window).scrollTop();
if (scroll >= 1) {
navlogo.removeClass('.nav-logo-before').addClass('nav-logo-after');
} else {
navlogo.removeClass('.nav-logo-after').addClass('nav-logo-before');
}
});
});
http://codepen.io/bradpaulp/pen/gmXOjG
There's a couple of things here:
1) You start with a .nav-logo-before class but when the logo becomes black you remove that class and then try to get the same element using a class selector that doesn't exist anymore
2) removeClass('.nav-logo-before') is different than removeClass('nev-logo-before), notice the "." in the first selector.
3) You get the element using the $('.selector')in every scroll event, this can be a performance issue, it's better to cache them on page load and then use the element stored in memory
4) It's not a good practice to listen to scroll events as this can be too performance demanding, it's usually better to use the requestAnimationFrame and then check if the scroll position has changed. Using the scroll event it could happen that you scroll up really fast and the scroll event doesn't happen at 0, so your logo won't change. With requestAnimationFrame this can't happen
$(function() {
var navlogo = $('.nav-logo');
var $window = $(window);
var oldScroll = 0;
function loop() {
var scroll = $window.scrollTop();
if (oldScroll != scroll) {
oldScroll = scroll;
if (scroll >= 1) {
navlogo.removeClass('nav-logo-before').addClass('nav-logo-after');
} else {
navlogo.removeClass('nav-logo-after').addClass('nav-logo-before');
}
}
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
});
body {
background-color: rgba(0,0,0,.2);
}
.space {
padding: 300px;
}
.nav-logo-before {
content: url(https://image.ibb.co/kYANyv/logo_test_before.png)
}
.nav-logo-after {
content: url(https://image.ibb.co/jYzFJv/logo_test_after.png)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<img class="nav-logo nav-logo-before">
</div>
<div class="space">
</div>
Dont need to add the dot . in front of the class name in removeClass and addClass:
Use this:
navlogo.removeClass('nav-logo-before')
Secondly, you are removing the class that you are using to get the element in the first place.
I have an updated codepen, see if this suits your needs: http://codepen.io/anon/pen/ZeaYRO
You are removing the class nav-logo-before, so the second time the function runs, it can't find any element with nav-logo-before.
Just give a second class to your navlogo element and use that on line 3.
Like this:
var navlogo = $('.second-class');
working example:
http://codepen.io/anon/pen/ryYajx
You are getting the navlogo variable using
var navlogo = $('.nav-logo-before');
but then you change the class to be 'nav-logo-after', so next time the function gets called you won't be able to select the logo using jquery as it won't have the '.nav-logo-before'class anymore.
You could add an id to the logo and use that to select it, for example.
Apart from that, removeClass('.nav-logo-before') should be removeClass('nav-logo-before') without the dot before the class name.
The problem is that you removes nav-logo-before and then you want to select element with such class but it doesn't exist.
I've rafactored you code to avert it.
Another problem is that you uses dot in removeClass('.before') while it should be removeClass('before') - without dot
$(function() {
var navlogo = $('.nav-logo');
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 1) {
navlogo.removeClass('before').addClass('after');
} else {
navlogo.removeClass('after').addClass('before');
}
});
});
body {
background-color: rgba(0,0,0,.2);
}
.space {
padding: 300px;
}
.before {
content: url(https://image.ibb.co/kYANyv/logo_test_before.png)
}
.after {
content: url(https://image.ibb.co/jYzFJv/logo_test_after.png)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<img class="nav-logo before">
</div>
<div class="space">
</div>
I'm trying to get the scrollTop position of an element, but it always returns 0. What am I doing wrong, and how can I fix it?
JSFiddle
var inner = document.getElementById('inner');
window.addEventListener('scroll', function() {
console.log(inner.scrollTop);
})
#outer {
background-color: tan;
height: 1000px;
}
#first {
background-color: bisque;
height: 200px;
}
#inner {
background-color: aquamarine;
height: 100px;
}
<div id="outer">
<div id="first"></div>
<div id="inner">scrollTop always returns 0</div>
</div>
As #FelixKling pointed out in the comments:
inner.offsetTop is what to use for this. scrollTop returns the amount you scrolled in that particular container. So because inner doesn't have a scrollbar, it never scrolls, and therefore scrollTop is 0.
But offsetTop, on the other hand, returns the distance of the current element relative to the top of the offsetParent node.
So the formula to get the amount scrolled of an element based on window, would be:
inner.offsetTop - document.body.scrollTop;
For some reason, removing 'height: 100%' from my html and body tags fixed this issue.
I hope this helps someone else!
I am not sure why, but the only thing I could get to work was using window.pageYOffset:
window.addEventListener('scroll', function() {
let scrollPosition = window.pageYOffset;
if (scrollPosition >= 30) {
headerContainer.classList.add('lg:bg-green-lightest');
} else {
headerContainer.classList.remove('lg:bg-green-lightest');
}
});
I found a simplest way to do this by adding eventListener to window object this way:
window.addEventListener("click", () => {
let value = window.scrollTop;
console.log(value);
});
This isn't the cleanest way, but It's the only way I got it work as it should.
Removing overflow: hidden from my html tag fixed this for me.
I'm trying to adapt this JSFiddle to make the menu button on my website hide when I'm at the top of the page and show when I start scrolling down.
I modified the JS to match the CSS on my site. Then I placed it in tags in the head of my page
var $scb = $('<div class="toggle-menu-wrap"></div>');
$('.top-header').append($scb);
var $ccol = $('.content');
$ccol.scroll(function(){
$scb.stop(true,true).fadeTo(500, $ccol.scrollTop() > 10 ? 1 : 0);
});
However, it still doesn't work. Am I making a mistake in how I'm modifying the JS to fit my CSS?
You can include the toggle-menu-wrap element in your HTML from the start. There is no need to insert it using JS.
Write the one line of CSS you need, which is to hide the element from the beginning
.toggle-menu-wrap {
display: none;
}
Your version of jQuery uses 'jQuery' instead of '$' to reference itself. I would also re-write your JS like:
jQuery(document).ready(function() {
fadeMenuWrap();
jQuery(window).scroll(fadeMenuWrap);
});
function fadeMenuWrap() {
var scrollPos = window.pageYOffset || document.documentElement.scrollTop;
if (scrollPos > 300) {
jQuery('.toggle-menu-wrap').fadeIn(300);
} else {
jQuery('.toggle-menu-wrap').fadeOut(300);
}
}
Like #murli2308 said in the comments above, you need to attach a scroll event listener to the window:
$(document).ready(function () {
var $scb = $('<div class="scroll-border"></div>');
$('.above').append($scb);
var $ccol = $('.content');
$(window).scroll(function(){
$scb.stop(true,true).fadeTo(500, $ccol.scrollTop() > 10 ? 1 : 0);
});
})
Wrapping your code in $(document).ready() would also be a good idea.
The reason $ccol.scroll(function() { ... works in that fiddle is because of the CSS:
.content{
height: 200px;
width: 200px;
overflow: auto;
}
Notice overflow: auto;. This causes that specific div to be scrollable. However, on your website, you scroll the entire page, not $ccol. This means the event handler will never fire a scroll event (since $ccol will never scroll).
You might have forgotten to link Jquery.
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
Link this inside your head tag incase.....
This should do the job:
$(window).scroll(function(e){
if ($(this).scrollTop() > 0) {
$(".your_element").css("display", "block");
} else {
$(".your_element").css("display", "none");
}
});
I'm trying to use the affix function to attach a header to the top of the screen, but have it attached only for a portion of the page. It should detach (and scroll up along with the content) when the user scrolls past a certain point.
I'm using the script from this jsfiddle.
What I'm trying right now is this:
$('#nav-wrapper').height($("#nav").height());
$('#nav').affix({
offset: $('#nav').position()
});
$('#nav').detached({
offset: $('#bottom').position()
});
With the .detached class like so:
.detached { position: static; }
Can't get this to work. Any suggestions?
Twitter Bootstrap affix module doesn't have that option. But, I've used many times hcSticky, it is awesome. Take a look, it's simply to use and works very well.
You can write the logic in a function, and pass it to affix as offset.top.
Try
var navHeight = $("#nav").height();
var detachTop = $("#detach").offset().top;
var navTop = $("#nav-wrapper").offset().top;
$('#nav-wrapper').height(navHeight);
$('#nav').affix({
offset : {
top : function() {
if ((navHeight + $(window).scrollTop()) > detachTop) {
return Number.MAX_VALUE;
}
return navTop;
}
}
});
Fiddle is here.
Another option which might work for you: http://jsfiddle.net/panchroma/5n9vw/
HTML
<div class="header" data-spy="affix">
affixed header, released after scrolling 100px
</div>
Javascript
$(document).ready(function(){
$(window).scroll(function(){
var y = $(window).scrollTop();
if( y > 100 ){
$(".header.affix").css({'position':'static'});
} else {
$(".header.affix").css({'position':'fixed'});
}
});
})
Good luck!
Pleasantries
I've been playing around with this idea for a couple of days but can't seem to get a good grasp of it. I feel I'm almost there, but could use some help. I'm probably going to slap myself right in the head when I get an answer.
Actual Problem
I have a series of <articles> in my <section>, they are generated with php (and TWIG). The <article> tags have an image and a paragraph within them. On the page, only the image is visible. Once the user clicks on the image, the article expands horizontally and the paragraph is revealed. The article also animates left, thus taking up the entire width of the section and leaving all other articles hidden behind it.
I have accomplished this portion of the effect without problem. The real issue is getting the article back to where it originally was. Within the article is a "Close" <button>. Once the button is clicked, the effect needs to be reversed (ie. The article returns to original size, only showing the image, and returns to its original position.)
Current Theory
I think I need to retrieve the offset().left information from each article per section, and make sure it's associated with its respective article, so that the article knows where to go once the "Close" button is clicked. I'm of course open to different interpretations.
I've been trying to use the $.each, each(), $.map, map() and toArray() functions to know avail.
Actual Code
/*CSS*/
section > article.window {
width:170px;
height:200px;
padding:0;
margin:4px 0 0 4px;
position:relative;
float:left;
overflow:hidden;
}
section > article.window:nth-child(1) {margin-left:0;}
<!--HTML-->
<article class="window">
<img alt="Title-1" />
<p><!-- I'm a paragraph filled with text --></p>
<button class="sClose">Close</button>
</article>
<article class="window">
<!-- Ditto + 2 more -->
</article>
Failed Attempt Example
function winSlide() {
var aO = $(this).parent().offset()
var aOL = aO.left
var dO = $(this).offset()
var dOL = dO.left
var dOT = dO.top
var adTravel = dOL-aOL
$(this).addClass('windowOP');
$(this).children('div').animate({left:-(adTravel-3)+'px', width:'740px'},250)
$(this).children('div').append('<button class="sClose">Close</button>');
$(this).unbind('click', winSlide);
}
$('.window').on('click', winSlide)
$('.window').on('click', 'button.sClose', function() {
var wW = $(this).parents('.window').width()
var aO = $(this).parents('section').offset()
var aOL = aO.left
var pOL = $(this).parents('.window').offset().left
var apTravel = pOL - aOL
$(this).parent('div').animate({left:'+='+apTravel+'px'},250).delay(250, function() {$(this).animate({width:wW+'px'},250); $('.window').removeClass('windowOP');})
$('.window').bind('click', winSlide)
})
Before you go scratching your head, I have to make a note that this attempt involved an extra div within the article. The idea was to have the article's overflow set to visible (.addclass('windowOP')) with the div moving around freely. This method actually did work... almost. The animation would fail after it fired off a second time. Also for some reason when closing the first article, the left margin was property was ignored.
ie.
First time a window is clicked: Performs open animation flawlessly
First time window's close button is clicked: Performs close animation flawlessly, returns original position
Second time SAME window is clicked: Animation fails, but opens to correct size
Second time window's close button is clicked (if visible): Nothing happens
Thank you for your patience. If you need anymore information, just ask.
EDIT
Added a jsfiddle after tinkering with Flambino's code.
http://jsfiddle.net/6RV88/66/
The articles that are not clicked need to remain where they are. Having problems achieving that now.
If you want to go for storing the offsets, you can use jQuery's .data method to store data "on" the elements and retrieve it later:
// Store offset before any animations
// (using .each here, but it could also be done in a click handler,
// before starting the animation)
$(".window").each(function () {
$(this).data("closedOffset", $(this).position());
});
// Retrieve the offsets later
$('.window').on('click', 'button.sClose', function() {
var originalOffset = $(this).data("originalOffset");
// ...
});
Here's a (very) simple jsfiddle example
Update: And here's a more fleshed-out one
Big thanks to Flambino
I was able to create the effect desired. You can see it here: http://jsfiddle.net/gck2Y/ or you can look below to see the code and some explanations.
Rather than having each article's offset be remembered, I used margins on the clicked article's siblings. It's not exactly pretty, but it works exceptionally well.
<!-- HTML -->
<section>
<article>Click!</article>
<article>Me Too</article>
<article>Me Three</article>
<article>I Aswell</article>
</section>
/* CSS */
section {
position: relative;
width: 404px;
border: 1px solid #000;
height: 100px;
overflow:hidden
}
article {
height:100px;
width:100px;
position: relative;
float:left;
background: green;
border-right:1px solid orange;
}
.expanded {z-index:2;}
//Javascript
var element = $("article");
element.on("click", function () {
if( !$(this).hasClass("expanded") ) {
$(this).addClass("expanded");
$(this).data("originalOffset", $(this).offset().left);
element.data("originalSize", {
width: element.width(),
height: element.height()
});
var aOffset = $(this).data("originalOffset");
var aOuterWidth = $(this).outerWidth();
if(!$(this).is('article:first-child')){
$(this).prev().css('margin-right',aOuterWidth)
} else {
$(this).next().css('margin-left',aOuterWidth)
}
$(this).css({'position':'absolute','left':aOffset});
$(this).animate({
left: 0,
width: "100%"
}, 500);
} else {
var offset = $(this).data("originalOffset");
var size = $(this).data("originalSize");
$(this).animate({
left: offset + "px",
width: size.width + "px"
}, 500, function () {
$(this).removeClass("expanded");
$(this).prev().css('margin-right','0')
$(this).next().css('margin-left','0')
element.css({'position':'relative','left':0});
});
}
});