scrollTop not working automatically - javascript

I know there are a couple of questions to scrollTop already out there but I haven't really seen anything resembling my problem.
Using jquery 1.7.2 on an IE9 we have a page with three Tabs (JqueryUI).
The Data is connected and that resulted in us only having the current tab on the page. Changing tabs will remove the unseen one and reload the one we jump into.
The Scroll-Positions are stored correctly in variables on the base page but trying to set that position in the document-ready-function does not work.
An alert shows the correct number, so the function is actually called but the scrollbar does not move.
Calling the same function with a button on the page afterwards however works perfectly.
The document-ready-function on the tab's jsp is quite simple:
<script type="text/javascript">
jQuery(document).ready(function(){
setAhaScrollbar();
});
</script>
and the called function is quite simple as well:
function setAhaScrollbar() {
var scrollWert = $('#scrollbarAnhaengeartikel').val();
alert(scrollWert);
$('#anhaengeGridScrollable').scrollTop(scrollWert);
}
Called from document-ready it does nothing. Called from a button later on it works fine.
The div where the scroll position is supposed to be set is defined with overflow: auto and a fixed height

crollTop( value )
Description: Set the current vertical position of the scroll bar for each of the set of matched elements.
.scrollTop( value )
value
Type: Number
An integer indicating the new position to set the scroll bar to.
More Information
As the documentationsaid value should be number.
Try
var scrollWert = Number($('#scrollbarAnhaengeartikel').val());
or
var scrollWert = parseInt($('#scrollbarAnhaengeartikel').val());

Apparently it was primarily a timing problem. Maybe there were still things going on when document ready fired.
Changing that function to
jQuery(document).ready(function(){
setTimeout("setAhaScrollbar()", 500);
});
did the trick so my problem is solved.

Related

How can I scroll a div on a page without using jquery (what is the "Angular way") and without scrolling the window?

I'm attempting to use the solution here to scroll a container to a certain position. Here's my version:
var wrapper = angular.element(document.getElementById('myWrapper'))[0];
var container = wrapper.querySelector('#myContainer');
var anchor = wrapper.querySelector('#myAnchorWithinTheContainer');
scrollContainerToAnchor(container, anchor);
...
function scrollContainerToAnchor(container, anchor) {
var element = angular.element(anchor);
angular.element(container).animate({scrollTop: element.offset().top}, "slow");
}
However, angular.element returns an array, so I don't see how that answer can work... but even if I correct it to the following:
function scrollContainerToAnchor(container, anchor) {
var element = angular.element(anchor);
angular.element(container)[0].animate({scrollTop: element[0].offset().top}, "slow");
}
the browser will still complain that "element[0].offset is not a function". So, I attempted to use getBoundingClientRect() instead:
function scrollContainerToAnchor(container, anchor) {
var element = angular.element(anchor);
angular.element(container)[0].animate({scrollTop: element[0].getBoundingClientRect().top}, "slow");
}
but then the browser gives me "Failed to execute 'animate' on 'Element': The provided double value is non-finite" (in my case, the "non-finite" value that it's complaining about is 3282.9375(?)).
Anyway, the fact that the above-linked answer has (as of today) 10 upvotes and no complaints in the comments suggests that I am missing something, not that the answer is incorrect... So, what am I missing?
If there's a better way to scroll a div without using jQuery and without scrolling the whole page in addition to the div (I've already looked at $anchorScroll, but it scrolls both the window and the div), I'm up for other suggestions/techniques.
The answer referenced above requires jQuery. The offset function is part of jQuery. Angular makes use of jQuery Lite aka jqLite, which has no offset function.
To scroll the div without jQuery, I did the following:
HTML:
...
<div id="myScrollableDiv">
...
<div id="elementIWantToScrollTo">...</div>
</div>
<div in-view="scrollableDivIsVisible()"></div>
...
Controller:
angular.module('myModule')
.controller('MyCtrl', ['$scope', function($scope) {
...
var _hasBeenScrolled = false;
$scope.scrollableDivIsVisible() {
if (!_hasBeenScrolled) {
document.getElementById('elementIWantToScrollTo').scrollIntoView();
_hasBeenScrolled = true;
}
}
}]);
Note that scrollIntoView() causes both the window and the div to scroll (similar to $anchorScroll, but easier to use and doesn't add a hash tag to the URL). Since one of the requirements is to NOT scroll the window, I avoid that by using the in-view directive to detect when the bottom of my scrollable div is visible. Thus I only trigger scrollIntoView() when scrolling the window won't matter/is already complete. Then I use _hasBeenScrolled to ensure scrollIntoView() doesn't interfere with any scrolling that the user did (i.e. it's only auto scrolled once).
If you need to scroll a div based on some other trigger, rather than when the user first sees it, as was my need, then you can use the in-view directive to set a variable and then $scope.$watch() that variable before running your other trigger.
Maybe there's a better "Angular way" to do it, but the above gets the job done, and doesn't need jQuery.

Chrome ignoring hashes in URL

I've spent quite a while trying to find answers for this issue, but haven't had any success. Basically I need to scroll the user to the contact portion of the website when they go to healthdollars.com/#contact. This works just fine in Safari, but in Chrome I haven't had any luck. I've tried using jQuery/Javascript to force the browser to scroll down, but I haven't been able to.
Does anyone have any ideas? It's driving me crazy - especially since it's such a simple thing to do.
Not a full answer but in Chrome if you disable Javascript I believe you get the desired behavior. This makes me believe that something in your JavaScript is preventing default browser behavior.
It looks to me like the target element doesn't exist when when page first loads. I don't have any problem if I navigate to the page and then add the hash.
if (window.location.hash.length && $(location.hash)) {
window.scrollTo(0, $(location.hash).offset().top)
}
check for a hash, find the element's page offset, and scroll there (x, y).
edit: I noticed that, in fact, the page starts at #contact, then scrolls back to the top. I agree with the other answerer that there's something on your page that's scrolling you to the top. I'd search for that before adding a hack.
You can do this with JS, for example` if you have JQuery.
$(function(){
// get the selector to scroll (#contact)
var $to = $(window.location.hash);
// jquery animate
$('html'/* or body */).animate({ scrollTop: $to.offset().top });
});
The name attribute doesn't exists in HTML 5 so chrome looks to have made the name attribute obsolete when you use the DOCTYPE html.
The other browsers have yet to catch up.
Change
<a name="contact"></a>
to
<a id="contact"></a>
Maybe this workaround with vanilla javascript can be useful:
// Get the HTMLElement that you want to scroll to.
var element = document.querySelector('#contact');
// Stories the height of element in the page.
var elementHeight = element.scrollHeight;
// Get the HTMLElement that will fire the scroll on{event}.
var trigger = document.querySelector('[href="#contact"]');
trigger.addEventListener('click', function (event) {
// Hide the hash from URL.
event.preventDefault();
// Call the scrollTo(width, height) method of window, for example.
window.scrollTo(0, elementHeight);
})

Associate toggle with another function

I have a problem combining a toggle function with another function involving a change of the css 'position' attribute.
I have a starting page with a menu at the top and columns of pictures beneath it.
Some columns are higher than the window and they can be scrolled down together with the menu (both in position: absolute).
When you click on an item from the menu however, the columns hide and another set of pictures appears (triggered by a click+toggle function). This new set is horizontal and this time I need the menu not to scroll with it.
So what I'm trying to do is to change the position of the menu from absolute to fixed, according to the state of the toggle.
At first I tried including an if/else statement inside my click function but the 'else' part never worked. Now I'm trying to use the callback property of the toggle, but I can't seem to make it work either... The best I can do is get the menu's position switched to fixed, but then it stays that way.
one of the uneffective try-outs:
function fixMenu(){
('.menu').css('position','fixed')};
function freeMenu(){
('.menu').css('position','absolute')};
$("#menu_item").click(function(){
$("#horizontal_set").toggle(1000,fixMenu);
$(".column").toggle(1000,freeMenu);
});
I have no idea whether my problem is in the syntax or if I need a completely different solution. Please enlighten me :-)
Many thanks
PS: I made two little sketches but it appears I'm not allowed to share them :-( I hope my problem remains understandable.
Try this:
It checks via an if-statement if horizontal_set or column is visible. and invokes the correct function as a result.
function fixMenu(){
$('.menu').css('position','fixed')};
function freeMenu(){
$('.menu').css('position','absolute')};
$("#menu_item").click(function(){
$("#horizontal_set").toggle(1000);
$(".column").toggle(1000);
if ( $( "#horizontal_set" ).is( ":visible" ) && $( ".column" ).is( ":hidden" ) )
{
fixMenu();
}
else
{
freeMenu();
}
});
You forgot jQuery selectors in the function. Try:
function fixMenu() {
$('.menu').css('position','absolute');
}

Weird variable value on jQuery and Ajax loading

I have this code
var varheight;
$('.item-content').load("content/content.html", function(){
varheight = $('.item-content').css('height');
$('.item-content').css({height: 0});
$('.item-content').animate({'height': varheight}, 1000);
});
What I want it to do is load the contents in the container, so I can get the total container size after the loading, then, set the height to 0 before the users see it, and then, slowly, by animation, increase the height to it's size.
Seems pretty straight forward and the code should be working... but, something weird is happening... if I check the value of varheight with an alert like this:
var varheight;
$('.item-content').load("content/content.html", function(){
varheight = $('.item-content').css('height');
alert(varheight);
$('.item-content').css({height: 0});
$('.item-content').animate({'height': varheight}, 1000);
});
I get 0. It should not be, because I've just loaded a lot of content inside the .item-content
The weird part is that if I remove the next 2 lines, like that:
var varheight;
$('.item-content').load("content/content.html", function(){
varheight = $('.item-content').css('height');
alert(varheight);
});
I get the true value (about 1300px, that's not really the important point here).
I can't help but wonder, how come can that value change even if these lines have not been reached yet? How can they have effect on value of this variable if it is never changed again and, worst of all, the alert comes BEFORE these lines??
I'm losing my mind here!
Apparently, there was another parallel script running which was hard-coding the height to 0 before this one, causing the problem!
Script removed, problem solved.

Hammer.js Carousel Start Pane

Heyho,
I´am working on a project in my university and I´d like to use "Hammer.js".
I´ve downloaded the Carousel-Example and it works perfectly for me.
But I would like to start a the middle pane of my code and it´s not so simple I think.
It´s something like this:
http://img203.imageshack.us/img203/6326/schemeas.jpg
so Hammer.js starts always with the green screen. But I like to start with the yellow one.
I´ve added one swipe right to the init function but it looks horrible when the page is loading and could not be the goal ^^
I hope anyone of you have an idea how to solve my problem.
Try calling
carousel.showPane(1);
That will display the second pane instantly. You will want to put this near the bottom, right after where it says.
carousel.init();
If you're feeling adventurous you could try and make it automatically start with that pane as there's a variable inside the Carousel function called current_pane which is set to a default of 0 (the first pane). Altering this may work too but might require more code somewhere else. Experiment!
edit
NULL is right, it does animate it. Here's a more in depth method to set it without animation:
I found that the method responsible for changing which pane is showing was the setContainerOffset mthod which could be passed a variable to animate it. I previously told you to use showPane(2) but that then called
setContainerOffset(offset, true)
which caused the animation occur. What you should do instead is make a slightly different version of showPane...
this.setPane = function( index ) {
// between the bounds
index = Math.max(0, Math.min(index, pane_count-1));
current_pane = index;
var offset = -((100/pane_count)*current_pane);
setContainerOffset(offset, false);
};
You'll find it's almost identical to showPane except for the name and the fact that it calls setContainerOffset with animation: false. This will immediately show the pane of your choice and can be called using
carousel.setPane(index);
What I've done is added this to the init function so that it looks like this:
this.init = function() {
setPaneDimensions();
var c = this;
$(window).on("load resize orientationchange", function() {
setPaneDimensions();
c.setPane(current_pane);
//updateOffset();
})
};
Now you can change
var current_pane = 0;
to whatever you want and the carousel will always start with that pane when it's initialised! simple!

Categories