allBlogsList

Angular directive that prevents content from loading on mobile devices

There are times when you shouldn’t load certain content on a mobile device. Large images and other content designed solely for larger screens (such as flash content which is not supported on mobile devices) not only slow down page load times but also use data which could be costly to your mobile users. Responsive grid systems such as the one provided by Zurb Foundation do a great job of showing and hiding content for the various mobile, tablet and desktop screen sizes however even though this content isn’t visible to the user it’s still downloaded.

Media queries can be used to help solve these problems based on min/max screen widths but what about the cases when you may want an entire section of a webpage to be visible only to desktop devices?  A real world example would be a current XC project where we want to show a carousel with high resolution images for desktop browsers and on mobile devices we only want to show a single smaller banner.

In order to achieve this I built an angular directive which uses a regex to check the browsers user agent order to identify the user's OS. If the regex determines that the user is browsing the site on a mobile device then an ng-if attribute with a value of false is added to the element which prevents the content from being loaded.

I created a similiar directive for demo purposes with full source code which you can view here. This simplified demo displays a random image on desktop browsers and simply doesn't display an image on mobile devices. Note that if you use chrome dev tools to emulate a mobile device you will need to refresh the page since the image was already loaded in desktop mode. 

.directive('xcDontLoadOnMobile', function ($compile) {
        return {
            restrict: 'A',
            replace: false,
            terminal: true,
            priority: 1000,
            link: function link(scope, element, attrs) {
                
                function mobileCheck() {
                    var check = false;

                    // get the first four chars of the user agent
                    var a = (navigator.userAgent || navigator.vendor || window["opera"]);

                    if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a))
                        check = true;

                    return check;
                }

                 scope["mobileCheck"] = mobileCheck;

                if (mobileCheck()) {
                    element.attr("data-ng-if", "false");    // don't show if we are on mobile   
                } 
                 

                // remove the xc-dont-load-on-mobile directive or the mobile check function will continue to run and cause a "Maximum call stack size exceeded" error 
                element.removeAttr("data-xc-dont-load-on-mobile");
                element.removeAttr("xc-dont-load-on-mobile");

                $compile(element)(scope);
            }
        };

And that's all there is to it. Now we can include the directive attribute to any element that we do not want to display on mobile devices.

To see it in action navigate to this plnkr preview from your mobile device.