I need to be able to scroll back to the top of a page within my ui-routed angular one-page site when a function is triggered, but I've used the simplebar scrollbar plugin as a custom scroller, so can't use the window scrolltop method to take the user back to the top of the page.
I can't use any window/document scrolling method as the container that utilises simplebar is a fixed 100vh container, therefore the window is always scrolled to the top.
I've tried using the jquery method below to reset the position of the scrollbar back to the top, but can't get it working, and there are no error messages in the console.
angular.element('#mainContent').simplebar('getScrollElement').scrollTop(0);
I've also tried this in plain js, which returns 'is not a function' in the console:
var mainContent = new SimpleBar(document.getElementById('mainContent'));
mainContent.SimpleBar.getScrollElement().scrollTop = 0;
It seems that the new SimpleBar(xxx) approach does not work with data-simplebar html attribute.
I don't want to initialize the SimpleBar programmatically so I used this in stead:
$('#mainContent .simplebar-content-wrapper').scrollTop(some_value)
The actual scrollable element would have simplebar-content-wrapper class, and it would be inside the element that you've added SimpleBar for.
The class simplebar-content-wrapper was mentioned in its documentation and can be expected to be consistent across versions.
There would be problem if you have cascaded SimpleBars. Solutions:
$('#mainContent .simplebar-content-wrapper')[0].scrollTop = some_value: This would only scroll the correct SimpleBar because the elements returned by nowaday JQuery is in document order.
$('#mainContent>>>>.simplebar-content-wrapper').scrollTop(some_value): The hierarchy of SimpleBar components is not guaranteed to be unchanged in future versions and this may fail in the future.
I have found the solution. You can access scroll element:
const el = new SimpleBar(document.getElementById('layout'));
el.scrollContentEl.scrollTop = 0;
You can try .animate for this:
$("body").animate({ scrollTop: 0 }, "slow");
var el = new SimpleBar(document.getElementById('myElement'));
el.getScrollElement().scrollTop = 0;
Related
I'm using ShieldUI's "Tabs" and there is a property for the tabs position. I want when the screen width is >= 768px to display the tabs at "left" and while <= 768px to display them on the "top". I came to here:
var $window = $(window);
var $pane = $('#tabsDiv');
function checkWidth() {
var windowsize = $window.width();
if (windowsize < 768) {
$pane.shieldTabs({
position: "top"
});
} else {
$pane.shieldTabs({
position: "left"
});
}
}
checkWidth();
$(window).resize(checkWidth);
But when i'm full width and i go "mobile" i have to refresh the page to get what i want, is there a way to do that without page refresh?
We kind of have some issues with your code, along with the Shield UI limitations. Let's see some of them:
First of all, for what I've checked at the official docs, the framework does support component refreshing, but only for new options you'd like to add to your widgets. Therefore, your code won't work when you try to update specific features of the tab (like the position). This means that it's good to have a global function (initTabs, in our case) for destroying and recreating the whole tab structure;
Second, once you do that, don't declare the resizing function inside of this global new one, in order to evict recursiveness problems;
It's also a good idea creating a global variable to store the state of the tabs position, since we have now local/global functions to handle.
Check out the final working code: https://jsfiddle.net/ro0a5bhv/4/
Note: See that I had to do a workaround regarding the CSS property min-height, which is always set by the framework when switching tab views.
Is there a way to reinitialize stellar.js on browser/window resize so that the element offsets get readjusted?
First of all, it sounds like you might be having an issue with horizontal alignment (assuming it's a vertical site). If so, it's likely that you only need to disable horizontal scrolling:
$.stellar({
horizontalScrolling: false
});
If this doesn't solve your issue, Stellar.js has an undocumented feature that allows you to refresh the plugin.
For example, let's assume you used Stellar.js like this:
$.stellar();
You can refresh it with the following:
$.stellar('refresh');
So, to refresh it on resize, you could do something like this:
$(window).resize(function() {
$.stellar('refresh');
});
Hopefully this should fix everything for you.
After a bit of sleuthing, I've figured this one out. In my case, I have 'slides', which contain my stellar elements, and they are sized to full width/height of the viewport. I needed to resize them for tablet orientation change.
$(window).resize(function(){
winHeight = $(window).height();
$("#scrollWrapper > div").height(winHeight);
// Find out all my elements that are being manipulated with stellar
var particles = $(window).data('plugin_stellar').particles;
// Temporarily stop stellar so we can move our elements around
// data('plugin_stellar') let's me access the instance of stellar
// So I can use any of its methods. See stellar's source code
$(window).data('plugin_stellar').destroy();
$.each(particles, function(i, el){
// destroy() sets the positions to their original PIXEL values.
// Mine were percentages, so I need to restore that.
this.$element.css('top', '');
// Once the loop is finished, re-initialize stellar
if(particles.length - 1 == i){
$(window).data('plugin_stellar').init();
}
});
});
If it doesn't matter that the elements get set to their original pixel values for left/top, then you can just call destroy & init one after the other:
$(window).data('plugin_stellar').destroy();
$(window).data('plugin_stellar').init();
If you instantiate stellar on an element (i.e., $("#element").stellar(); instead of $.stellar();) then replace "window" with your selector.
I also noticed odd offsets on mobiles that may be caused by the way Firefox/Chrome resizes the webview when scrolling down, when the location bar becomes visible again?
The answer to your question is in a section of the documentation: "Configuring everything":
// Refreshes parallax content on window load and resize
responsive: false,
So, this is false by default. To enable this, use .stellar( {responsive:true} )
The real question is... why is this disabled by default? It seemed to fix the problem I was noticing, except for iOS.
I have html elements with id's assigned. Now I want to scroll to those elements. I see jQuery has a scrollTop which takes an integer value.. How do I easily just make a particular html element with an id scroll to the top? Ideally, with nice and smooth animation.
A quick search showed many scrolling plugins... if a plugin is needed for the above functionality, what's the most popular one? I'm also using jquery-ui.
You could use something like this to scroll to #someElement when the page loads:
$(document).ready(function() {
$("html, body").animate({scrollTop: $("#someElement").offset().top}, 1000);
});
It simply animates the scrollTop property of the body element, and uses the top offset of some specific element as the position to scroll to. The animation lasts for 1000ms.
Note: it selects both html and body so it works across browsers. I'm not sure on the specifics, but some quick tests show that Chrome uses body, but Firefox and IE use html.
Here's a working example.
Consider the following snippet:
$('#myDiv').bind('click',function(){
var pos = $(this).offset().top,
scrollSpeed = 2;
for (var i = pos; i > 0; i=i-scrollSpeed) {
$(window).scrollTop(i);
}
});
It scrolling was binded to #myDiv element on click just for example. Code determines a position of #myDiv element, than calculates number of scroll steps (speed/smoothness). Than does jQuery .scrollTop() thing.
I am making a chat-like interface which can be seen here (best viewed in Chrome right now):
http://qas.im/web/sms.php
The temporary username:password is temp_guest:password
My problem is that when you click one of the chats, it doesnt automatically scroll to the bottom when I use this code:
$(".messages").attr({ scrollTop: $(".messages").attr("scrollHeight") });
What could be wrong? The messages div has a css of:
.messages {
height:400px;
overflow: auto;
}
For people who are wondering: Page isnt HTML validated yet but I will be cleaning it up soon. Most of the page is auto-generated which is challenging to make the code look pretty ;P
If you are using jQuery 1.6 or later, use prop instead of attr.
Working example: http://jsfiddle.net/FishBasketGordo/PNwj3/
I found two issues.
The first is that you were trying to set all .message DIVs to the height of the first DIV, so if the first DIV was hidden, it would never work.
The second was that jQuery's attr function is only for node attributes.
This method works better, and scrolls all the divs correctly:
$(".messages").each(function(idx, node) { node.scrollTop = node.scrollHeight; });
Alternatively, you can improve performance by using this selector:
$(".messages:visible").each(function(idx, node) { node.scrollTop = node.scrollHeight; });
Which works on visible message nodes.
Here's what i have so far:
function loadOff(){
$(document).ready(function(){
$("#eLoader").ajaxStop(function(){
$(this).hide();
$("#eventsContent").show();
var h = document.body.scrollHeight;
$("#bodyBackground").css("height",h+100+"px");
$("#sidePanel1").css("height",h-105+100+"px");
$("#bottom").css("top",h+100+"px");
});
});
}
This is a callback function for a JQuery ajax function, basically what is does is when all ajax is finished .ajaxStop() it hides the loader then shows the content.
The problem i am having is adjusting bodyBackground, sidePanel, and bottom to fit the content. I dont care to have it elastic and retract for short content at this point, i would just like it to extend to proper positioning based on content length.
All divs are absolutely positioned. The numbers in the function are broken down simply to make it easy to explain. -105 is the offsetTop of that element and +100 is the margin between the end of the content and the elements.
if there is a better, more efficient way to achieve this outcome, please, do tell.
Thanks.
Based on your code, the only thing you ought to see is the top 105px of #sidePanel1. Is that your intent? (h = the bottom of the window, according to your code.)
Sticking with the JQuery patterns, you would use
var h = $(window).height();
Maybe you're looking for this instead of the browser window's height? It will get the height of the content element.
$("#eventsContent").outerHeight();