Johan Broddfelt
/* Comments on code */

Snap menu on top

This was not planned right now but I wanted to have the page look good, even in mobile devices, in order to start promoting it a bit. So here are some neat design updates. The first one is about snapping the menu to the top of the page as you scroll down. And in order to do that we need some javascript.

// Framework components

// addListner make sure that the listner work in all browsers
var addListener = function(element, eventType, handler, capture) {
  if (capture === undefined) { capture = false; }
  if (element.addEventListener) {
    element.addEventListener(eventType, handler, capture);
  } else if (element.attachEvent) {
    element.attachEvent("on" + eventType, handler);
  }
};

// Calculate the scrolled distance
function scrolltop() {
    var top = 0;
    if (typeof(window.pageYOffset) === "number") {
        top = window.pageYOffset;
    } else if (document.body && document.body.scrollTop) {
        top = document.body.scrollTop;
    } else if (document.documentElement && document.documentElement.scrollTop) {
        top = document.documentElement.scrollTop;
    }
    return top;
}

// End Framework Components


// Stick menu in the top of the browser when scrolling
addListener(window, 'scroll', fix_sidemenu);
addListener(window, 'resize', fix_sidemenu);
addListener(window, 'touchmove', fix_sidemenu);
addListener(window, 'load', fix_sidemenu);

function fix_sidemenu() {
    var w, top;
    var topHeight = document.getElementById("top").clientHeight;
    // The line below could be usefull to handle resize of windows
    //w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
    top = scrolltop();
    if (top > topHeight) {
        // Add a copy of the menu as a placeholder while we fix the original one in the top of our browser.
        if (document.getElementById("menu_clone") === null) {
            var menu = document.getElementById("menu");
            var cln = menu.cloneNode(true);
            cln.setAttribute("id", "menu_clone");
            menu.parentNode.insertBefore(cln, menu);
        }
        document.getElementById("menu").style.position = "fixed";        
        document.getElementById("menu").style.top = "0";
    } else {
        // Remove the clone from the DOM and move our real menu back into position
        if (document.getElementById("menu_clone") !== null) {
            var menu = document.getElementById("menu");
            menu.parentNode.removeChild(document.getElementById("menu_clone"));
        }
        document.getElementById("menu").style.position = "relative";
    }
}
// End Stick menu in the top of the browser when scrolling

Worth noting is that I have a section I call Framework Components. We are not going to build or use any javascript framework. Even though I am a fan of jQuery. No, we are going to user our own code. But there still are some browser differences to take into account and there are some functions that are really nice to have so for now we call them Framework Components. And we are going to add more of those as we go along. Then we come to the code that manages the menu. Changeing some css parameters depending on how far we have scrolled the page. We also need to make sure that the clone has the same style as the orignal menu so that it filles the same space. We do that by adding the clone to all #menu css styles like this:

#menu>div, #menu_clone>div {
  background: #MainDim;
  display: flex;
  justify-content: flex-start;
  flex-wrap: wrap;
  padding-left: 20px;
  padding-right: 90px;
}
#menu a, #menu_clone a {
  color: #GreyLight;
  padding: 15px;
...

The second mobile fix is that the Title and slogan of the page were to big on a mobile device, so the text ended up on top of the menu. These css rules will fix that issue.

@media screen and (max-width:500px) {
  #name {
    font-size: 2em;
    line-height: 1.1em;
  }
  #slogan {
    font-size: 0.8em;
    line-height: 0.8em;
    margin-left: 20px;
    padding-left: 30px;
  }
}

Then we want to add a drop down menu instead if the items page. So we make a copy of the items page and call it post_menu.php:

<div>
    <?php
    $post = new Post();
    $list = $post->fetchArray('WHERE publish < '' . date('Y-m-d H:i:s') . '' ORDER BY publish DESC LIMIT 20');
    foreach($list as $item) {
        ?>
        <a href="index.php?module=post&view=item&id=<?php echo $item->id; ?>">
            <div class="sub_menu_title"><?php echo $item->title; ?></div>
            <div class="sub_menu_info"><?php echo $item->posted; ?> - <?php echo $item->tags; ?></div>
        </a>
        <?php 
    }
    ?>
</div>

And of course add som styling

#sub_menu_post {
  margin: 0px !important;
  padding: 0px !important;
  background: #MainBright !important;
}
#sub_menu_post>div {
  width: 100%;
}
#sub_menu_post a {
  display: block;
  color: #GreyDark;
  text-transform: none;
  margin: 0px !important;
  padding: 0px !important;
  margin-left: 0px !important;
  padding-left: 35px !important;
  padding-right: 35px !important;
  margin-right: 0px !important;
  padding-top: 5px !important;
  padding-bottom: 5px !important;
}
#sub_menu_post a:hover, #sub_menu_post a.selected {
  background: #MainLight !important;
}
#sub_menu_post .sub_menu_title {
  
}
#sub_menu_post .sub_menu_summary {
  font-size: 0.8em;
  color: #GreyNormal;
}
#sub_menu_post .sub_menu_info {
  font-size: 0.8em;
  color: #GreyNormal;
  font-style: italic;
}

In order for this menu to be included in our main_template.php we add the following div after the menu div.

<div id="sub_menu_post" style="display: none;">
    <?php include('views/post/post_menu.php'); ?>
</div>

We also add an id "post_link" to our Post link a tag in the menu. And for the menu to acually be shown when we click on the link we have to add the following code to our javascript.

// Post sub menu
var postLink = document.getElementById('post_link');
var originalPos = 0;
addListener(postLink, 'click', post_menu);

function post_menu(e) {
    e.preventDefault();
    var content = document.getElementById('content');
    var footer = document.getElementById('footer');
    var subMenu = document.getElementById('sub_menu_post');
    if (getComputedStyle(subMenu, null).display === 'none') {
        // Store our current position so we can get back there when we close the menu
        originalPos = scrolltop();
        
        subMenu.style.display = '';
        content.style.display = 'none';
        footer.style.display = 'none';
        
        // Scroll to the top of our menu for best user experience
        var topHeight = document.getElementById("top").clientHeight;
        window.scrollTo(0, topHeight);
    } else {
        subMenu.style.display = 'none';
        content.style.display = '';
        footer.style.display = '';
        
        // Scroll back to our original position when we close the menu
        window.scrollTo(0, originalPos);
    }
}
// End Post sub menu

- Framework, JavaScript, CSS

Follow using RSS

<< Authentication and users Give your audience a voice >>

Comment

Name
Mail (Not public)
Send mail uppdates on new comments
0 comment