I want to reload the page only once if a given div is positioned higher than position:absolute; top:15%.
I think this could be done with jQuery's .css method, something like:
if ('#mydive').css('top') > '15%' {
//reload the page
}
Could someone suggest a simple solution, preferably jQuery or pure JavaScript?
If what you meant is the top of the document, you can probably try:
var percent = .15; // 15%
if ($('#yourdiv').offset().top > ($(document).height() * percent)) {
window.location.reload();
}
// if by pixels
var pixels = 10; // 10px
if ($('#yourdiv').offset().top > pixels) {
window.location.reload();
}
You can check the current position of a div using the Computed Style
If you are have a like an animation or a drag and drop, you can use the onmousemove event to track the position of the div. but be careful the mousemove will be trigger for every pixel it moves and it my use lots of process time, so be wise on how you use it :)
Well, it is rather hard to say how you should determine the position of the div since you presented no code, but basically you should write a function that fetches the window height and the offset of the div relative to the top of the window to determine whether it is higher than 15%. You then need to call this function every time using the window.onscroll event listener. When the function returns true, trigger trigger window.location.reload(true) to reload the page. I imagine this could be done fairly easily in jQuery as well.
the above answers point you in the right way, but in order to "reload the page only once", you need an extra ingredient. you need a way to store a flag that points out whether the page has already been reloaded or not.
Say you follow tradyblix's code.
You should check for that flag before reloading your page :
if (hasReloaded() && $('#yourdiv').offset().top > ($(document).height() * percent)) {
reload();
}
where hasReloaded is a function that determins if the page has been reloaded, and it can be either a function that sends an ajax request to a server, that checks a cookie or even the localStorage object:
function hasReloaded(){
return !!localStorage['reloaded'];
}
In order to set that flag, your reload function needs to access the localStorage (or cookie or ajax server response) :
function reload(){
localStorage['reloaded'] = true;
window.location.reload();
}
This is just a sketch of how you should write this functionality.
Related
I'm trying to create a generic function that can be placed just once in my site and work across multiple pages, nice and lightweight.
I want to be able to make certain divs on the site fade-in when you reach 10px above them on the scroll.
I want to do this by simply adding the following attributes to my divs:
.fade-in-block
#specific-block-name
The idea is that I could go through the site, add this class and an ID, and the animation would work.
I almost have it working except for one thing, the scroll listening constantly continues to console.log after the function has been called. I don't like this as it feels like it's going to be constantly trying to apply the animation, which won't really be seen from the front-end but I feel the constant maths behind the scenes could slow stuff down.
Here is my jQuery:
$('body .fade-in-block').each(function(){
var block = '#'+$(this).attr('id');
console.log('Block class is = '+block);
var offset = $(block).offset().top;
var $w = $(window).scroll(function () {
if ($w.scrollTop() > offset - 10) {
console.log('reached block turn-on point for '+block);
$(block).removeAttr('id'); // remove the ID from the element so the script doesn't continue to find the element
// fade and rise animation here
}
});
});
And here is a JSFiddle. It works just fine, but once you hit the block you'll see it logs constantly every pixel scrolled.
I tried to remedy this by removing the selecting id from the element once the event has occurred, but it continues to run.
Scroll and resize events both have this problem and the solution is said to be debouncing. However, I've never actually gotten debouncing to work properly. Instead I typically create a sort of switch that is turned off once the scroll condition has activated. In your case, since you have multiple elements, you would need to assign a switch to each element.
$(window).on('scroll', function(){
$('.fade-in-block').each(function(){
var appear = $(this).attr('data-appeared');
if(!appear){
$(this).attr('data-appeared', true);
//do something to $(this)
}
})
})
Here I'm adding a data attribute after it has appeared and checking for it again once it has.
Context: I have a button on the top of the page in the header, and I want visitors to jump to the form section which is at a lower position on the same page. For some unchangeable factors, the form is partially hidden under the header after page jump, so I am thinking of creating a new div before the form and change the height of the div to push the form down after jumping. Then, when users scroll again on the page, the height should go back to 0.
Problem: When I click on the DemoButton for the first time, the div height doesn't change and the form goes under header, but the second time it works. I don't know how to fix that.
The basic html structure is shown as following:
<div>
<a href="#demoForm" id="DemoButton">
<button>request demo</button>
</a>
</div>
<div id="space"></div>
<from id="demoForm">...</form>
JavaScript:
window.onload = function comparison() {
window.addEventListener("scroll", reset, false);
var demo = document.getElementById('DemoButton');
demo.onclick = uniform;
}
function reset() {
document.getElementById('Space').style.height = '0';
}
function uniform() {
document.getElementById('Space').style.height = '160px';
};
I know a lot of people are using newer CSS for reactive headers these days. I believe it's done using media queries, and I might suggest researching it some more. (I have some experience, it was very easy and cool too.)
Ideally, you'd want something like this to happen in CSS without JavaScript at all. See if you can get it figured out that way.
Using very light Javascript, it seems the easiest thing to do would be to just offset the scroll by the height of the header once the button has been clicked. You can hard-code the header height or calculate it dynamically.
So...
;;;;;;;;;;;;;;
; $ = document ;
; id = 'getElementById' ;
;;;;;;;;;;;;;
onload = function (e)
{
$[id]('DemoButton')
. onclick = function offset(e)
{
document.body.scrollTop -= $[id]('Header').offsetHeight;
}
;
}
Notes
You may have to wrap it in a 5ms setTimeout. Easy enough.
I don't remember all the cross-browseryness. There might be a need to parseInt or use document.documentElement. But at least you don't have cross-browser scroll events to deal with now, so this should be nice.
I am using jquery to find div's height, but it always returns zero. I can clearly see the height of the div in chrome's inspect element css window.
<div class="findheight">some text here</div>//original height is 21px
But when i do the following it returns zero:
$('.findheight').height() //it always returns zero. really making me sick
So I thought div might not have text when i call height method on it and i did like below.
if($('.findheight').text().length > 6){
alert($('.findheight').height());//This also returns zero so weird
}
I also tried by setting windows.timeoutcall, but that does not help with any delay time.
Can any one help me why I am always getting zero?
If the content of your divs are loaded dynamically, then you will need to use window.load event to get its correct height as discussed here: https://stackoverflow.com/a/13071846/1845408
$(window).load(function() {
alert($('.findheight').height());
});
Copied your code into jsfiddle, the height is 18
<div class="findheight">some text here</div>//original height is 21px
alert($('.findheight').height());
Did you wrap your jquery in a function that executes when the dom is ready?
$(document).ready(function(){
console.log($('.findheight').height());
});
It works for me otherwise your error may be browser specific.
Here is a jsfiddle of it working. Just check your console.
https://jsfiddle.net/lesshardtofind/vzxd4t57/
If for some reason you wouldn't have access to the element on document ready, such as working in dynamically templated frameworks like Meteor, Ember, React, or Angular then each object has a hook to register your functions in.
If otherwise you were trying to get access to an element in between transitions you could set a interval.
var interval;
var timeout = setTimeout(function(){
clearInterval(interval)
}, 10000); // destroy interval after 10 seconds to prevent memory leak
interval = setInterval(function(){
if($('.findheight').length > 0){
// execute your code here because you know this element is in the dom
clearInterval(interval);
clearTimeout(timeout);
// clear both timeout and interval
}
}, 100); // loop every 100 milliseconds to "poll" for the node in the dom
Try doing this:
$('div.findheight').height();
The .height() takes exactly CSS's height property.
If it's a dynamic content you have to handle this in the respective event..
For example:
If you're working with the content on page load like #renakre said, use $(window).load() or $(document).load() to trigger the call.
If it's a content generated from some other process you have coded, you have to bind respective event.. let's presume it's a click or on:
$(document).load(function() {
// Shows the height on page load
console.log($('.findheight').height());
$('#another-element-ID').click(function() {
// .. code which populate the div dynamicaly
// Shows the height
console.log($('.findheight').height());
});
$('.another-element-class').on('change', function() {
// .. code which populate the div dynamicaly
// Shows the height
console.log($('.findheight').height());
});
});
Hope this can help you.
This happens when an explicit height/width is not set for that element OR when the CSS for inner/outer elements set the height/width to 0;
To get height/width like this you have to explicitly set height/width.
My page has a DIV, with overflow and I've placed two buttons on either side of the div to act as secondary scrolling methods.
When pressing the left button, the following script is run and seems to work perfectly:
function slideLeft() {
if ($("#divfieldWidgets").scrollLeft() == 0) {
$('#divScrollWidgetsLeft').animate({ opacity: 0.1 }, 250);
window.clearInterval(animationHandler);
}
$('#divfieldWidgets').animate({ scrollLeft: "-=100px" }, 250);
}
However I just can't seem to be able to find a method to determine when the DIV has hit it's limit when scrolling right.
I'm pretty sure I need some calculation based on $("#divfieldWidgets").scrollLeft() and $("#divfieldWidgets").width(), but all arithmetic calculations I've performed on those two values don't yield any results that show any relation to the width, it's maximum, etc, etc.
There is ONE final option I thought of, and that's storing the current scrollLeft value in a temporary variable and comparing the new value; if there's no change, then it's reached the end but I'm sure there must be a more cleaner way of achieving this.
Any thoughts?
You could use something like
$(function() {
$('#lorem').scroll( function() {
if ( $('#lorem').scrollLeft() == ($('#lorem p').width() - $('#lorem').width())) {
alert('end!');
}
});
});
As shown here
I'd suggest store width on ready in variables accessible inside the scroll event
a = $('#lorem p').width();
b = $('#lorem').width();
and use them in function
if ( $('#lorem').scrollLeft() == (a - b)) {
// rest of the code
}
This way, you'll save a couple of more function calls on scroll. As it is a very costly event that you should be using only if there is no other solution.
Ideally, you should use throttled function calls like this. Which will delay the function call and save a lot of resources.
I have a long jQuery mobile page and would like to scroll to an element halfway down this page after the page loads.
So far I've tried a few things, the most successful being:
jQuery(document).bind("mobileinit", function() {
var target;
// if there's an element with id 'current_user'
if ($("#current_user").length > 0) {
// find this element's offset position
target = $("#current_user").get(0).offsetTop;
// scroll the page to that position
return $.mobile.silentScroll(target);
}
});
This works but then the page position is reset when the DOM is fully loaded. Can anyone suggest a better approach?
Thanks
A bit late, but I think I have a reliable solution with no need for setTimeout(). After a quick look into the code, it seems that JQM 1.2.0 issues a silentScroll(0) on window.load for chromeless viewport on iOS. See jquery.mobile-1.2.0.js, line 9145:
// window load event
// hide iOS browser chrome on load
$window.load( $.mobile.silentScroll );
What happens is that this conflicts with applicative calls to silentScroll(). Called too early, the framework scrolls back to top. Called too late, the UI flashes.
The solution is to bind a one-shot handler to the 'silentscroll' event that calls window.scrollTo() directly (silentScroll() is little more than an asynchronous window.scrollTo() anyway). That way, we capture the first JQM-issued silentScroll(0) and scroll to our position immediately.
For example, here is the code I use for deep linking to named elements (be sure to disable ajax load on inbound links with data-ajax="false"). Known anchor names are #unread and #p<ID>. The header is fixed and uses the #header ID.
$(document).bind('pageshow',function(e) {
var $anchor;
console.log("location.hash="+location.hash);
if (location.hash == "#unread" || location.hash.substr(0,2) == "#p") {
// Use anchor name as ID for the element to scroll to.
$anchor = $(location.hash);
}
if ($anchor) {
// Get y pos of anchor element.
var pos = $anchor.offset().top;
// Our header is fixed so offset pos by height.
pos -= $('#header').outerHeight();
// Don't use silentScroll() as it interferes with the automatic
// silentScroll(0) call done by JQM on page load. Instead, register
// a one-shot 'silentscroll' handler that performs a plain
// window.scrollTo() afterward.
$(document).bind('silentscroll',function(e,data) {
$(this).unbind(e);
window.scrollTo(0, pos);
});
}
});
No more UI flashes, and it seems to work reliably.
The event you're looking for is "pageshow".
I was digging a lot this issue, also at jQuery mobile official forum.
Currently it seems that there is no solution (at least for me).
I tried different events (mobileinit, pageshow) and different functions (silentscroll, scrolltop) as suggested above, but, as a result, I always have page scrolled until all images and html is finished loading, when page is scrolled to top again!
Partial and not really efficient solution is using a timer as suggested in comment to sgliser's answer; unfortunately with a timeout is difficult to know when page will be fully loaded and if scroll happened before that, it will scroll back to top at the end of load, while if it happens too long after page has fully loaded, the user is already scrolling page manually, and further automated scroll will create confusion.
Additionally, would be useful to have silentscroll or other function to address a specific id or class and not plain pixels, because with different browsers, resolutions and devices it may give different and not correct positioning of the scroll.
Hope someone will find a smarter and more efficient solution than this.