开发者

What's the best practice to add default function to jQuery Dialog open/close events?

I'm trying to define some default behaviours for my jQuery Dialogs like the following:

(function($) {
        /**
         * Overriding default options
         **/
        $.ui.dialog.defaults.bgiframe = true;
        $.ui.dialog.defaults.open = function() {
            if ($('.ui-widget-overlay').length == 0) return;
            if ($.browser.msie) {
                // scrollbar fix for IE
                $('html').css('overflow-y','hidden');
                $('html').css('overflow-x','hidden');
            } else {
                // disable scrollbar for other browsers
                $('body').css('overflow','hidden');
            }
        };
        $.ui.dialog.defaults.beforeclose = function(event, ui) {
            if ($('.ui-widget-overlay').length == 0) return;
            if ($.browser.msie) {
                // scrollbar fix for IE
                $('html').css('overflow-y','auto');
                $('html').css('overflow-x','auto');
            } else {
                // disable scrollbar开发者_如何学编程 for other browsers
                $('body').css('overflow','auto');
            }
        };
})(jQuery);

The above works when I have no custom open/beforeclose function specified when the dialog is created. So I'm wondering what is the best practice to add these functionality into all my dialogs, while preserving the ability to specify open/beforeclose functions.


You're overriding defaults here. More likely than not, you don't want to be doing that. You're reaching in and tinkering with how the plugin itself was written, essentially. The way that you should be attaching these kinds of behaviors is by passing it into the config when you initialize your jQueryUI dialog:

$('some selector').dialog({
    bgiframe: true,
    open: function() { /* your code */ },
    beforeclose: function(event, ui) { /* your code */ }
});

Even more correctly, what you should be doing to conform to what the API specifies is initializing the dialog as normal, and then subsequently binding to its events:

var $dialog = $('some selector');
$dialog.dialog({ /* your config */ });
$dialog.bind('dialogopen', function() { /* your code */ });
$dialog.bind('dialogbeforeclose', function(event, ui) { /* your code */ });

It seems like a deeper problem is that you're not used to jQuery just yet. I think if you spend a little time reading some established jQuery code on GitHub, you'll get the hang of it pretty quickly.

Also, as a side note, I would be cautious about applying CSS properties directly to body and html on dialog load; if these things aren't things that can go in your CSS to begin with, they're not going to be any safer to do when someone interacts with the application. Try to select something more specific, or simply apply these things with conditional CSS.


Okay, I think I figured this out. Following is the least intrusive way of extending jQuery UI functions by attaching the events in _init function.

(function($) {
        /**
         * Overriding default options
         **/
        $.ui.dialog.defaults.bgiframe = true;

        var _init = $.ui.dialog.prototype._init;
        $.ui.dialog.prototype._init = function() {
            _init.apply(this, arguments);
            // only applying these function for modal dialog
            if (this.options.modal) {
                this.uiDialog.bind('dialogopen.ui-dialog', function() {
                    if ($.browser.msie) {
                        // scrollbar fix for IE
                        $('html').css('overflow-y','hidden');
                        $('html').css('overflow-x','hidden');
                    } else {
                        // disable scrollbar for other browsers
                        $('body').css('overflow','hidden');
                    }
                }).bind('dialogbeforeclose.ui-dialog', function() {
                    if ($.browser.msie) {
                        // scrollbar fix for IE
                        $('html').css('overflow-y','auto');
                        $('html').css('overflow-x','auto');
                    } else {
                        // disable scrollbar for other browsers
                        $('body').css('overflow','auto');
                    }
                });
            }
        }
})(jQuery);


This is now better achieved by listening to events instead of modifying the dialog prototype. The following code disables document scrollbars when a modal dialog is open. It re-enables them when all modal dialogs are closed (remember there can be more than one!).

$(document)
  .on('dialogopen', function(e) {
    var $el = $(e.target);
    // Modal dialogs should disable scrollbars
    if ($el.dialog('option', 'modal')) {
      $el.addClass('modal-dialog');
      $('body').css({overflow: 'hidden'});
    }
  })
  .on('dialogclose', function(e) {
    // Restore scrollbars when closing modal
    if ($('.ui-dialog .modal-dialog:visible').not(e.target).length < 1) {
      $('body').css({overflow: ''});
    }
  });
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜