Floating Images mess up Bootstrap Scrollspy - javascript

I have set up a page using bootstrap. (http://ethnoma.org/about.html) I have a sidebar navigation that is affixed (which is working great). I also am using bootstrap scrollspy on this navigation and all links in the navigation are within the same page (using ancors). Everything was working fine (even with a smooth-scroll plugin added). I simply had to call this script to force Scrollspy to refresh after all content is added to the page (which I placed in the <head>).
<script type="text/javascript">
// ScrollSpy
$(function () {
$('[data-spy="scroll"]').each(function () {
var $spy = $(this).scrollspy('refresh')
});
});
</script>
My client then asked me to add images to the page. I did so using bootstrap markup and css classes like the following:
<a class="pull-right pad5" href="#">
<img class="media-object img-polaroid" src="assets/img/about-001.jpg" alt="Partnership"/>
</a>
Which makes the parent "a" tag float to the right (in this case) and makes the img into a block element.
Problem is these floated images make the page longer than it was originally. Yet Scrollspy is still switching the active link at the same place. This causes scrollspy to activate links for content farther down the page than you currently are.
I am at a loss for how to force Scrollspy to take the floated images into account when calculating the location of the ID's the ancors link to. Do any of you have an idea how I could fix this. You can see the problem in effect at the following page http://ethnoma.org/about.html

I just came across this issue myself, so I thought I'd provide some explanation, and a possible solution, in case anyone else finds themselves in this bind.
First, scrollspy is working correctly. At the time that it computes the offsets of the various elements on the page, the images haven't loaded yet, so they have an effective height of 0. Later, when the images load, the browser determines their native dimensions, recalculates the page layout, and then repaints the page with the images. However, scrollspy is completely unaware that the page has been repainted, so it continues to use the stale offsets.
If you were to refresh scrollspy after all the images loaded, you'd find that the offsets would be correct. So, the question is how to do this.
One solution is to attach an onLoad event handler on every image, and then refresh scrollspy inside the handler. A simplified approach might look like this:
<script type="text/javascript">
function refreshScrollspy() {
$('[data-spy="scroll"]').each(function() {
$(this).scrollspy('refresh');
});
}
$(function() {
refreshScrollspy();
});
</script>
<img onload="refreshScrollspy()" src="assets/img/about-001.jpg" alt="Partnership"/>
Here's a working jsfiddle example. Note that that image's load handler has to be registered before the image actually loads. Otherwise, it won't get fired. That's why I'm using an inline event handler here. A more elegant solution is left to the reader.

Came across this issue myself while trying to use the Scrollspy from Bootstrap, and it seems that the script doesn't take into account of the image's height while calculating, thus causing the Scrollspy to be in accurate.
I believe this is due to that the image doesn't have a height set to it. By inspecting the page, I have found that the floating images I have included in the page had the height set to auto, and when I've set it to a specific value after media queries in the CSS, my Scrollspy was working perfectly.

Related

jquery one page scroll start at the bottom

I'm using the One Page Scroll jquery plugin (https://github.com/peachananr/onepage-scroll) and I want to have the site start from the bottom.
I have five sections, so when I added:
$( window ).load(function() { $(".main").moveTo(5); })
The page loads at the top and then immediately scrolls down to the bottom. I'm trying to avoid that: just want it to load at the bottom and then the user can navigate upwards.
I'm still learning jquery/javascript so I have a feeling this is a simple fix and thats why I couldn't find an answer in the forum.
Thanks in advance for any help or guidance.
Edit: here's the working example
This will be very difficult for two reasons:
The browser constructs the DOM from top to bottom, like stacking blocks upside down. Handlers on window.onload or $(document).ready don't run until after the page has already been built and rendered. Any delay while your scripts and content are loading will exacerbate the lag time. To affect how it looks from the very beginning, your code would need to run even before window.onload. (EDIT: You can do that with JS that's outside an event handler and physically before the elements you're rendering, but it will run before those elements exist. Among other problems, you won't know how tall anything is yet.)
Before the DOM is rendered, there is no bottom of the page. It gains height as more blocks are stacked. You can add some kind of wrapper with an absolute height, but that has its own issues.
If you really want this to work smoothly, you may need a more radical approach. I suggest you exclude the first page from the initial response, then add it dynamically afterward. You can give it an inline style="display:none" or just add it later via AJAX. Injecting content at the top will push everything else down, so you'll need to automatically scroll down as the page expands upward. If you do it right, the user should never be able to tell.
Try this:
jQuery( document ).ready(function( $ ) {
$(".main").moveTo(5);
});
".ready()" will wait for the DOM to load and then execute the script within
I would suggest you to make us of fullPage.js instead and make use of the 'active' class to determine which section will be visible on load as detailed in its docs:
Each section will be defined with a div containing the section class. The active section by default will be the first section, which is taken as the home page.
...
If you want to define a different starting point rather than the first section or the first slide of a section, just add the class active to the section and slide you want to load first.
Living demo
<div id="fullpage">
<div class="section">One</div>
<div class="section">
<div class="slide">
<div class="demo">Demo</div>Two</div>
<div class="slide">Three</div>
</div>
<div class="section active">Third</div> <!-- Active section -->
<div class="section">Four</div>
</div>

fullpage.js will only scrollOverflow after window resize

I have a fullpage.js site setup here.
The first section has no scrollOverflow, but the second section is a grid (generated using gridify), which requires (on certain screen sizes), for it to be a scrollable section.
The problem is it refuses to scroll. However, if I resize the window (even by a single pixel in any direction), then the fullpage.js scrollbar will appear for that section.
Does anyone have any idea why fullpage.js is acting this way? And how can I get the scrollbar to appear in that section without having the resize the window manually?
It's worth noting, I've been able to get the same thing working using the fullpage.js example page for scrollOverflow. That is setup right here. However, I haven't been able to figure out why it works there, but not in my original page!
That's probably because the content of your section or slide is being generated (or modified somehow) after fullPage.js gets initialized.
You should have used that javascript code inside the afterRender callback as fullPage.js documentation details:
afterRender()
This callback is fired just after the structure of the page is
generated. This is the callback you want to use to initialize other
plugins or fire any code which requires the document to be ready (as
this plugin modifies the DOM to create the resulting structure).
In any case, I believe you can solve it by calling the method reBuild provided by fullPage.js.
You can try to use it in the afterRender callback or directly after the code you use to generate the layout/content of the section to which you want to apply the scrollOverflow option.
$('#fullpage').fullpage({
//your options
});
//code used to generate the content of your section
//...
//re-building fullPage.js to detect the current content of each section
$.fn.fullpage.reBuild();
If that doesn't work, you can always try to use a timeout which should also solve it with some delay:
setTimeout(function(){
$.fn.fullpage.reBuild();
}, 1000);

How to stop loading a .JS dynamically?

I am building a website, which is having parallax effect,its almost done but i have an issue with that ,at a particular part I have some lengthy texts (hence scroll bar also present),now when i scroll the text ,the text scrolls as well as background also scrolls (which I don't want).I have tried putting things like position:fixed but it does not work.However I have observed that by disabling(not at all adding it in the index page) a particular .js (say custom.js) I achieve what I want.
My requirement is like when i hover upon the text area ,the background to be fixed(no scrolling) but text to be scrolling and when I come out of the text area,it should be like the previous case(background scrolling possible).Is it possible to disable a particular .js WRT mouse events.I have already tried a few online solutions on how to disable js and reload js but none works for me,am new to js does know much either .I have also read online that once js loads its effects cannot be removed(sticks to memory kind of thing),completely puzzled!
Any help
HERE is a SOLUTION
If you want to stop a script you can wrap your <script> tag by <noscript> tag using jquery wrap() function.
Here is an Example.
with scroll example too.

how to keep the document from autoscrolling when i add content?

i have a web app that has content like a facebook wall. when you click a button it adds more content at the end of the current content then should scroll to it. but currently if im scrolled any amount down, when i add the content the page suddenly scrolls down a seemingly random amount, and I have not added the scroll-to code yet. Why is the page auto scrolling? and how do i get it to stop?
The simplest way to do this without looking to far into what your code might be would just be offsetting what you add. So using some js find out the height the new content would add and then when you add it, scroll down that amount
While I'm not exactly sure why it's happening, I do know that you should be able to play around with CSS to avoid any scrolling while adding content to the page. If you set the body overflow to hidden PRIOR to adding the content, then setting it back to visible afterward, you should be able to prevent any scrolling from happening.
If you're using jQuery, something like this:
$(document.body).css('overflow','hidden');
// do your stuff here e.g.
for(var i=0;i<1000;i++) {
$(document.body).append('<div>some content to append here</div>');
}
$(document.body).css('overflow','visible');
NOTE: if it's a 3rd party library that's appending the content and they're using JS to scroll the page, this solution may not work.

Minor problem while loading page with jquery

I'm using the slidedeck jquery plugin which basically puts slides on my page. Everything works fine, but the problem is with the css loading part. Below these slides i have an import statement for another page. This page which i'm importing fetches quite a bit of data from the database before being completely displayed.
So whenever i open my page for a second or two the display for my page goes hay wire. The probable cause of this may be that i'm putting most of my jquery including the one for these slides in the document.onready function. So since the document is not loaded completely for that period of time slides are also not displayed. (as in they are displayed but in a weird manner......they are all over the page!!!!)
Is there some way i can make sure that my css and jquery get loaded first and then a call is made to this page which i'm importing or something like that. i just want that my display comes fine right in the beginning.
this is the slidedeck jquery plugin i'm using
slidedeck : http://www.slidedeck.com/
ahh i actually found a solution for my problem. Now what i'm doing is that i'm keeping the div (say id="slideDeckContainer") containing this slidedeck initially as hidden (using css style=display:none). Only after the page is done loading inside the $(document).ready(function(){....}); i call $('#slideDeckContainer).show(); on the div. (since the $(document).ready(function(){...}) is callled only after the page is loaded)
Definitely not the best solution but for now it works :).
instead of $(document).ready(function() { //code here }); you can use $(document).load(function() { //code here}); The load function fires after everything in the selector has loaded. In this case, we are selecting the document, so this function will run only after the CSS, javascript, and DOM have finished loading. Another suggestion is to give the DOM elements that you are loading content into a defined width and a height. This way, before the loading finishes, there will be space reserved for the loading content and it won't mess up your page layout.

Categories