js和css重寫Confirm提示窗口,支持服務器控件調用。

js和css重寫Alert和Confirm提示窗口,支持服務器控件調用。

  js自帶的Alert和Confirm窗口樣貌醜陋,且每個瀏覽器的實現方式都不一樣(彈出位置等),而且還不支持自己輸入樣式和自定義返回函數等。
  在一次.NET的web開發過程中,爲用戶提供一個刪除功能時,在用戶刪除前彈出提示框,這做起來方法很多。
  1. 可以前臺寫個按鈕(input,button)或者連接(a)標籤,又或者隨便一個標籤,然後加個click事件,在click事件中用ajax來調用服務器代碼,進行更新數據。如果你要改的代碼或者新寫的代碼是這樣的,那恭喜你,你造福了你自己和你的後來者。
  2. 使用.net自帶的服務器控件來做。如果你是在改代碼,而且時間不允許你重新構建整個表格區域,又或者是你不想改前輩們的勞動成果,那麼你很有可能就直接添加了一個服務器控件,然後添加一個onClientClick事件,直接return confirm(“xxxx”)來簡單實現一個提示窗口。
  但是作爲一個很有責任感的開發人員,作爲一個追求完美的開發者,在這前端越來越讓人眼花繚亂的前端開發世界裏,仍舊使用原生的Confirm實在是讓人心裏發麻,很不爽。所以花了點時間研究如何自定義新的彈窗來做替換。多說無益,真槍實彈纔是真,直接上代碼。

前臺HTML文件代碼和調用方法:

<!doctype html>  
<html>  
<head>  
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
    <title>模擬alert和confirm提示框</title>  
    <script src="../js/jquery-1.12.4.js"></script>
    <script src="../js/confirm.js"></script>
</head>  
<body>
    <input id="add" type="button" value="添加" onclick="AlertDemo()"/>  
    <input id="update" type="button" value="修改" onclick="ConfirmDemo()" />
    <script>
        //非服務器控件調用Alert
        function AlertDemo(){
            PlusAlert("模擬Alert彈窗", "模擬Alert成功!");
        }
        //非服務器控件調用Confirm
        function ConfirmDemo(){
            PlusConfirm("模擬Confirm彈窗", "模擬Confirm成功!", 340, function (r) {
                if (r) {
                    PlusAlert("模擬Alert彈窗", "你單擊了確定");
                } else {
                    PlusAlert("模擬Alert彈窗", "你單擊了取消");
                }
            });
        }
    </script>
</body>
</html>

生成彈窗的js代碼:

$(function () {
    //css樣式
    var strStyle = "<style type='text/css'>";
    strStyle += ".confirmPop a{text-decoration: none;}";
    strStyle += ".confirmPop{width:350px; border:#64a64b solid 1px; position:absolute;background:#fff;z-index: 9999;left: 40%;top: 40%;font-family:Microsoft Yahei;}";
    strStyle += ".confirmTitle{ background-color:#69ae4e; position:relative;}";
    strStyle += ".confirmTitle span{line-height: 30px;margin-left: 5px;font-size: 15px;color: white;}";
    strStyle += ".confirmText{ margin:20px 0;text-align: center;}.confirmText span{ font-size: 15px;}";
    strStyle += ".confirmBtnBox{ text-align:center; margin:10px 0;}";
    strStyle += ".confirmBtnBox .btn{ display:inline-block; padding:0 28px; height:30px; line-height:30px; color:#fff; background-color: #64a64b;margin: 0 10px;}";
    strStyle += ".confirmBtnBox .btn:hover{ background-color:#509236;}";
    strStyle += ".confirmGlobal{display: block; position: fixed; clear: both; z-index: 9999; left: 0px; top: 0px; bottom: 0px;border: 0px solid rgb(255, 255, 255); width: 100%; height: 100%; opacity: 0.5; background: rgb(255, 255, 255);}";
    strStyle += "</style>";
    $("head").append(strStyle)
    //js事件
    $.alerts = {
        alert: function (title, message, width, callback) {
            if (title == null) title = 'Alert';
            $.alerts._show(title, message, width, 'alert', callback);
        },
        confirm: function (title, message, width, callback) {
            if (title == null) { title = 'Confirm'; }
            return $.alerts._show(title, message, width, 'confirm', callback);
        },
        _show: function (title, msg, width, type, callback) {
            renderHtml(title, msg, width, type);
            switch (type) {
                case 'alert':
                    $("#confirmBtnSure").click(function () {
                        $.alerts._hide();
                        if (callback) {
                            callback(true);
                        }
                    });
                    $("#confirmBtnSure").focus().keypress(function (e) {
                        if (e.keyCode == 13 || e.keyCode == 27) {
                            $("#confirmBtnSure").trigger('click');
                        }
                    });
                    break;
                case 'confirm':
                    $("#confirmBtnSure").click(function () {
                        $.alerts._hide();
                        if (callback) {
                            return callback(true);
                        }
                    });
                    $("#confirmBtnCancel").click(function () {
                        $.alerts._hide();
                        if (callback) {
                            return callback(false);
                        }
                    });
                    $("#confirmBtnCancel").focus();
                    $("#confirmBtnSure, #confirmBtnCancel").keypress(function (e) {
                        if (e.keyCode == 13) {//回車
                            $("#confirmBtnSure").trigger('click');
                        }
                        if (e.keyCode == 27) {//ESC
                            $("#confirmBtnCancel").trigger('click'); 
                        }
                    });
                    break;
            }
        },
        _hide: function () {
            $("#confirmId,#confirmGlobal").remove();
        }
    }
    //修改Alert彈層提示框
    //標題-title,提示信息-altInfo,確認按鈕函數-callback,寬度-width
    PlusAlert = function (title, message, width, callback) {
        $.alerts.alert(title, message, width, callback);
    }
    //修改Confirm彈層提示框
    PlusConfirm = function (title, message, width, callback) {
        $.alerts.confirm(title, message, width, callback);
    };
})
//生成html並渲染樣式
function renderHtml(title, msg, width, type) {
    if (width) {
        strPrompt = "<div id='confirmId' style='width: " + width + "px'>";
    } else {
        strPrompt = "<div id='confirmId'>";
    }
    strPrompt += "<div id='confirmTitleDiv'><span id='confirmTitle'>" + title + "</span></div><div id='confirmTextDiv'><span id='confirmInfo'>";
    strPrompt += msg + "</span></div><div id='confirmBtnBox'>";
    strPrompt += "<a class='btn' href='javascript:void(0)' id='confirmBtnSure'>確認</a>";
    if (type == "confirm") {
        strPrompt += "<a class='btn' href='javascript:void(0)' id='confirmBtnCancel'>取消</a>";
    }
    strPrompt += "</div></div>";
    $("body").append(strPrompt)
    //遮罩層
    $("#confirmId").before("<div id='confirmGlobal'></div>")
    //手動渲染樣式
    $("#confirmId").attr("class", "confirmPop");
    $("#confirmTitleDiv").attr("class", "confirmTitle");
    $("#confirmTextDiv").attr("class", "confirmText");
    $("#confirmBtnBox").attr("class", "confirmBtnBox");
    $("#confirmBtnSure").attr("class", "btn");
    $("#confirmBtnCancel").attr("class", "btn");
    $("#confirmGlobal").attr("class", "confirmGlobal");
}

  彈窗的css樣式已經寫在了js文件中,這樣就不用再引用一次css文件,只需要引用一個js文件即可。當然將css寫到另外的文件,自己修改樣式時會更方便。
  通過以上的代碼,對非服務器控件,你完全可以實現一個自定義的alert和confirm窗口,裏面的所有東西你都可以修改,樣式完全可以根據自己的需求自定義。

  對於服務器控件,通過添加onclientclick事件,調用renturn PlusConfirm()來實現一個提示時,你會發現他的返回值永遠是true,還沒等你點擊確定或者取消,頁面已經被提交到後臺執行了。

  實現一個自定義的提示窗口,然後自定義返回函數這些都簡單,半小時一小時就能實現,煩人的是對於服務器控件,在調用了自定義窗口完成後,並不會阻塞程序,等待用戶的下一步操作指示再進行是否提交到後臺執行。

我嘗試用了while循環,結果失敗,因爲while執行的過程中你無法操作;用Timeout來做,還是失敗,延時0微妙,你還是不能操作界面,大於0秒,程序會還沒等你跑Timeout方法就已經提交到後臺執行;那就只能阻塞js的進程咯,然後找半天的結果和上面兩種差不多的結果。

經過不懈的努力,我想到了實現方法。其實上面的while和Timeout的嘗試中我已經無限接近這個答案了。

服務器控件調用自定義提示窗口的代碼:

//後臺控件調用自定義confirm窗口時,需要單擊控件後先返回false,當點擊確定時,再次模擬點擊控件。
        var IsOk = false;
        function bgControlConfirm() {
            if (IsOk) {
                return true;
            }
            PlusConfirm("模擬Confirm彈窗", "模擬服務器控件調用Confirm彈窗", 340, function (r) {
                if (r) {
                    IsOk = true;
                    document.getElementById('SignInGrid_ctl02_btnDelete').click();
                } else {
                    IsOk = false;
                }
            });
            return false;
        }
  還有一個小的提示點,在調用服務器控件的click事件時,用jquery的$(“id”).click()事件無法將頁面提交到後臺,只有用原生的js,document.getElementById(‘id’).click()的方式纔會觸發後臺事件。至於爲什麼,下回見分曉。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章