JavaScript >> Javascript 文檔 >  >> jQuery

帶有內置進度表的按鈕

進度條最近變得非常流行,並且有很多插件可以幫助您將進度條添加到您的網站。但是你如何自己製作一個?問題是已經有很多實現了,所以在本教程中,我們將編寫一些不同的代碼 - 內置進度表的按鈕。

它們非常適合在通過 AJAX 提交表單或加載內容時顯示進度。他們還將使用 CSS3 樣式和過渡,使它們易於定制。

HTML

在教程的第一部分,我們將編寫 HTML 標記。它以標準 HTML5 文檔的形式出現,其中包括我們稍後將討論的兩個附加資源 - styles.css 樣式表和 script.js JavaScript 文件。此外,我還包含了 jQuery 庫和來自 Google 網絡字體的 Raleway 字體。

index.html

<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8"/>
        <title>Tutorial: Buttons with built-in progress meters</title>

        <link href="http://fonts.googleapis.com/css?family=Raleway:400,700" rel="stylesheet" />

        <!-- The Stylesheets -->
        <link href="assets/css/style.css" rel="stylesheet" />

    </head>

    <body>

        <h1>Progress Buttons</h1>

        <a id="submitButton" href="#" class="progress-button">Submit</a>

        <a id="actionButton" href="#" class="progress-button green" data-loading="Working.." data-finished="Finished!" data-type="background-bar">Action!</a>

        <a id="generateButton" href="#" class="progress-button red" data-loading="Generating.." data-finished="Download" data-type="background-vertical">Generate</a>

        <h1>Progress Control</h1>

        <a id="controlButton" href="#" class="progress-button">Start</a>

        <div class="control-area">
            <a class="command increment">Increment</a>
            <a class="command set-to-1">Set to 1%</a>
            <a class="command set-to-50">Set to 50%</a>
            <a class="command finish">Finish</a>
        </div>

        <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
        <script src="assets/js/script.js"></script>

    </body>
</html>

標記非常簡單。進度按鈕被定義為常規超鏈接。為了被插件識別並變成帶有內置進度條的按鈕,它們需要有 .progress-button 班級。也可以通過設置三個data-*來配置按鈕 屬性:

  • data-type 指定將顯示哪種類型的進度條。目前支持三種類型:背景-水平 (默認),背景欄背景垂直 .
  • data-loading 指定進度條移動時顯示的文本。默認值為正在加載..
  • data-finished 保存進度完成時在按鈕上設置的文本。默認值為完成!

如果省略屬性,將使用默認值。

jQuery 代碼

在本教程的這一部分,我們將編寫 JavaScript 和 jQuery 代碼來使按鈕工作。代碼被組織為 6 個 jQuery 插件,它們共享一個通用名稱 - progressInitialize , progressStart , progressIncrement , progressTimed , progressSetprogressFinish .我在代碼中提供了很多註釋,所以你可以直接挖掘:

assets/js/script.js

$(document).ready(function(){

    // Convert all the links with the progress-button class to
    // actual buttons with progress meters.
    // You need to call this function once the page is loaded.
    // If you add buttons later, you will need to call the function only for them.

    $('.progress-button').progressInitialize();

    // Listen for clicks on the first three buttons, and start 
    // the progress animations

    $('#submitButton').click(function(e){
        e.preventDefault();

        // This function will show a progress meter for
        // the specified amount of time

        $(this).progressTimed(2);
    });

    $('#actionButton').click(function(e){
        e.preventDefault();
        $(this).progressTimed(2);
    });

    $('#generateButton').one('click', function(e){
        e.preventDefault();

        // It can take a callback

        var button = $(this);
        button.progressTimed(3, function(){

            // In this callback, you can set the href attribute of the button
            // to the URL of the generated file. For the demo, we will only 
            // set up a new event listener that alerts a message.

            button.click(function(){
                alert('Showing how a callback works!');
            });
        });
    });

    // Custom progress handling

    var controlButton = $('#controlButton');

    controlButton.click(function(e){
        e.preventDefault();

        // You can optionally call the progressStart function.
        // It will simulate activity every 2 seconds if the
        // progress meter has not been incremented.

        controlButton.progressStart();
    });

    $('.command.increment').click(function(){

        // Increment the progress bar with 10%. Pass a number
        // as an argument to increment with a different amount.

        controlButton.progressIncrement();
    });

    $('.command.set-to-1').click(function(){

        // Set the progress meter to the specified percentage

        controlButton.progressSet(1);
    });

    $('.command.set-to-50').click(function(){
        controlButton.progressSet(50);
    });

    $('.command.finish').click(function(){

        // Set the progress meter to 100% and show the done text.
        controlButton.progressFinish();
    });

});

// The progress meter functionality is available as a series of plugins.
// You can put this code in a separate file if you wish to keep things tidy.

(function($){

    // Creating a number of jQuery plugins that you can use to
    // initialize and control the progress meters.

    $.fn.progressInitialize = function(){

        // This function creates the necessary markup for the progress meter
        // and sets up a few event listeners.

        // Loop through all the buttons:

        return this.each(function(){

            var button = $(this),
                progress = 0;

            // Extract the data attributes into the options object.
            // If they are missing, they will receive default values.

            var options = $.extend({
                type:'background-horizontal',
                loading: 'Loading..',
                finished: 'Done!'
            }, button.data());

            // Add the data attributes if they are missing from the element.
            // They are used by our CSS code to show the messages
            button.attr({'data-loading': options.loading, 'data-finished': options.finished});

            // Add the needed markup for the progress bar to the button
            var bar = $('<span class="tz-bar ' + options.type + '">').appendTo(button);

            // The progress event tells the button to update the progress bar
            button.on('progress', function(e, val, absolute, finish){

                if(!button.hasClass('in-progress')){

                    // This is the first progress event for the button (or the
                    // first after it has finished in a previous run). Re-initialize
                    // the progress and remove some classes that may be left.

                    bar.show();
                    progress = 0;
                    button.removeClass('finished').addClass('in-progress')
                }

                // val, absolute and finish are event data passed by the progressIncrement
                // and progressSet methods that you can see near the end of this file.

                if(absolute){
                    progress = val;
                }
                else{
                    progress += val;
                }

                if(progress >= 100){
                    progress = 100;
                }

                if(finish){

                    button.removeClass('in-progress').addClass('finished');

                    bar.delay(500).fadeOut(function(){

                        // Trigger the custom progress-finish event
                        button.trigger('progress-finish');
                        setProgress(0);
                    });

                }

                setProgress(progress);
            });

            function setProgress(percentage){
                bar.filter('.background-horizontal,.background-bar').width(percentage+'%');
                bar.filter('.background-vertical').height(percentage+'%');
            }

        });

    };

    // progressStart simulates activity on the progress meter. Call it first,
    // if the progress is going to take a long time to finish.

    $.fn.progressStart = function(){

        var button = this.first(),
            last_progress = new Date().getTime();

        if(button.hasClass('in-progress')){
            // Don't start it a second time!
            return this;
        }

        button.on('progress', function(){
            last_progress = new Date().getTime();
        });

        // Every half a second check whether the progress 
        // has been incremented in the last two seconds

        var interval = window.setInterval(function(){

            if( new Date().getTime() > 2000+last_progress){

                // There has been no activity for two seconds. Increment the progress
                // bar a little bit to show that something is happening

                button.progressIncrement(5);
            }

        }, 500);

        button.on('progress-finish',function(){
            window.clearInterval(interval);
        });

        return button.progressIncrement(10);
    };

    $.fn.progressFinish = function(){
        return this.first().progressSet(100);
    };

    $.fn.progressIncrement = function(val){

        val = val || 10;

        var button = this.first();

        button.trigger('progress',[val])

        return this;
    };

    $.fn.progressSet = function(val){
        val = val || 10;

        var finish = false;
        if(val >= 100){
            finish = true;
        }

        return this.first().trigger('progress',[val, true, finish]);
    };

    // This function creates a progress meter that 
    // finishes in a specified amount of time.

    $.fn.progressTimed = function(seconds, cb){

        var button = this.first(),
            bar = button.find('.tz-bar');

        if(button.is('.in-progress')){
            return this;
        }

        // Set a transition declaration for the duration of the meter.
        // CSS will do the job of animating the progress bar for us.

        bar.css('transition', seconds+'s linear');
        button.progressSet(99);

        window.setTimeout(function(){
            bar.css('transition','');
            button.progressFinish();

            if($.isFunction(cb)){
                cb();
            }

        }, seconds*1000);
    };

})(jQuery);

progressInitialize 為需要更新儀表時其他函數調用的進度自定義事件設置事件偵聽器。感謝自定義事件,我們可以擁有像 progressStart 這樣完全獨立的函數 ,它管理自己的計時器和狀態 - progresInitialize 不需要知道progressStart .

另一個重要的事情是我們在按鈕上設置了兩個特殊的類 - .in-progress 當進度條移動時,.finished 當它準備好時。它們用於更新按鈕的文本,您將在下一節中看到。

CSS

我提到我們在按鈕上設置了兩個 CSS 類 - .in-progress.finished .但是添加這些類之一會如何改變按鈕的文本呢?很簡單——我們使用了一個涉及 CSS3 attr 的 CSS 技巧 運算符,當與 content 結合使用時 , 可以設置一個:before的文本 或 :之後 偽元素到元素屬性的偽元素。一旦你自己看到它就會變得更清楚(第 44-52 行):

assets/css/styles.css

.progress-button{
    display: inline-block;
    font-size:24px;
    color:#fff !important;
    text-decoration: none !important;
    padding:14px 60px;
    line-height:1;
    overflow: hidden;
    position:relative;

    box-shadow:0 1px 1px #ccc;
    border-radius:2px;

    background-color: #51b7e6;
    background-image:-webkit-linear-gradient(top, #51b7e6, #4dafdd);
    background-image:-moz-linear-gradient(top, #51b7e6, #4dafdd);
    background-image:linear-gradient(top, #51b7e6, #4dafdd);
}

/* Hide the original text of the button. Then the loading or finished
   text will be shown in the :after element above it. */

.progress-button.in-progress,
.progress-button.finished{
    color:transparent !important;
}

.progress-button.in-progress:after,
.progress-button.finished:after{
    position: absolute;
    z-index: 2;
    width: 100%;
    height: 100%;
    text-align: center;
    top: 0;
    padding-top: inherit;
    color: #fff !important;
    left: 0;
}

/* If the .in-progress class is set on the button, show the
   contents of the data-loading attribute on the butotn */

.progress-button.in-progress:after{
    content:attr(data-loading);
}

/* The same goes for the .finished class */

.progress-button.finished:after{
    content:attr(data-finished);
}

/* The colorful bar that grows depending on the progress */

.progress-button .tz-bar{
    background-color:#e667c0;
    height:3px;
    bottom:0;
    left:0;
    width:0;
    position:absolute;
    z-index:1;

    border-radius:0 0 2px 2px;

    -webkit-transition: width 0.5s, height 0.5s;
    -moz-transition: width 0.5s, height 0.5s;
    transition: width 0.5s, height 0.5s;
}

/* The bar can be either horizontal, or vertical */

.progress-button .tz-bar.background-horizontal{
    height:100%;
    border-radius:2px;
}

.progress-button .tz-bar.background-vertical{
    height:0;
    top:0;
    width:100%;
    border-radius:2px;
}

其餘代碼設置按鈕和內置進度表的樣式。在 styles.css 中 我還包括了兩個額外的顏色主題和一些其他的規則,這裡沒有給出,但是你可以通過自己瀏覽源代碼看到。

我們完成了!

我們今天編寫的代碼已準備好進行自定義。只需在您喜歡的代碼編輯器中打開 styles.css 並更改顏色、字體或樣式,使其與您的站點相匹配。通過編輯 HTML 和數據屬性來更改文本。或者您甚至可以使用一些很酷的新功能來改進代碼。在這種情況下,請務必在評論部分分享:)


Tutorial JavaScript 教程
  1. 使用 Express、TypeScript 和 Swagger 構建 REST API

  2. 在 React 中使用 Markdown 的簡單響應表。

  3. ECMAScript、TC39 和 JavaScript 的歷史

  4. 編寫 React 代碼的最佳實踐是什麼

  5. 帶有 VML 的 IE 畫布

  6. 2021年如何成為Kickass Web開發者【前端&後端技巧】

  7. 構造函數不復存在 |反應

  1. 停止使用 var 聲明變量!!!

  2. dev.to 似乎喜歡我的應用程序tripcoster.com。昨天它取得了第一歐元🙌🙌🙌

  3. 5個你可能不知道的非常有用的javascript方法

  4. React Props 初學者完整指南

  5. 使用 Node、Express 和 MongoDB 構建 REST API!

  6. Javascript 類型轉換

  7. 如何使用 FormData 和 React Hook 表單進行多部分文件上傳

  1. 重新思考 TypeScript 中的依賴注入

  2. 以動態數組為對象的下拉菜單

  3. 向 NPM 包注入後門

  4. 使用 API 從 Wikipedia 獲取數據