【程式開發筆記】完美將 Dialog 視窗固定畫面上,保證閱讀內容,JQuery Dialog - 大漠國渡

前言

我在使用 JQuery Dialog 上,遇到好多好多問題,到底是我不會使用 ,還是 JQuery Dialog 程式有 BUG😵,雖然這一點我搞不清楚,但沒關西我找到了我自己的解法💪,在此做個記錄及分享📝。

舉例個問題來說,我將 Dialog 開始在畫面正中央,但我縮放視窗大小時,Dialog 位置就跑掉了,不在正中央了😱。

再來就是,如果我再將它設定遮罩就更慘了,位置就跑掉之後就無法點即到關閉視窗的 [X] 按鈕了😱。 

以上廢話結束~ 處理的項目,如下  (本次 JQuery 版本為1.3.0)

一、自動調整 JQuery Dialog 視窗大小及位置

先舉個例子,為什麼要自動調整視窗大小及位置❓

範例一、為什麼要自動調整「視窗位置」

1. 原先視窗為瀏覽器視窗寬度為 1440。

JQuery Dialog - 範例一、為什麼要自動調整「視窗位置」

 2. 將瀏覽器視窗寬度放大至 1920 後,Dialog 視窗就沒有再視窗中間了。

JQuery Dialog - 範例一、為什麼要自動調整「視窗位置」 

範例二、為什麼要自動調整「視窗大小

 1. 原先視窗為瀏覽器視窗寬度為 1920。

JQuery Dialog - 範例二、為什麼要自動調整「視窗大小」

2. 將瀏覽器視窗寬度縮小至 1440 後,Dialog 視窗就會超過可視畫面,這時再加上禁止滾動卷軸的話,就無法關閉視窗以及觀看超過部分的內容。

JQuery Dialog - 範例二、為什麼要自動調整「視窗大小」

(一)、增加 Dialog  視窗變化監聽事件

1. 開啟 Dialog 視窗時,針對視窗大小變化時,增加監聽事件

2. 自動調整視窗大小「程式碼」如下


open : function() {

    $(window).on("resize.unable", function (e) {
        
        var newWidth = document.body.clientWidth * 0.95;
        var newHeight = document.body.clientHeight * 0.99;

        $("#dialog").dialog({ 

            width : newWidth,
            height : newHeight
                
        }); 
        
    });

}

3. 自動調整視窗位置「程式碼」如下


open : function() {

    $(window).on("resize.unable", function (e) {


        $("#dialog").dialog({ 

            position : {
    
                my : "center",
                at : "top+" + newHeight / 2,
                of : window
                
            }
                
        }); 
        
    });

}

(二)、解除 Dialog  視窗變化監聽事件


close : function() {

    $(window).unbind("resize.unable");
    
}

(三)、Dialog 監聽事件,完整內容如下


var width = document.body.clientWidth * 0.95;
var height = document.body.clientHeight * 0.99;

$("#dialog").dialog({
                
    title : title,
    width : width,
    height : height,
    modal : true,
    resizable : false,
    draggable : false,
    position : {
        
        my : "center",
        at : "top+" + height / 2,
        of : window
        
    },
    open : function() {

        $(window).on("resize.unable", function (e) {
            
            var newWidth = document.body.clientWidth * 0.95;
            var newHeight = document.body.clientHeight * 0.99;

            $("#dialog").dialog({ 
    
                width : newWidth,
                height : newHeight,
                position : {
        
                    my : "center",
                    at : "top+" + newHeight / 2,
                    of : window
                    
                }
                    
            }); 
            
        });

    },
    close : function() {

        $(window).unbind("resize.unable");
        
    }
    
});

(四)、Dialog 監聽事件調整後結果

調整結果範例一

1. 原先視窗為瀏覽器視窗寬度為 1440,Dialog 視窗寬度為 1328、高度為 648。

JQuery Dialog - 調整結果範例一

2. 將瀏覽器視窗寬度放大至 1920 後,Dialog 視窗跟著變寬為 1784、高度為 826,且依然固定在畫面中間

JQuery Dialog - 調整結果範例一

調整結果範例二

1. 原先視窗為瀏覽器視窗寬度為 1920,Dialog 視窗寬度為 1784、高度為 826。 

 JQuery Dialog - 調整結果範例二

2. 將瀏覽器視窗寬度放大至 1440後,Dialog 視窗跟著變寬為 1328、高度為 648,且仍然固定在畫面中間

 JQuery Dialog - 調整結果範例二

二、開啟 JQuery Dialog 時,禁止背景滾動

主要是透過繼承並覆寫 JQuery UI Widget 程式碼內容,來達到禁止背景滾動這件事。

第一步、繼承 JQuery UI Widget

1. 建立一個 .js 檔案。

2. 內容輸入,如下


/**
 * 
 *	繼承 JQuery Dialog 並增加功能
 *		
 *	1. 增加開啟 Dialog 時,禁止背景畫面滾動
 *
 *
 **/
 $.widget("ui.dialog", $.ui.dialog, {

	
});

第二步、覆寫 JQuery UI Widget

(一)、覆寫 open 的方法 (function),達到禁止背景滾動

 1. 取得原方法內容

這邊我麼只是需要,增加的程式碼片段,所以還是需要原碼,因此要先將原碼寫進來。

原碼的部份可以在 jquery-ui-1.13.0.custom.js 中收尋 「open: function( event ) 」字串找到,並且在「$.widget( "ui.dialog")」下。

2. 插入「程式碼片段」

(1) 增加監聽事件,偵測到滾動事件,返回最上方。

只插入此段程式碼」,使用者操作過程會感覺畫面一直抖動。


var top = $(document).scrollTop();

$(document).on("scroll.unable", function (e) {
    
    $(document).scrollTop(top);
    
});

(2) 開啟 Dialog 視窗前,隱藏超過視窗的內容,進而使卷軸消失。


$("html").css("overflow", "hidden");

3. 完整內容如下 :


/**
* 
*	繼承 JQuery Dialog 並增加功能
*		
*	1. 增加開啟 Dialog 時,禁止背景畫面滾動
*
*
**/
$.widget("ui.dialog", $.ui.dialog, {

    open : function() {

        // 禁止背景畫面滾動 - start
        var top = $(document).scrollTop();

        $(document).on("scroll.unable", function (e) {
			
            $(document).scrollTop(top);
			
        });

        // 隱藏卷軸,解決使用者說抖動問題
        $("html").css("overflow", "hidden");
		
        // 禁止背景畫面滾動 - end

        var that = this;
        
        if(this._isOpen) {
            
            if(this._moveToTop()) {
                this._focusTabbable();
            }
            
            return;
            
        }

        this._isOpen = true;
        this.opener = $($.ui.safeActiveElement(this.document[0]));

        this._size();
        this._position();
        this._createOverlay();
        this._moveToTop(null, true);

        // Ensure the overlay is moved to the top with the dialog, but only when
        // opening. The overlay shouldn't move after the dialog is open so that
        // modeless dialogs opened after the modal dialog stack properly.
        if(this.overlay) {
            this.overlay.css("z-index", this.uiDialog.css("z-index") - 1);
        }

        this._show(this.uiDialog, this.options.show, function() {
            
            that._focusTabbable();
            that._trigger("focus");
            
        });

        // Track the dialog immediately upon opening in case a focus event
        // somehow occurs outside of the dialog before an element inside the
        // dialog is focused (#10152)
        this._makeFocusTarget();
        
        this._trigger("open");

    }
    
});

(二)、覆寫 close 方法 (function),解除禁止背景滾動

 1. 取得原方法內容

這邊我麼只是需要,增加的程式碼片段,所以還是需要原碼,因此要先將原碼寫進來。

原碼的部份可以在 jquery-ui-1.13.0.custom.js 中收尋 「close: function( event ) 」字串找到,並且在「$.widget( "ui.dialog")」下。

2. 插入「程式碼片段」

(1) 解除監聽事件


$(document).unbind("scroll.unable");

(2) 超過視窗的內容,使用捲軸


$("html").css("overflow", "auto");

3. 完整內容如下 :

/**
 * 
 *	繼承 JQuery Dialog 並增加功能
 *		
 *	1. 增加開啟 Dialog 時,禁止背景畫面滾動
 *
 *
 **/
 $.widget("ui.dialog", $.ui.dialog, {

    open : function() {

        .
        .
        .

    },
    close : function(event) {
        
        var that = this;
	
        if(!this._isOpen || this._trigger("beforeClose", event) === false) {
        	return;
        }
	
        this._isOpen = false;
        this._focusedElement = null;
        this._destroyOverlay();
        this._untrackInstance();
	
        if(!this.opener.filter(":focusable").trigger("focus").length) {
	
        	// Hiding a focused element doesn't trigger blur in WebKit
        	// so in case we have nothing to focus on, explicitly blur the active element
        	// https://bugs.webkit.org/show_bug.cgi?id=47182
        	$.ui.safeBlur($.ui.safeActiveElement(this.document[0]));
        	 
        }
	
        this._hide(this.uiDialog, this.options.hide, function() {
        	
        	that._trigger("close", event);
        	 
        });
	
        // 解除背景畫面滾動 - start
        // 還原背景畫面滾動
        $(document).unbind("scroll.unable");
        
        // 還原背景畫面隱藏卷軸,解決使用者說抖動問題
        $("html").css("overflow", "auto");
        // 解除背景畫面滾動 - end
		 
    }
	
});

三、精選美景 - 周邊商品 (提供客製化服務)

大漠有設計簡單的程式碼,讓大家可以體驗一下寫程式的感覺,以及呈現結果,並將他製作成周邊商品,如 : 藍芽喇叭、拼圖、鑰匙圈、筆記本、滑鼠、滑鼠墊、鍵盤...等商品

商品類別涉及了電子產品、居家用品、杯子餐廚、服飾、旅行用品、辦公用品...等

有興趣的人可以到 大漠國渡 - 商品小舖 看看喔~  

我的優惠碼 K0999975,可享受 KUSDOM 全場 9 折優惠。 

大漠國渡 - 商品小舖 (KUSDOM)

四、精選授權圖片

如果您喜歡大漠國渡「攝影照片」的話,可以在 大漠國渡 Shutterstock 的作品集中購買喔 ~

Shutterstock 授權表
如果你也有攝影做作品要分享的話,也歡迎你加入 Shutterstock contributor

五、如果您喜歡我的內容,可以這樣贊助大漠國渡 (支持創作)

如果您喜歡我的內容,可以透過以下方式贊助大漠國渡,支持創作

Paypal : https://www.paypal.com/paypalme/jay82313tw

悠游付 (EasyWallet APP) : (390) 2202-2122-3306-1876

將來銀行 : (823) 8862-0972-6236-01

留言

  1. 回覆
    1. 灰鴿大大的用CSS也是個好方法,有機會我看看怎麼套入 JQuery Dialog

      刪除

張貼留言