mCustomScrollbar prepend new content - javascript

I am using mCustomScrollbar and I am trying to dynamically load content on top and bottom of the scroll (of course, not the same time).
http://manos.malihu.gr/jquery-custom-content-scroller/
When appending content it works awesome, the scroll will stay in the correct position (the position you scrolled to, and will automatically change the scroll bar position so that you can continue to scroll down to see the new content).
However, when you prepend content (place it on top in the scrollbar), and the user scrolls up, the content will load but the scrollbar will be forced to move up to the top. I want this to work exactly the same way as when appending content on the bottom: let the user scroll up to see the new content.
$(selector).mCustomScrollbar({
mouseWheel: {
scrollAmount: 500,
preventDefault: true
},
callbacks: {
advanced: {
updateOnContentResize: true
},
onScroll: function() {
// this.mcs.topPct contains the current scroll position (when scroll animation is completed.
// it can be between 0-100, where 100 is bottom and 0 is top
//
// my scroll starts on the bottom, and when this.mcs.topPct is 0
// I load dynamic content and place it on the very top of all content
// this causes the scroll to display this content immediately,
// and I would like the user to manually scroll up to see the added content.
}
}
});

if it's still relevant, my solution is:
Before loading new data (assuming you use jquery load/post) get your first ,the top most entry (comment,picture etc.) as an object 'YourObject' (name it how you like it)
Once you load new content use the following line
$(selector).mCustomScrollbar("scrollTo",YourObject,{scrollInertia:0});
It flickers a bit, but at the moment that's about the only way to achieve it.

$(selector).mCustomScrollbar({
mouseWheel: {
scrollAmount: 500,
preventDefault: true
},
callbacks: {
advanced: {
updateOnContentResize: true
},
onBeforeUpdate:function(){
this.totalScroll = this.mcs.topPct.slice(0);
},
onUpdate:function(){
this.mcs.topPct = this.totalScroll;
}
});
Not sure if it works because I don't really have time to make a list that renders objects both on the top and bottom, but if it works then great!
Let me know if it works :)

I ended with the solution below which is not perfect because of flickering.
It requires that the item size is fixed, that you compute "itemsPerRow" beforehand, and (preferably) that you prepend full rows
My content is generated by angular directives doing asynchronous calls. Maybe it is the cause of the flickering.
I'll have to dig again into malihu code to find a better way I guess.
var container=$('.mCustomScrollbar');
var mcs=container[0].mcs;
if (mcs.direction=='y') {
var offset=Math.round(items.length/itemsPerRow)*itemHeight;
} else {
var offset=items.length*itemWidth;
}
var side={x: 'left', y: 'top'};
var pos=mcs[side[mcs.direction]];
var scrollOptions={scrollInertia: 0};
container.mCustomScrollbar('scrollTo', pos-offset, scrollOptions);

Related

Is there anyway to prevent page jumps (from loading images) while scrolling to a div?

I use the following code on page load to smoothly scroll to a div
$(document).ready(function() {
$('html,body').delay(50).animate({scrollTop:jQuery('#3342').position().top-10}, 'slow');
});
It works wonderfully to smoothly scroll the page to a predefined div id (in this case div id=3342, but the actual div ID changes depending on what button the user clicks).
The problem is that if there are any images in the pages above div 3342, then after the scroll finishes, the page jumps and the entire positioning scroll is for nothing, as that content is no longer on screen.
This is on mobile safari btw. I know Google chrome has recently introduced Scroll anchoring, and I believe this is the functionality i'm trying to reproduce somehow.
Just FYI, I have no way of knowing the sizes of images or the ratio of the image sizes ahead of time. They are random images from around the web
Thanks!
EDIT: I don't want to change to window/load event as that means I would have to wait for all the images to load first, which would delay the scroll event massively on some pages
EDIT: The image URLs are all on the source page, no ajax loading of pages after the fact
Repeat until complete:
$(document).ready(function() {
var div = jQuery('#3342');
var complete = false;
function adjust () {
if (!complete) {
$('html,body').delay(50).animate({scrollTop:div.position().top-10}, 'slow', adjust);
} else {
$('html,body').delay(50).animate({scrollTop:div.position().top-10}, 'slow');
}
}
adjust();
$(window).on('load', function () {
complete = true;
});
});

JavaScript replace content by sliding more content in without losing height

So i currently have a setup that allows for a button to be pressed, the current content is hidden, and more content scrolls in from the right. However my problem is that for the briefest of moments the footer, which sits below the content, moves up before moving back down below the content just loaded in.
This fiddle best illustrates the problem: http://jsfiddle.net/9Dubr/766/
My Code:
$('#rightButton').click(function(){
var toLoad = 'page.html #content';
$('#content').hide("fast", loadContent);
function loadContent() {
$('#content').load(toLoad,'',showNewContent);
}
function showNewContent() {
$('#content').show("slide", {direction: "right" }, 1000 );
}
return false;
});
Thanks for your help
The fiddle doesn't seem to work for me, but it sounds to me like your footer is simply trying to occupy the empty space left behind by the previous content. In which case, you can try giving the parent container of your content a fixed height just before hiding it. You can then unset the height once the next content is loaded, that way there isn't really any empty space for the footer to try and occupy.
Untested code:
$('#content').parent().css({height: $('#content').height()});
$('#content').hide("fast", loadContent);
...
function showNewContent() {
$('#content').show("slide", {direction: "right", complete: function() {
$('#content').parent().css({height: ''});
} }, 1000 );
}
If you'd like to make it more visually appealing, you can animate the height so the footer will get pushed/pulled more smoothly.
Hope this helps.
It may be because the page is allowed to resize the lengths of divs. A few suggestions that might work is:
Quick Fixes:
Hiding your footer until the person is at the bottom of the screen
Making your footer a static size and maybe even making the footer position final.
Adding a fixed size container around your objects as mentioned in a previous comment.
This way atleast it won;t bother the footer in any way.
Fix without changing footer:
It is obviously a load problem when the button itself is pressed. Because as I understand from your code when the button is pressed and then you are adding this new content to your page right before using the slide effect.
I would suggest you preload the content when first opening the page and then just use the .slide() when the button is pressed.

One page scroll wrong offset with floating menu bar

I am having an issue. Im using a one page design for a friend with a fixed floating menu on the top. The problem I encounter is that when I click on a link it scrolls down but the offset is not right. Most the of time it scrolls down a little too much covering the content below the menu. What I am trying to achieve is that the scrolling stops at the div being exactly below my menu bar. The other issue is that somehow it wont scroll down when the space between two sections is too narrow. It tries but somehow only moves a few pixels then stops. I can imagine that both are related to the offset issue.
Im sorry, english is not my native language.
Here is what I got so far. A standard scrolling function with window.location.hash. The target are divs spread across the site.
$(document).ready(function () {
$('a[href^="#"]').on('click', function (e) {
e.preventDefault();
var target = this.hash;
var t = $(this.hash).offset().top;
$('.wrapper').animate({
scrollTop: t,
}, 1000, function () {
window.location.hash = target;
});
});
});
You can see an example of the problem live: http://rolfvohs.com/
What I tried so far was using the add.class function to bind the div with an extra padding when a link is clicked. It does work in a way but creates an awkward space. I also tried placing the divs at different locations but that does not fix the job either, just messes it up further.
I would appreciate some insight.
window.location.hash = target;
moves the scroll by default to the div position and you are setting offset top before the hash change so first its changes the offset after that it move to div location.
first try after removing the line "window.location.hash = target;" from the code
or
move the "window.location.hash = target;" out side and above the "$('.wrapper').animate({})" it will work .

Jquery Sticky Nav Issue

I'm been trying to get my head around issue and seem to cant find some help.
http://fiddle.jshell.net/DQgkE/7/show/
The experience is a bit jumpy and buggy now- but what i will like is
1) When you scroll down the page. I want the Sticky Nav to be (disable,dropped off, stop) at a specific location(chapter-3) on the page and the user should have the ability to keep scrolling down.
2) When the user is scrolling back up, the code will stick the nav back and carry it up until the nav reaches the original position at the top.
Below is a starting point.
3) Currently is kinda of doing that but there's some huge jump going on when scrolling back up
http://imakewebthings.com/jquery-waypoints/#doc-disable
using disable, destroy, enable option will be nice.
This is a original experience cleaned: http://fiddle.jshell.net/DQgkE/1/show/
Thanks for the help in Advance.
I'm not sure how this plugin you used work, but I have a solution I wrote a while back that I wrote in jquery. It has few variables at the top, the item you wanted sticky, the item where you want it to stop, and the class to add when it becomes sticky and padding at the top and bottom. I only modified the javascript portion in this fork.
EDIT
I went ahead and fixed the original code. Solution without waypoint plugin is in comments.
Here is the result:
http://fiddle.jshell.net/Taks7/show/
I would recommend to use jQuery (that was a surprise, right?! :P)
$(document).ready(function() { //when document is ready
var topDist = $("nav").position(); //save the position of your navbar !Don't create that variable inside the scroll function!
$(document).scroll(function () { //every time users scrolls the page
var scroll = $(this).scrollTop(); //get the distance of the current scroll from the top of the window
if (scroll > topDist.top - *distance_nav_from_top*) { //user goes to the trigger position
$('nav').css({position:"fixed", width: "100%", top:"*distance_nav_from_top*"}); //set the effect
} else { //window is on top position, reaches trigger position from bottom-to-top scrolling
$('nav').css({position:"static", width:"initial", top:"initial"}); //set them with the values you used before scrolling
}
});
});
I really hope I helped!

How DIV scrolls in chat script?

I coded for a chat script and all the issue is with scrolling DIV layer. I downloaded few chat scripts and found the below after careful observation.
When ever a new line of chat is added, scroll bar doesn't scrolls down after chat line is added. Its adding to the bottom of the DIV layer as the scroll doesn't make any kind of disturbance while making it.
What I did:
Before I used javascript to scroll down for every fixed interval. Doing this I am unable to manually scroll up to view past lines(due to interval refresh scroll bar moves to set position). Later I coded for a javascript that can scrolls down OnClientClick but doing this I can only able to scroll down Chat sender side but it cannot scroll down at Chat receiver side when a new chat line is added.
I downloaded many chat scripts and checked how this particular issue is managed but I couldn't find any solution for it. I fairly guess that its the work of jQuery (not sure) can anybody tell me how to fix this issue?
I am sorry if you failed to understand my issue as I am unable to explain it in more detailed than as above. However I can give you more information on request.
Languages I am using are ASP.NET, AJAX update panels, timer ticks for updating div with new values, javascripts are till now used only to scroll down the element.
Your chat 'screen' should look like this:
<div id="chat">
<div class="wrapper">
<!-- chat messages go here -->
</div>
</div>
Put overflow-y: auto on the chat, but leave the wrapper as it is. Create on function that runs at an interval and add or removes a class "atBottom" to chat 'screen' based on value returned by $('#chat').scrollTop() method.
monitor = function() {
var $this = $(this),
wrap = $this.find('.wrapper'),
height = $this.height(),
maxScroll = wrap.height() - height,
top = $this.scrollTop();
if (maxScroll === top) {
$this.addClass('atBottom');
} else {
$this.removeClass('atBottom');
}
}
window.setInterval(function() {
monitor.call($('#chat').get(0));
}, 350);
Then you need to bind an event 'addMessage' that works like so:
$('#chat').bind('addMessage', function(e, message) {
var $this = $(this),
// store whether it's at the bottom before appending the message
scroll = $this.hasClass('atBottom');
// then append the message
$this.find('.wrapper').append(message);
if (scroll) {
// measure the new maxScroll and scroll to it.
var wrap = $this.find('.wrapper'),
height = $this.height(),
maxScroll = wrap.height() - height
$this.scrollTop(maxScroll);
}
})
$('button').click(function() {
$('#chat').trigger('addMessage', 'asdgagasdg<br/>');
});
Here's an example:
http://jsfiddle.net/WVLE2/

Categories

Resources