Ibo
Ibo

Reputation: 4309

Script not working outside html body tag

I have a base template that works fine with the format that I am posting here. However, I want to keep the scripts inside one block, but when I am moving one of the scripts from the body to head, the menu does not drop when clicking. How can I fix this?

html:

{% load staticfiles %}

<!DOCTYPE html>

<html lang="en" class="no-js">
    <head>
        {% block meta_tags %}{% endblock meta_tags%}


    <title>
        {% block title %}BPM App{% endblock title %} 
    </title>

    {% block stylesheets %}
        <link type="text/javascript" href="{% static 'bpmapp/js/topnavbar.js' %}">
        <link rel="shortcut icon" type="image/png" href="{{STATIC_URL}}/favicon.ico"/>
    {% endblock %}

    {% block javascript %}
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

        <script>
            $(function() {
                cbpHorizontalMenu.init();
            });
        </script>
    {% endblock javascript %}

    {% block extra_head %}{% endblock %}
    </head>

    <body>
        {% include 'bpmapp/_topnavbar.html' %}

        {% block content %}
        {% endblock content %}

        <script src="static/bpmapp/js/cbpHorizontalMenu.min.js"></script>

    </body>
</html>

cbpHorizontalMenu.min.js:

var cbpHorizontalMenu = (function() {
    var b = $("#cbp-hrmenu > ul > li"),
        g = b.children("a"),
        c = $("body"),
        d = -1;

    function f() {
        g.on("click", a);
        b.on("click", function(h) {
            h.stopPropagation()
        })
    }

    function a(j) {
        if (d !== -1) {
            b.eq(d).removeClass("cbp-hropen")
        }
        var i = $(j.currentTarget).parent("li"),
            h = i.index();
        if (d === h) {
            i.removeClass("cbp-hropen");
            d = -1
        } else {
            i.addClass("cbp-hropen");
            d = h;
            c.off("click").on("click", e)
        }
        return false
    }

    function e(h) {
        b.eq(d).removeClass("cbp-hropen");
        d = -1
    }
    return {
        init: f
    }
})();

edited to:

var cbpHorizontalMenu =$( document ).ready(function() {
    var b = $("#cbp-hrmenu > ul > li"),
        g = b.children("a"),
        c = $("body"),
        d = -1;

    $(function f() {
        g.on("click", a);
        b.on("click", function(h) {
            h.stopPropagation()
        })
    });

    $(function a(j) {
        if (d !== -1) {
            b.eq(d).removeClass("cbp-hropen")
        }
        var i = $(j.currentTarget).parent("li"),
            h = i.index();
        if (d === h) {
            i.removeClass("cbp-hropen");
            d = -1
        } else {
            i.addClass("cbp-hropen");
            d = h;
            c.off("click").on("click", e)
        }
        return false
    });

    $(function e(h) {
        b.eq(d).removeClass("cbp-hropen");
        d = -1
    }
    return {
        init: f
    });
})();

Upvotes: 1

Views: 1458

Answers (2)

axrami
axrami

Reputation: 177

The elements you are trying to augment on the DOM may not be finished loading and therefore do not exists when the javascript runs. By keeping it at the bottom of the body the elements exist when the javascript runs. You can use something like

$( document ).ready(function() {
  var cbpHorizontalMenu = {};
});

more info here https://api.jquery.com/ready/

Upvotes: 2

M0nst3R
M0nst3R

Reputation: 5283

If you are going to include your script in the head of the page (so before the body tag) there will be no escaping the need to include jQuery as part of your project (for cross browser reliabilty purposes). I suggest you download it to be able to load it locally from your disk, otherwise, here is the online link for it, you can just add this to your head (just before your own script tag) :

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

You now need to use jQuery to make sure your DOM has completely loaded before your script is executed, you do this by wrapping you whole script code inside the ready function :

$(document).ready(function () {
    var cbpHorizontalMenu = (function() {
        var b = $("#cbp-hrmenu > ul > li"),
            g = b.children("a"),
            c = $("body"),
            d = -1;

        function f() {
            g.on("click", a);
            b.on("click", function(h) {
                h.stopPropagation()
            })
        }

        function a(j) {
            if (d !== -1) {
                b.eq(d).removeClass("cbp-hropen")
            }
            var i = $(j.currentTarget).parent("li"),
                h = i.index();
            if (d === h) {
                i.removeClass("cbp-hropen");
                d = -1
            } else {
                i.addClass("cbp-hropen");
                d = h;
                c.off("click").on("click", e)
            }
            return false
        }

        function e(h) {
            b.eq(d).removeClass("cbp-hropen");
            d = -1
        }
        return {
            init: f
        }
    })();
});

Upvotes: 0

Related Questions