Angular $window.scrollTo() isn't working - javascript

I'm trying to scroll to a particular element after finding it on a page in my Angular app.
angular.element(document).ready(function () {
var foundDone = 0;
var currOver = 0;
for (var prog in $scope.programs){
var big = $scope.programs[prog];
if(!big.over && foundDone === 0){
foundDone++;
var e = document.getElementsByClassName('programThumbs')[currOver];
var theTop = e.getBoundingClientRect().top;
$window.scrollTo(0, theTop)
console.log("Scrolled to " + theTop)
}
currOver++;
}
});
I've tried $window.scrollTo() as well as window.scrollTo(), but neither are doing anything here. My console logs: Scrolled to 565, which is the correct y-position.
Any ideas on what I'm doing wrong here?

I'm not sure about scrollTo() but have you tried scrollTop property?
// Set the number of pixels scrolled
element.scrollTop = intValue;

Related

How to disable a jquery function from executing for a certain amount of time

I have a jQuery function that calculates the distance between two slideshows and detects to see if they have been scrolled past yet and tells it to display the first slide with important information on it.
However, it displays it once, but then the if statement loops and keeps displaying it, which would be expected.
I am wondering if there is a way to force the function to wait 25-ish seconds before it executes again? Any help would be much appreciated.
Here is the jQuery code:
$(window).scroll(function() {
$('.infoIdentifier').each(function() {
var scroll = $(window).scrollTop();
var objectpos = $(this).offset().top - 600;
var nextobject = $(this).parent().nextAll('.slideshow').children(".infoIdentifier")
if (nextobject.length === 0) {
var nextobjectpos = 10000;
} else {
var nextobjectpos = nextobject.offset().top - 600;
}
if (scroll > objectpos && scroll < nextobjectpos) {
var $this = $(this).parent('.slideshow');
var $currentSlide = $this.find('.active');
var $nextSlide = $this.children('.jumbotron').first();
$nextSlide.fadeIn(500).addClass('active');
$currentSlide.fadeOut(500).removeClass('active');
}
});
});
As for HTML, the slideshows are held in a main container, and each slide show with important information is tagged as class = 'infoIdentifier'. This part of the function does its job. The calculations are fine and the application of classes is fine, however, how do I disable the if (scroll > objectpos && scroll < nextobjectpos){ statement for x amount of seconds. Any help would be much appreciated. Thank you!
Here's one way to achieve this. I added a boolean outside of your scroll function called wait, which is set to false initially.
Then I added !wait as a condition to your if logic, which means it will only validate if wait is currently false.
Then inside that block, I set wait to true, and started a setTimeout for 25 seconds, after which wait is set back to false.
During those 25 seconds, that slideshow code will not run.
var wait = false;
$(window).scroll(function() {
$('.infoIdentifier').each(function() {
var scroll = $(window).scrollTop();
var objectpos = $(this).offset().top - 600;
var nextobject = $(this).parent().nextAll('.slideshow').children(".infoIdentifier")
if (nextobject.length === 0) {
var nextobjectpos = 10000;
} else {
var nextobjectpos = nextobject.offset().top - 600;
}
if (!wait && scroll > objectpos && scroll < nextobjectpos) {
var $this = $(this).parent('.slideshow');
var $currentSlide = $this.find('.active');
var $nextSlide = $this.children('.jumbotron').first();
$nextSlide.fadeIn(500).addClass('active');
$currentSlide.fadeOut(500).removeClass('active');
wait = true;
setTimeout(function() {
wait = false;
}, 25000);
}
});
});

How to transform a generic Animated JS script to work with many classes id

I don't know how I can explain my problem... but I have a Animated JS script and this JS Works fine.
This script identify by CLASS NAME each ICONS on the page marked by the class name - and animated this icons with a delay between each icon.
Then I have in my page 3 sections (all in the same page):
1- About Us
2- Services
3- Clients
I create this script to use in SERVICES SECTION where I have 20 services, with 20 icons - animated one after other on screen.
But now, I want to use this script in About Us and Clients Sections to animated the icons in this sections
My problem:
The script Works fine for 1 section. If I use in other section I need to wait all animations from the other sections stop to start the animations from the actual sector. (All animations are "scrollbar controlled")
To correct this I clone the script 2x and change the class name for each section.
Problem solved!
But I need to write 3x the same script and only change a class name..
If I need to create another 10 sections, a I will need to write the same script 10x..
There is a way to avoid this?
SORRY! I'M A BEGINNER IN JS.. I understand many things, but I'm not a expert.
var $animation_elements = $('.animation-element');
var $window = $(window);
const MULTIPLIER = 800;
var countInView = 0;
var timeouts = [];
for (i = 0; i < $animation_elements.length; i++)
timeouts[i] = [];
function check_if_in_view() {
var window_height = $window.height();
var window_top_position = $window.scrollTop();
var window_bottom_position = (window_top_position + window_height + 15);
for(var i=0; i < $animation_elements.length ; i++) {
var $element = $animation_elements.eq(i);
var element_height = $element.outerHeight();
var element_top_position = $element.offset().top;
var element_bottom_position = (element_top_position + element_height);
if ((element_bottom_position >= window_top_position) &&
(element_top_position <= window_bottom_position)) {
if($element.is($('i').parent()) && !$element.hasClass('in-view')) {
var delay = MULTIPLIER * ++countInView;
$element.addClass('paused');
(function(delay, $element, savedtimeout){
savedtimeout[i][0] = setTimeout(function() {
$element.removeClass('paused');
countInView--;
}, delay);
}(delay, $element, timeouts));
}
$element.addClass('in-view');
} else {
if($element.hasClass('in-view')) {
$element.removeClass('in-view');
}
if($element.hasClass('paused')) {
if(timeouts[i][0] != null) {
//Retira o timeout da fila
clearTimeout(timeouts[i][0]);
countInView--;
}
$element.removeClass('paused');
} // end if
} // end if
} // end for
}
$window.on('scroll resize', check_if_in_view);
$window.trigger('scroll');
Then i change:
var $animation_elements = $('.animation-element');
var $animation_elements = $('.animation-element2');
var $animation_elements = $('.animation-element3');
And copy+paste all the rest

Floating JQuery menu issues on slower connection

I'm trying to create a floating menu (#quickmenu in left hand sidebar of bottom link) that stops at #weather whilst also re-calculating the bottom = $(\'#weather\').offset().top; every 0.5 seconds...
Page to test: Bristol International Jazz & Blues Festival 2014 | Festival Archive
The recalculation is key as I use expandable content in the main body and because without recaculating on slower connections it doestn't work. I need only #weather.offset.top to be recalculated every 5 seconds, not the whole script otherwise it refreshes and flickers...
I've tried to do code it myself and it's not working, it's 99% not coded correctly but can't figure out what's going wrong? The logic seems to be correct though... if (y >= top && z <= bottom) { ....
<script type="text/javascript">
$(document).ready(function () {
top = $('#quickmenu').offset().top;
var didScroll = false;
$(window).scroll(function() {
didScroll = true;
});
setInterval(function() {
if ( didScroll ) {
didScroll = false;
bottom = $('#weather').offset().top;
y = $(this).scrollTop();
z = y + $('#quickmenu').height();
if (y >= top && z <= bottom) {
// if so, add the fixed class
$('#quickmenu').addClass('fixed');
} else if(z > bottom) {
// otherwise remove it
$('#quickmenu').removeClass('fixed').addClass('absolute');
} else {
// otherwise remove it
$('#quickmenu').removeClass('fixed');
}
}
}, 500);
});
</script>
Thanks for the input, and apologies for lack of clarity within the question. I have fixed my issue by taking another approach. I hope that this is less resource heavy?
<script type="text/javascript">
(function () {
var s = document.querySelector(\'#event-info\').style;
s.overflow = \'inherit\';
s.height = \'auto\';
})();
window.updateQuickMenuPos = function () {
var menu = document.querySelector(\'#quickmenuwrapper\');
var scroll_pos = document.body.scrollTop;
var menu_pos = menu.offsetTop + 10;
var weather = document.querySelector(\'#weather\');
var pos = (scroll_pos - menu_pos);
// min height
if (pos < 0) {
pos = 0;
}
// max height
if (menu_pos + menu.offsetHeight + pos > weather.offsetTop) {
pos = weather.offsetTop - menu.offsetHeight - menu_pos;
}
var s = menu.style;
s[\'webkitTransform\'] = s[\'mozTransform\'] = s[\'transform\'] = \'translateY(\' + pos + \'px)\';
};
jQuery(document).scroll(window.updateQuickMenuPos);
</script>

elementFromPoint() full document alternative

I am trying to recover a value from a cookie, which is somewhere on the Y-axis where the user clicked. I then want to find the parent <h2> from that click (if it helps, all the <h2>s are the first child of a <div class="_bdnable_">). Here is what I have so far:
var bookmarkLocation;
function getBookmarkPos() {
if ($.cookie("bookmark-position") !== null) {
$(".bdnable").each(function(i) {
var scrollTopTop = $(this).offset.top;
var scrollTopBottom = $(this).offset.top + $(this).height();
// var screenWidth = parseInt(screen.width/2);
// alert(screenWidth);
// var bookmarkPosition = parseInt($.cookie("bookmark-position"));
// alert(bookmarkPosition);
// var query = document.elementFromPoint(screenWidth, 50).nodeName;
// alert(query);
if ($.cookie("bookmark-position")>=scrollTopTop && $.cookie("bookmark-position")<=scrollTopBottom) {
bookmarkLocation = $(this).closest("div").children(":nth-child(1)").text();
}
});
if (bookmarkLocation == null) {
bookmarkLocation = "Unknown";
}
} else {
bookmarkLocation = "No bookmark set";
}
$("#bookmarklocationspan").html(bookmarkLocation);
}
In the commented out section is where I tried to use getElementFromPoint and then realized that it only checks the visible area. Not good, because the scrollable Y-axis on the page is 1000s of pixels tall.
Any ideas are greatly appreciated!!!
If you already have the y-coordinate of the click from the cookie, why not simply compare all H2's y-position and pick the one which is the next "higher" one? Your approach looks like it's compares whether the user has clicked directly on the H2 instead of the article/button below it?
Just an idea - don't rate it's style, think its prettey messy:
var $myH2 = $('h2');
var clickY = <COOKIE_VALUE>;
var currentY = 0;
var foundH2ID = '';
for (var i = 0; i < $myH2.length; i++) {
var h2Y = $($myH2[i]).position().top;
if (h2Y <= clickY && h2Y > currentY) {
currentY = h2Y;
foundH2ID = $myH2[i].id;
}
}
Or maybe I got you wrong?

How to check if a DIV is scrolled all the way to the bottom with jQuery

I have a div with overflow:scroll.
I want to know if it's currently scrolled all the way down. How, using JQuery?
This one doesn't work: How can I determine if a div is scrolled to the bottom?
Here is the correct solution (jsfiddle). A brief look at the code:
$(document).ready(function () {
$('div').on('scroll', chk_scroll);
});
function chk_scroll(e) {
var elem = $(e.currentTarget);
if (elem[0].scrollHeight - elem.scrollTop() == elem.outerHeight()) {
console.log("bottom");
}
}
See this for more info.
function isScrolledToBottom(el) {
var $el = $(el);
return el.scrollHeight - $el.scrollTop() - $el.outerHeight() < 1;
}
This is variation of #samccone's answer that incorporates #HenrikChristensen's comment regarding subpixel measurements.
Since it works without jQuery like that :
var isBottom = node.scrollTop + node.offsetHeight === node.scrollHeight;
I do :
var node = $('#mydiv')[0]; // gets the html element
if(node) {
var isBottom = node.scrollTop + node.offsetHeight === node.scrollHeight;
}
You can do that by
(scrollHeight - scrollTop()) == outerHeight()
Apply required jQuery syntax, of course...
Here is the code:
$("#div_Id").scroll(function (e) {
e.preventDefault();
var elem = $(this);
if (elem.scrollTop() > 0 &&
(elem[0].scrollHeight - elem.scrollTop() == elem.outerHeight())) {
alert("At the bottom");
}
});
Since 2012 Firefox contains the scrollTopMax property. If scrollTop === scrollTopMax you're at the bottom of the element.
Without jquery, for onScroll event
var scrollDiv = event.srcElement.body
window.innerHeight + scrollDiv.scrollTop == scrollDiv.scrollHeight
For me $el.outerHeight() gives the wrong value (due to the border width), whereas $el.innerHeight() gives the correct one, so I use
function isAtBottom($el){
return ($el[0].scrollHeight - $el.scrollTop()) == $el.innerHeight();
}

Categories