Thursday, August 7, 2014

SharePoint 2010: Understanding SharePoint scrolling behaviour

It’s useful to understand how the default scrolling behaviour of a SharePoint 2010 website (site) works. Instances where you may want to change this behaviour become trivial if you already understand the mechanisms that make it work. SharePoint uses JavaScript to set inline style dimensional attributes on the workspace and ribbon bar. SharePoint uses CSS to set scrolling options on the workspace based on the dimensions applied by the JavaScript. We will go over the elements, CSS and JavaScript that SharePoint has setup to provide a seamless scrolling experience.

Jump to Section



1. The HTML

1.1 s4-workspace div (s4-workspace)

S4-workspace is where all the page content for your SharePoint site is rendered; this includes items such as your site logo, web parts, s4-bodycontainer, s4-titlerow, navigation items, etc... Figure 1 shows the location of and all the content contained in the s4-workspace div.

1.2 s4-ribbonrow div (s4-ribbonrow)

s4-ribbonrow is located at the top of your screen. It contains the Site Actions menu, the breadcrumb pop-up, ribbon tabs (e.g. browse and page) and user menu. Figure 1 shows the location of and all the content contained in the s4-ribbonrow.

Figure 1


2. The CSS

SharePoint sets the CSS used for scrolling in corev4.css. Figure 2 displays the CSS for the s4-workspace; it has the properties overflow-y: scroll and overflow-x: auto. These overflow properties signify that if the current content rendered into the s4-workspace doesn’t fit within the height (overflow-y) or width (overflow-x) of the div, then a scrollbar will be provided. For example, s4-workspace has a height of 200 pixels and we render content with a height of 400 pixels. In this situation, a vertical scroll bar will appear in the s4-workspace that allows us to view the 200 pixels of content that are outside our current viewing area (viewport). Figure 3 shows an example of content being rendered that has a greater height and width than s4-workspace.
Body #s4-workspace {
 Overflow-y: scroll;
 Overflow-x: auto;
 Position: relative;
 Left: 0px;
}

Figure 2


Figure 3


3. The JavaScript

All the JavaScript that we need to look at is located in init.js. Init.js gets called when a SharePoint site is loaded. This script sets up all the event handlers required for scrolling to function properly. The default scrolling behaviour uses events that get fired when the window or s4-ribbonrow containers resize. The purpose of capturing these events is to resize s4-workspace and s4-ribbonrow, so that they fit within the viewport.

3.1 FixRibbonAndWorkspaceDimensionsForResize

Figure 4 displays the code for this function that is called whenever the browser window resizes. The purpose of it is to set the global variables g_viewportHeight and g_viewportWidth to the height and width of the viewport. The GetViewportHeight and GetViewportWidth functions are shown on lines 18 and 26 in Figure 4 and work exactly as you would expect. After setting up the global variables we call the FixRibbonandWorkspaceDimensions function to perform the resizing.
function FixRibbonAndWorkspaceDimensionsForResize()
{  ULSxSy:;
 if(g_frl)
  return;
 var vph=GetViewportHeight();
 var vpw=GetViewportWidth();
 if(g_viewportHeight==vph
  && g_viewportWidth==vpw)
 {
  return;
 }
 g_viewportHeight=vph;
 g_viewportWidth=vpw;
 window.setTimeout(FixRibbonAndWorkspaceDimensions, 0);
}

function GetViewportHeight()
{  ULSxSy:;
 if(typeof(window.innerHeight) !='undefined')
  viewportHeight=window.innerHeight;
 else
  viewportHeight=document.documentElement.clientHeight;
 return viewportHeight;
}
function GetViewportWidth()
{  ULSxSy:;
 if(typeof(window.innerWidth) !='undefined')
  viewportWidth=window.innerWidth;
 else
  viewportWidth=document.documentElement.clientWidth;
}

Figure 4


3.2 FixRibbonAndWorkspaceDimensions

This function adds inline styles for the width and height dimensions of s4-ribbonrow and s4-workspace. The FixRibbonAndWorkspaceDimensions function gets called whenever the s4-ribbonrow or window resizes.

3.2.1 s4-ribbonrow height calculation

The height of the s4-ribbonrow is based on whether the ribbon is minimized or maximized. A maximized ribbon bar means that that the browse ribbon tab is not selected. A minimized ribbon bar means that we currently have the browse ribbon tab selected. Line 1 in Figure 5 show the logic for determining the ribbon bar height based on its minimized / maximized status and line 2 calculates factors in the amount of padding applied to the s4-ribbonrow element; the actual height is set as an inline style on line 7 by combining the results of the two calculations.
var baseRibbonHeight=RibbonIsMinimized() ? 44 : 135;  // if the ribbon bar is minimized, then the height is 44.  If the ribbon bar is maximized, then the height is 135.
var ribbonHeight=baseRibbonHeight+g_wpadderHeight;  // g_wpadderHeight is set to 0 by default
if (GetCurrentEltStyle(elmRibbon, "visibility")=="hidden")
{
    ribbonHeight=0;
}
    elmRibbon.style.height=ribbonHeight+"px";  // set the ribbon bar height as an inline style element

Figure 5


3.2.2 s4-workspace height calculation

The height of s4-workspace is calculated based on the viewport height, s4-ribbonrow height and the amount of pixels applied to the margin-top css property of the s4-ribbonrow. The viewport height is obtained from the variable g_viewportHeight that was set by FixRibbonAndWorkspaceDimensionsForResize. Line 7 performs the logic to calculate the height of s4-workspace. The calculation takes the size of the viewport and subtracts the full height of the ribbon bar (includes any margins and padding). For example, s4-ribbonrow has a height of 300 pixels and margin-top property of 10 pixels. The viewport height is 800 pixels. The calculation would be 800 – 300 – 10 = 490 pixels. This means that the maximum height of the s4-workspace element can be 490 pixels. The actual height of s4-workspace is set as an inline style on line 10.
var vph=g_viewportHeight;
if (null===vph)
{
 vph=GetViewportHeight();
 g_viewportHeight=vph;
}
var newWorkspaceHeight=vph - elmRibbon.offsetHeight - AbsTop(elmRibbon);
if(newWorkspaceHeight < 0)
 newWorkspaceHeight=0;
elmWorkspace.style.height=newWorkspaceHeight+"px";

Figure 6


3.2.3 s4-workspace width calculation

SharePoint offers the option of setting the width as an inline style on s4-workspace. If s4-workspace has the class “s4-nosetwidth”, then the width will not be set as an inline style. The code that performs this check is on line 4 in Figure 7. Line 10 to 20 in Figure 7 sets the width of the s4-workspace, s4-bodycontainer and s4-titlerow elements. The width of s4-workspace is set to the viewport width on line 12.
if(!g_setWidthInited)
{
    var setWidth=true;
    if(elmWorkspace.className.indexOf("s4-nosetwidth") > -1)
        setWidth=false;
    g_setWidth=setWidth;
    g_setWidthInited=true;
}

if(setWidth)
{
    elmWorkspace.style.width=document.documentElement.clientWidth+"px";
    if(elmBodyTable.offsetWidth < elmWorkspace.clientWidth)
        elmBodyTable.style.width=elmWorkspace.clientWidth+"px";
    if(elmTitleArea)
    {
 elmTitleArea.style.width=Math.max(elmBodyTable.offsetWidth - 1, 0)+"px";
 elmTitleArea.className+=" ms-titlerowborder";
    }
}

Figure 7


3.2.4 s4-workspace scrollbar specifics

When the browser loads a page we want the slider in the scrollbar to start at the top of the element; this means that we need to give it a scroll value of zero. The code in Figure 8 sets the slider to reside at the top of the scrollbar and it modifies the CSS property overflow-y based on whether or not the current window is a dialog. I’ve added comments to the code in Figure 8 to help explain what is happening and when.
var isIE7=browseris.ie && browseris.iever==7 && !browseris.ie8standard;
if (!g_setScrollPos) // only executes once
{
    if (browseris.firefox && browseris.firefox36up) // if firefox, then scroll to the top of the page
        window.scroll(0,0); // set slider to the top of the scrollbar
    if (window.location.search.match("[?&]IsDlg=1"))
// if this is a pop-up window and we aren’t using IE7, then the overflow-y property is set to auto
// if this is a pop-up window and the scrollbar is bigger than the s4-workspace div, then set the overflow-y property auto
    {
        if (!isIE7  || elmWorkspace.scrollHeight < elmWorkspace.clientHeight)
            elmWorkspace.style.overflowY="auto";
    }
    var scrollElem=document.getElementById("_maintainWorkspaceScrollPosition");
    if (scrollElem !=null && scrollElem.value !=null)
    {
        elmWorkspace.scrollTop=scrollElem.value; // set slider to the top of the scrollbar
    }
g_setScrollPos=true;
}

Figure 8


3.2.5 Executing Additional event handlers

The last thing the FixWorkspaceAndRibbonDimensions function does is call all of the event handlers that are associated with resizing the s4-workspace. Figure 9 shows the code in the FixRibbonAndWorkspaceDimensions function that executes all of the event handlers in the g_workspaceResizedHandlers array. You can add your own function to the stack of event handlers by calling SP.UI.Workspace.add_resized(yourEventHandler) shown in Figure 10.
var handlers=[].concat(g_workspaceResizedHandlers);
for (var i=0, wLen=handlers.length; i < wLen; i++)
{
    handlers[i]();
}

Figure 9


SP.UI.Workspace.add_resized=function (handler)
{   ULSxSy:;
    g_workspaceResizedHandlers.push(handler);
};

Figure 10


4. The End

That was a lot of information to process, so let’s do a quick re-cap.
  • Whenever the browser window or an element on the page resizes the FixWorkspaceAndRibbonDimensionsForResize or FixWorkspaceAndRibbonDimensions functions are called.
  • The FixWorkspaceAndRibbonDimensionsForResize or FixWorkspaceAndRibbonDimensions functions work together to set the height and width dimensions as inline styles of the s4-workspace and s4-ribbonrow elements.
  • The CSS properties overflow-y is set as scroll and overflow-x is set as auto on s4-workspace; these properties will create a scrollbar on an element when the content exceeds the width and/or height of the containing element.
  • You can add your own function to the g_workspaceResizedHandler stack to be executed at the end of the FixWorkspaceAndRibbonDimensions function.
  • The slider on the scrollbar is programmatically set to the top of the scrollbar.
  • The s4-ribbonrow height is 44 when minimized and 135 when maximized.
  • The s4-workspace height is based on the height of s4-ribbonrow and the viewport.
  • In most situations, if our current window is a dialog, then the overflow-y property of s4-workspace will be set to auto.

You should now have a better understanding of how SharePoint creates a seamless scrolling experience for its users. The next step is to take this information and manipulate the scrolling behaviour to suit your own needs. Hopefully this information will help you in your future SharePoint 2010 branding projects.

No comments:

Post a Comment