QuintoViento
QuintoViento

Reputation: 198

Dynamically Make CSS Class

Using this link, I created a loading bars div with HTML and CSS
http://www.paulund.co.uk/css-loading-spinners

However, now I want to use JS to create such a loading bar; I want use a function that defines css's height, width and some other attributes and that defines how many bar divs are used for the loading bar. I understand that there are many libraries out there that do such, but I'd rather not use these for now while I'm still learning JS/jQuery/CSS.

What would need to be appended to the style element would be:

        .loading{
            width: 100px;
            height: 100px;
            margin: 30px auto;
            position: relative;
        }

        .loading.bar div{
            width: 10px;
            height: 30px;
            border-radius:5px;
            background: black;
            position: absolute;
            top: 35px;
            left: 45px;
            opacity: 0.05;

            -webkit-animation: fadeit 1.1s linear infinite;
            animation: fadeit 1.1s linear infinite;
        }



        .loading.bar div:nth-child(1){
            -webkit-transform: rotate(0deg) translate(0, -30px);
            transform: rotate(0deg) translate(0, -30px);

            -webkit-animation-delay:0s;
            animation-delay:0s;
        }

Where I would need to define widths, heights, each nth-child...

So my question is the following even in the right direction at all? Also, does it even make sense to be trying to do this? I mean, I want to learn; however, I don't want to learn something that seems unnecessary.

    <script>
        function addSpinner(bar_amount, time_incr, height, width, margin){
            //
            //$('head').removeClass('load');
            $('<style>.load{width: ' + width + 'px; height: ' + height + 'px; margin: ' + margin + 'px auto; position: relative;}</style>').append('head');

            //
            $('<style>.load.brick div{width: 10px; height: 30px; border-radius:5px; background: black; position: absolute; top: 35px; left: 45px; opacity: 0.05; -webkit-animation: fadeit 1.1s linear infinite; animation: fadeit 1.1s linear infinite;}</style>').append('head');

            //
            for(var i = 0; i < bar_amount; ++i){
                var degree = i / bar_amount * 360;
                var delay = i * time_incr;

                window.alert('<style>.load.brick div:nth-child(' + (i + 1) + '){ -webkit-transform: rotate(' + degree + 'deg) translate(0, -30px); transform: rotate(' + degree + 'deg) translate(0, -30px); -webkit-animation-delay:' + delay + 's; animation-delay:' + delay + ';</style>');

                //
                $('<style>.load.brick div:nth-child(' + (i + 1) + '){-webkit-transform: rotate(' + degree + 'deg) translate(0, -30px); transform: rotate(' + degree + 'deg) translate(0, -30px); -webkit-animation-delay:' + delay + 's; animation-delay:' + delay + ';</style>').append('head');
            }


            var spinner_div = $('<div class="load brick"/>');

            for(var i = 0; i < bar_amount; ++i){
                spinner_div.append('<div/>');
            }

            return spinner_div;
        }


        $(document).ready(function(){
            var new_spinner = addSpinner(8, 0.13, 100, 100, 30);

            $('body').append(new_spinner);
        });
    </script>

Upvotes: 0

Views: 154

Answers (4)

QuintoViento
QuintoViento

Reputation: 198

As you know, I'm still learning CSS/HTML5/JS so I can not say this is the cleanest code, but I figured I'd at least post a working example. I understand that static sections do not need to be declared dynamically, but for the sake of just making an example, I left it. Thanks everyone and yes, I know I have a long way to go :)

<head>
    <script src="jquery-2.1.1.min.js"></script>


    <style>
        @-webkit-keyframes fadeit{
            0%{opacity: 1;}
            100%{opacity: 0;}
        }

        @keyframes fadeit{
            0%{opacity: 1;}
            100%{opacity: 0;}
        }

        .load{}

        .load.brick{
            width: 10px;
            height: 30px;
            border-radius:5px;
            background: black;
            position: absolute;
            top: 35px;
            left: 45px;
            opacity: 0.05;

            -webkit-animation: fadeit 1.1s linear infinite;
            animation: fadeit 1.1s linear infinite;
        }

    </style>
</head>


<body>
    <div id="spinner" class="load">
    </div>

    <script>
        function addSpinner(bar_amount, time_incr, height, width, margin){
            var spinner_div = $('#spinner');

            //
            //$('head').removeClass('load');
            $('.load ').css({'width': width + 'px',
                            'height': height + 'px',
                            'margin': margin + 'px auto',
                            'position': 'relative'});

            //
            for(var i = 0; i < bar_amount; ++i){
                var degree = i / bar_amount * 360;
                var delay = i * time_incr;
                var tile = $('<div class="load brick"></div>');

                //
                tile.css({  '-webkit-transform': 'rotate(' + degree + 'deg) translate(0, -30px)',
                            'transform': 'rotate(' + degree + 'deg) translate(0, -30px)',
                            '-webkit-animation-delay':  delay + 's',
                            'animation-delay': delay + 's'});

                //
                spinner_div.append(tile);
            }
        }


        $(document).ready(function(){
            addSpinner(9, 0.13, 100, 100, 30);
        });
    </script>


</body>

Upvotes: 0

adzza24
adzza24

Reputation: 2084

You are almost there, but the way you are adding your css to the document is unnecessary. you can do it in the following way much easier, but you have to do it after you add the spinner to the page:

$('.load.brick').css({
    'width': width + 'px',
    'height': height + 'px',
    'margin': margin + 'px auto',
    'position': 'relative'
});

Anything which won't change, such as position: relative you should not apply in the jQuery, just add this as a rule to your existing css file. The only things you need to include in your jQuery are the things that are variable. That means that the second style tag you add should go completely in your css file as it is completely static. No need to add it via jQuery as it just wastes valuable browser resources.

Also, you can join your for loops for neater, faster code:

var spinner_div = $('<div class="load brick"/>');

for(var i = 0; i < bar_amount; ++i) {
    var degree = i / bar_amount * 360,
        delay = i * time_incr,
        tile = $('<div class="tile' + i + '"></div>'

    tile.css({
        '-webkit-transform': 'rotate(' + degree + 'deg) translate(0, -30px)',
        'transform': 'rotate(' + degree + 'deg) translate(0, -30px)',
        '-webkit-animation-delay': delay + 's',
        'animation-delay': delay + 's'
    });

    spinner_div.append(tile);
}

return spinner_div;

Upvotes: 1

cs_stackX
cs_stackX

Reputation: 1527

If you're doing this purely as a learning exercise, then keep exploring, looks like you're on the right track. Since you want to use just JS/Jquery then you could use the jquery css method, then you could make things a little cleaner in your addSpinner function:

 spinner_div.css("width", width+'px');
 spinner_div.css("height", height+'px');
 spinner_div.css("margin", margin+'px');

etc.

I understand that you are just playing around with it, but if you go on to use this for a real project then it's worth noting though that adding/manipulating all these CSS styles (especially to the HTML head) like you are doing with javascript/jquery is considered bad practice - it has slow performance and makes it harder to debug. The general solution for loading divs is to just download the css from somewhere like ajax loader and then you can use simple addClass and removeClass jquery to turn the loading gifs on and off.

Upvotes: 0

user3466395
user3466395

Reputation: 100

I would use a standard spinner.css with your spinner classes and modify the style of the spinner_div as needed.

var spinner_div = $('<div class="load brick" />');
$(spinner_div).style(...)

for(...)

return spinner_div;

Upvotes: 0

Related Questions