none
Scroll page to ANY anchor point

    Question

  • Hi

    I've created a Publishing page and added contents and Bookmarks (Anchors).  I've tried to add smooth scrolling using jquery but it doesnt work. I want to be able to scroll to ANY anchor on the page.

    I added a HTML form webpart at the top of page using SP UI. Added code from http://stackoverflow.com/questions/4198041/jquery-smooth-scroll-to-an-anchor

    $('a[href*=#]').click(function () {
        var hash = $(this).attr('href');
        hash = hash.slice(hash.indexOf('#') + 1);
        $.scrollTo(hash == 'top' ? 0 : 'a[name='+hash+']', 500);
        window.location.hash = '#' + hash;
        return false;
    });
    Does anyone have any ideas why its failing? Has anyone got this to work in SharePoint?

    Thanks
    Thursday, June 20, 2013 11:27 AM

Answers

  • Hi,

    window.scrollTo is supported but not the scrollTo on a div selected by jQuery. Thought you are using one of the scrollTo jquery plugins to get a smooth scrolling. I used the following plugin jquery.scrollTo and the code to get it working looks like this:

    $(document).ready(function(){
    		$('#s4-workspace a[href*=#]').click(
    			function (e) {
    		
    			    // Disable default click event and scrolling
    			    e.preventDefault();
    			    var hash = $(this).attr('href');
    			    hash = hash.slice(hash.indexOf('#') + 1);
    			    
    			    // Scroll to
    			    $("#s4-workspace").scrollTo(hash == 'top' ? 0 : 'a[name='+hash+']', hash == 'top' ? 0 : 'a[name='+hash+']');
    			    
    		    	window.location.hash = '#' + hash;
    			}
    		);
    });

    Along with the following references on the Master Page:

    	<script src="http://code.jquery.com/jquery-1.9.1.js" type="text/javascript"></script>
    	<script src="/_layouts/test/jquery.scrollto.js" type="text/javascript"></script>
    	<script src="/_layouts/test/test.js" type="text/javascript"></script>

    You need to adjust the path to your script references.

    You also need to remove the # from <a name="#book1"> because in this case you need to scroll ##book1.
    You can define a bookmark inside the text if you only support the name.

    Kind regards
    Stefan


    http://www.n8d.at/blog
    Follow me on Twitter: StFBauer | n8design

    Microsoft Community Contributor 2011 / 2012
    MCTS - SharePoint / WSS Configuration and Development


    Monday, June 24, 2013 9:24 AM

All replies

  • Try 
    $('a[href=#]').click(function () { in the first line

    Thanks Santhosh V

    Saturday, June 22, 2013 8:48 PM
  • The problem is that sharepoint only scrolls inside the s4-workspace div. not inside the document or body tag. The correct code is:
    // added an e for event to the function
    $('a[href*=#]').click(function (e) {
    
        // Disable default click event and scrolling
        e.preventDefault();
        var hash = $(this).attr('href');
        hash = hash.slice(hash.indexOf('#') + 1);
        
        // Scroll inside the s4-workspace
        $("#s4-workspace").scrollTo(hash == 'top' ? 0 : 'a[name='+hash+']', 500);
        window.location.hash = '#' + hash;
    });

    Hope this helps
    Kind regards
    Stefan

    http://www.n8d.at/blog
    Follow me on Twitter: StFBauer | n8design

    Microsoft Community Contributor 2011 / 2012
    MCTS - SharePoint / WSS Configuration and Development

    Saturday, June 22, 2013 10:59 PM
  • Hi

    I think the code picks up the href but the code errors with:

    TypeError: $(...).scrollTo is not a function (firefox)

    SCRIPT438: Object doesn't support property or method 'scrollTo'  (IE9)

    Does it work for you?

    Code view of page extract:

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>	
    		
    <script type="text/javascript">
    $(document).ready(function(){
    // if (jQuery) { alert("jQuery loaded"); }
    // added an e for event to the function
    $('a[href*=#]').click(function (e) {
        // Disable default click event and scrolling
        e.preventDefault();
        var hash = $(this).attr('href');
        hash = hash.slice(hash.indexOf('#') + 1);
        
        // Scroll inside the s4-workspace
        $("#s4-workspace").scrollTo(hash == 'top' ? 0 : 'a[name='+hash+']', 500);
        window.location.hash = '#' + hash;
    });
    });
    		
    </script>
    </div></td>
    	</tr>
    </table></td></tr></table></div>
    <div id="vid_87f5d8fb-7816-448e-8945-86cabe2914e9" style="display:none"></div></div>
    <p>sddsds</p>
    <p>1. <a href="#book1">hello </a></p>
    <p>2. fia</p>
    <p> </p>
    <p> </p>
    <p> </p>
    <p> </p>
    <p> </p>
    <p> </p>
    <p> </p>
    <p> </p>
    <p> </p>
    <p> </p>
    <p> </p>
    <p> </p>
    <p> </p>
    <p> </p>
    <p> </p>
    <p> </p>
    <p> </p>
    <p> </p>
    <p> </p>
    <p> </p>
    <p><a name="#book1" id="#book1" href="#">all about</a></p>
    <p> </p></div></div></td></tr></tbody></table>

    Monday, June 24, 2013 8:12 AM
  • Hi,

    window.scrollTo is supported but not the scrollTo on a div selected by jQuery. Thought you are using one of the scrollTo jquery plugins to get a smooth scrolling. I used the following plugin jquery.scrollTo and the code to get it working looks like this:

    $(document).ready(function(){
    		$('#s4-workspace a[href*=#]').click(
    			function (e) {
    		
    			    // Disable default click event and scrolling
    			    e.preventDefault();
    			    var hash = $(this).attr('href');
    			    hash = hash.slice(hash.indexOf('#') + 1);
    			    
    			    // Scroll to
    			    $("#s4-workspace").scrollTo(hash == 'top' ? 0 : 'a[name='+hash+']', hash == 'top' ? 0 : 'a[name='+hash+']');
    			    
    		    	window.location.hash = '#' + hash;
    			}
    		);
    });

    Along with the following references on the Master Page:

    	<script src="http://code.jquery.com/jquery-1.9.1.js" type="text/javascript"></script>
    	<script src="/_layouts/test/jquery.scrollto.js" type="text/javascript"></script>
    	<script src="/_layouts/test/test.js" type="text/javascript"></script>

    You need to adjust the path to your script references.

    You also need to remove the # from <a name="#book1"> because in this case you need to scroll ##book1.
    You can define a bookmark inside the text if you only support the name.

    Kind regards
    Stefan


    http://www.n8d.at/blog
    Follow me on Twitter: StFBauer | n8design

    Microsoft Community Contributor 2011 / 2012
    MCTS - SharePoint / WSS Configuration and Development


    Monday, June 24, 2013 9:24 AM
  • Hi

    Thats works! looks great Thank you.

    Just one minor thing. When the page scrolls to the destination link, the link goes about 10px too high and is covered by the ribbon.

    I could add the title again in plain text lower than the link but i think it would be nicer to offset the scroll so its approx 10 pixels.

    Does the jquery.scrollto.js require edit?

    Monday, June 24, 2013 2:25 PM
  • This has the unfortunate side effect of disabling any links to anchors located on other pages (e.g. you're on index.html and there's a link on the page to page01.html#link01, clicking that link will now have no effect).

    Any tips for overcoming that issue?

    Tuesday, December 03, 2013 4:24 PM
  • Hi Steven,

    you are right that this disables the behaviour for external links too. The trick is to compare the url in the selected hyperlink with the one of the current window. If those urls (without the hash tag) matches the use scrollTo otherwise behave as a default hyperlink.

    I sketched this out for you in the following lines of code:

    $(document).ready(function () { $('#s4-workspace a[href*=#]').click( function (e) {

    var hash = $(this).attr('href'); // get hash value just in case there is one // +1 is for removing the # hash = hash.slice(hash.indexOf('#') + 1); // get original url of the without hashUrl = url.replace("#" + hash); // Get Current url var currentUrl = window.location; // Check if hash is in there and return it with the # currentHash = currentUrl.slice(currentUrl.indexOf("#")) // generate URL without hash currentUrl = currentUrl.replace(currentHash, "") // Check if current URL of the window is the same as in the Hyperlink if (hashUrl == "" || hashUrl == currentUrl) { // Disable default click event and scrolling e.preventDefault();

    // Scroll to $("#s4-workspace").scrollTo(hash == 'top' ? 0 : 'a[name=' + hash + ']', hash == 'top' ? 0 : 'a[name=' + hash + ']'); window.location.hash = '#' + hash;
    } }

    } ); });

    Hope this helps

    Kind regards
    Stefan


    http://www.n8d.at/blog
    Follow me on Twitter: StFBauer | n8design

    Microsoft Community Contributor 2011 / 2012
    MCTS - SharePoint / WSS Configuration and Development


    Tuesday, December 03, 2013 4:57 PM
  • Stefan,

    I really, really appreciate you lending a hand here. I don't know enough about the syntax of javascript to adjust the code myself to do this, so you're saving me.

    With your new code, I first get an error Message: Expected ')' on line 27 of your code. If I comment the } element from line 27 out, I get the error Message: 'url' is undefined for line 9.

    Either way, the smooth scrolling is not working on the page.

    Fingers crossed that this was a small typo somewhere in your code?

    Tuesday, December 03, 2013 5:18 PM
  • Hi,

    yep there was some small typos in the script. Speed kills is all I can say hopefully it works now.

    <script>
    $(document).ready(function () {
        $('a[href*=#]').click(
    		function (e) {
    
    		    var hash = $(this).attr('href');
    		    // get hash value just in case there is one
    		    // +1 is for removing the #
    		    hash = hash.slice(hash.indexOf('#') + 1);
    		    // get original url of the without
    		    var hashUrl = $(this).attr("href").replace("#" + hash);
    
    		    // Get Current url
    		    var currentUrl = document.location.href;
    		    // Check if hash is in there and return it with the #
    		    var currentHash = currentUrl.slice("#"+document.location.hash);
    		    // generate URL without hash
    		    var currentUrl = currentUrl.replace(currentHash, "");
    
                        // Check if current URL of the window is the same as in the Hyperlink
    		    if (hashUrl == "" || hashUrl == currentUrl) {
    		        // Disable default click event and scrolling
    		        e.preventDefault();
    	            // Scroll to
    	            $("#s4-workspace").scrollTo(hash == 'top' ? 0 : 'a[name=' + hash + ']', hash == 'top' ? 0 : 'a[name=' + hash + ']');
    	            window.location.hash = '#' + hash;
                }
    	}
         );
    });
    </script>
    
    Please make also sure that you have jquery referenced in your site a well as the scroll.to plugin. http://plugins.jquery.com/scrollto/

    Kind regards
    Stefan


    http://www.n8d.at/blog
    Follow me on Twitter: StFBauer | n8design

    Microsoft Community Contributor 2011 / 2012
    MCTS - SharePoint / WSS Configuration and Development

    Tuesday, December 03, 2013 5:37 PM
  • I get a syntax error on the ; after the ) on line 29, but even if I remove it (or leave it, for that matter), I'm still not getting any smooth scrolling.

    I'm referencing scrollTo v1.4.7 and jQuery v1.10.2 and suspect that that isn't the issue because I can still get your original code to function.

    I feel bad that you're spending so much time on this, so if nothing jumps out at you, I don't want to keep bothering you with this.

    --------------

    Thanks to some input from a colleague, I was able to refine the code to this, which works!

    $(document).ready(function () {
        $('#s4-workspace a[href^="#"]').on('click', function (e) {
    		var elemEvt, elemDst, hashVal;
    		var stopDef = true;
    
    		if (stopDef) {
    			e.preventDefault();
    		}
    
    		elemEvt = $(this);
    		hashVal = elemEvt.attr('href').match('^#+(.*)')[1];
    
    		// Look for id, if not found then a[name]
    		elemDst = $('#' + hashVal).eq(0);
    		if (elemDst.size() == 0) {
    			elemDst = $('a[name="' + hashVal + '"]').eq(0)
    		}
    
    		// Still not found, either implicit 'top' or don't scroll at all
    		if (elemDst.size() == 0) {
    			elemDst = hashVal == 'top' ? 0 : null;
    		}
    
    		if (elemDst !== null) {
    			$("#s4-workspace").scrollTo(elemDst, {
    				axis: 'y',
    				duration: 300
    			});
    		}
    	});
    });
    

    Thanks again for your dedication to helping a stranger, Stefan.


    • Edited by ohemgee_ste7en Tuesday, December 03, 2013 8:31 PM resolved
    Tuesday, December 03, 2013 6:00 PM
  • Hello

    I am not sure if this thread is still alive or not, but I'll give it a try anyways. 
    I have been trying to have the smooth scroll to anchor from link functionality in my SharePoint Enterprise Wiki page. I am using summary links webpart to define the links at the top of a page though, could that be a problem? Because nothing so far has worked for me. I am on Sharepoint Online.


    Thursday, August 04, 2016 10:13 AM