3
\$\begingroup\$

This is my first attempt at JavaScript, so I am looking to learn.

I have a website that has jQuery built in and I wanted to leverage that in the following way:

  1. I want to get a number variable that precedes a certain text string (*n*/portal.css)
  2. Get the name of the current webpage
  3. Use this number and pageName to help build a URL to a specifically named image file The image will have the same name as the webpage with an "_hd.jpg" appended to it
  4. Check if the image file exists and if it does add this image to a CSS div background otherwise do nothing
<script>

    $(function () {
        $(document).foundation();
        //get webpage name
        var loc = window.location.href
        var fileNameIndex = loc.lastIndexOf("/") + 1;
        var dotIndex = loc.lastIndexOf('.');
        var pageName = loc.substring(fileNameIndex, dotIndex < fileNameIndex ? loc.length : dotIndex);

        //get number variable
        var head = document.head
        var portalCss = head.innerHTML.match(/\/[0-9]+\/portal.css/);

        var portalNum = portalCss[0].replace("/", "")
        portalNum = portalNum.replace("portal.css", "")

        //build url for image
        var HeaderImgUrl = '/Portals/' + portalNum + '/Images/' + pageName + '_hd.jpg'

        //check if image exists and assign css values to css class RowPageHeader
        $.ajax({
            url: HeaderImgUrl, //or your url
            success: function (data) {
                $(".RowPageHeader").css("background-image", "url(" + HeaderImgUrl + ")");
                $(".RowPageHeader").css("background-position", "center top");
                $(".RowPageHeader").css("background-size", "100% auto");
                $(".RowPageHeader").css("background-repeat", "no-repeat");
                $(".RowPageHeader").css("overflow", "hidden");
            },
        })

        var FooterImgUrl = '/Portals/' + portalNum + '/Images/footer_bg.jpg'

        $.ajax({
            url: FooterImgUrl, //or your url
            success: function (data) {
                $(".RowFooter").css("background-image", "url(" + FooterImgUrl + ")");
                $(".RowFooter").css("background-position", "center top");
                $(".RowFooter").css("background-size", "2000px auto");
                $(".RowFooter").css("background-repeat", "no-repeat");
                $(".RowFooter").css("overflow", "hidden");
            },
        })

    })

</script>

Two questions:

  1. How can I improve this code?
  2. I want to move the CSS rules into a CSS class in the pages skin.css file. How can I add a CSS class to the existing one that I am adding the CSS rules to?
\$\endgroup\$
  • \$\begingroup\$ Can you give some sample inputs? It's hard to understand the code when you don't know the input. \$\endgroup\$ – Joseph Oct 24 '13 at 2:30
  • \$\begingroup\$ sure, the only inputs are the url of the website page (ie www.website.com/MyPage or www.website.com/MyPage.aspx) and the regex search for "n/portal.css" where n is an integer that I want to extract. The css classes are hard coded in because they will never change (RowPageHeader and RowFooter). Does this help @JosephtheDreamer? \$\endgroup\$ – J King Oct 24 '13 at 15:19
2
\$\begingroup\$

Basically every duplicated object can be made one object. And maybe use a function so you can call it when required.

If you use an IIFE like below, you can put this code in an external *.js file. It will then run asap without stalling other http requests while loading the page. Also pass in the jQuery object as a parameter so you can safely use $ instead.

  1. The configuration separation allows you to easily change things when needed. They're also grouped and give you a better overview. Compared to the other objects the cfg variable is the "local global" so you can use cfg throughout your whole script.

  2. The window object groups your functionality or component in one object. Basically one DOM object for a project is ideal imho. Allows you to access window.ComponentName in other files as well.

  3. The activation is under your control. For the moment it uses the common DOM ready event and basically just runs the init() function.

// @param ($): jquery version x?
(function ($) {
    // 1. CONFIGURATION
    var cfg = {
        rowpageheader: '.RowPageHeader',
        rowfooter: '.RowFooter',
        options: {
            header: {
                'background-position': 'center top',
                'background-size': '100% auto',
                'background-repeat': 'no-repeat',
                'overflow': 'hidden'
            },
            footer: {
                'background-position': 'center top',
                'background-size': '2000px auto',
                'background-repeat': 'no-repeat',
                'overflow': 'hidden'
            }
        },
        path: {
            portal: 'Portals',
            images: 'Images'
        },
        misc: {
            portalcss: 'portal.css',
            imagequality: '_hd.jpg',
            footerbg: 'footer_bg.jpg'
        }
    };

    // 2. DOM OBJECT
    window.Images = {
        init: function () {
            this.cacheItems();
            this.activate();
        },

        cacheItems: function () {
            this.rowPageHeader = $(cfg.rowpageheader);
            this.rowFooter = $(cfg.rowfooter);
        },

        activate: function () {
            var cfgOptions = cfg.options, 
                portalNum = this.getPortalNum(),
                pageName = this.getPageName();

            this.updateHeader(portalNum, pageName, cfgOptions.header);
            this.updateFooter(portalNum, cfgOptions.footer);
        },

        getPageName: function () {
            var loc = window.location.href,
                fileNameIndex = loc.lastIndexOf('/') + 1,
                dotIndex = loc.lastIndexOf('.');

            return loc.substring(fileNameIndex, dotIndex < fileNameIndex ? loc.length : dotIndex);
        },

        getPortalNum: function () {
            var head = document.head,
                portalcss = cfg.misc.portalcss,
                regexp = '/\/[0-9]+\/' + portalcss + '/',
                portalCss = head.innerHTML.match(regexp),
                portalNum = portalCss[0].replace('/', '');

            return portalNum.replace(portalcss, '');
        },

        updateHeader: function (portalNum, pageName, options) {
            var proj = this,
                cfgPath = cfg.path,
                headerUrl = [cfgPath.portal, portalNum, cfgPath.images, pageName, cfg.misc.imagequality];

            $.ajax({
                url: headerUrl.join('/')
            }).done(function () {
                var opt = $.extend(options, { backgroundImage: 'url(' + headerUrl + ')' });
                proj.rowPageHeader.css(opt);
            });
        },

        updateFooter: function (portalNum, options) {
            var proj = this,
                cfgPath = cfg.path,
                footerUrl = [cfgPath.portal, portalNum, cfgPath.images, cfg.misc.footerbg];

            $.ajax({
                url: footerUrl.join('/')
            }).done(function () {
                var opt = $.extend(options, { backgroundImage: 'url(' + footerUrl + ')' });
                proj.rowFooter.css(opt);
            });
        }
    };

    // 3. DOM READY
    $(function () {
        $(document).foundation();
        Images.init();
    });
} (jQuery));

Haven't checked if this works, but it should ^^

\$\endgroup\$
  • \$\begingroup\$ thats a lot to process for a first time java user. thanks, learned a lot \$\endgroup\$ – J King Oct 26 '13 at 5:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.