ShowModalDialog альтернатива?

Я управляю старым сайтом, который пронизан всплывающими окнами. Они очень раздражают, потому что они теряются за главным окном. Я медленно перемещаю их до более современного "лайтбокса", но это медленный и утомительный процесс, потому что все эти всплывающие окна содержат формы, а валидация выполняется на стороне сервера, что означает, что я должен иметь возможность отправить форму, а затем повторите его, если есть ошибка, не разбирая всю страницу.

Я только что обнаружил window.showDialogBox, который отлично работает в Firefox (не позволяет вам щелкнуть главную страницу, пока вы не закроете диалог), но Chrome уже устарел это, и IE поддерживает только половину.

Итак, есть ли что-нибудь, что я могу заменить window.open тем временем, чтобы обеспечить лучший пользовательский интерфейс, не переписывая каждую форму для отправки и приема JSON через XHR?

Ответ 1

Вы можете использовать showModalDialog polyfill с помощью нового модального элемента <dialog>, который работает в новейшем Google Chrome. A <dialog> polyfill для старых браузеров здесь.

Ответ 2

Вы можете использовать разные коды для разных браузеров, например:

if(navigator.userAgent.indexOf("MSIE") != -1){     //If the browser is IE
     //Code for IE
}
else if(navigator.vendor == "Firefox"){            //If the browser is Firefox
     //Code for Firefox
}
else if(navigator.vendor == "Google Inc."){        //If the browser is Chrome
     //Code for Chrome
}

Для IE showModalDialog работает просто отлично, и он не позволяет вам щелкнуть главную страницу, пока вы не закроете диалог.
Для Firefox вы можете использовать, как вы сказали, showDialogBox.
Для Chrome вы можете использовать то, что предлагает niutech.

В противном случае, если вы используете window.open, все всплывающие окна будут находиться на панели задач, поэтому, если они скрыты за окном, просто нажмите на них на панели задач, чтобы сделать их видимыми.

Ответ 3

здесь мой код:

/**
 * May 2015: showModalDialog will not be supported any longer, so, if not available, we need to make a pure
 * window.open and a catch which callbacks.
 * 
 * In contradiction to other solutions, this "emulator" is capable of loading 
 * cross-origin urls such as oAuth2 redirect cascades, which can not be put in to iframes or dialogs due to
 * their CSSP settings!
 * 
 * Flow control of the caller needs to take care whether a window is returned or false
 * 
 * @constructor showModalDialogHandler(callback) - callback is called, if window is closed.
 *
 */
var showModalDialogHandler = function(callback)
{
    this.modalDialogEmulator = null;
    this.callBack = callback;
    this.returnImmediately = false;
    this.modalDialog = false;
    this.maxRuns = 180;
    this.intervall = 750;
    this.force = false;             // if set to true, emulate always.
    this.chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
    /**
     * make the call, open a dialog, load etc.
     *
     * @param url - URL to load
     * @param arg - args to pass to the window
     * @param feature - featurelist as of window.open
     * @return - erturns a window object (if modal dialogs are supported) or false otherwise
     *
     */
    this.callModalDialog = function(url, arg, feature) {
        var self = this;

        if ( !this.force && window.showModalDialog )
            this.modalDialog = window.showModalDialog(url, arg, feature );
        else
        {
            this.modalDialog = this.modalDialogEmulator(url, arg, feature );
            window.setTimeout(function () {
                self.modalDialog.focus();
            }, 20);

            /*
             * Catch lose focus on main window. Modal dialog should at least
             * stay in front of the opener. If the opener gets focus,
             * window is either shuffled up or closed and reopend (chrome).
             *
             */
            jQuery(window).bind("focus", function() {
                //console.log("opener focus");
                if ( self.chrome )
                {
                    // brute force: close and reopen, hope it will cope with that !!!
                    if( !self.modalDialog.closed )
                    {
                        self.modalDialog.close();
                        self.modalDialog = self.modalDialogEmulator(url, arg, feature );    
                    }
                }
                else
                {
                    if( !self.modalDialog.closed )
                    {
                        window.setTimeout(function () {
                            self.modalDialog.blur();
                            self.modalDialog.focus();
                        }, 30);
                    }
                    else
                    {
                        jQuery(window).unbind("focus"); // remove that listener, cpu-sucker.
                    }
                }
            }); 
        }

        if ( this.returnImmediately )
        {
            var runs = this.maxRuns;
            var loop = setInterval(function() {
                if(self.modalDialog.closed)
                {
                    //console.log("close catched, callback:");
                    clearInterval(loop);
                    self.callBack();
                }
                if ( runs-- <= 0 )
                    clearInterval(loop); // infinitystopper
            }, this.intervall );
            return false;
        }
        else
            return this.modalDialog;

    };

    /*
     * showModalDialog is not longer supported, emulate with popup and
     * a catcher with returnImmediately
     */
    if ( this.force || !window.showModalDialog)
    {
        var self = this;
        this.modalDialogEmulator = function(url, arg, feature) {
            // console.log("window.ShowModalDialog not supported");
            self.returnImmediately = true;
            var opFeature = feature.split(";");
            var featuresArray = new Array()
            if (document.all)
            {
                for (var i = 0; i < opFeature.length - 1; i++)
                {
                    var f = opFeature[i].split("=");
                    featuresArray[f[0]] = f[1];
                }
            }
            else
            {
                for (var i = 0; i < opFeature.length - 1; i++)
                {
                    var f = opFeature[i].split(":");
                    featuresArray[f[0].toString().trim().toLowerCase()] = f[1].toString().trim();
                }
            }

            var h = "200px", w = "400px", l = "100px", t = "100px", r = "yes", c = "yes", s = "no";
            if (featuresArray["dialogheight"]) h = featuresArray["dialogheight"];
            if (featuresArray["dialogwidth"]) w = featuresArray["dialogwidth"];
            if (featuresArray["dialogleft"]) l = featuresArray["dialogleft"];
            if (featuresArray["dialogtop"]) t = featuresArray["dialogtop"];
            if (featuresArray["resizable"]) r = featuresArray["resizable"];
            if (featuresArray["center"]) c = featuresArray["center"];
            if (featuresArray["status"]) s = featuresArray["status"];
            var modelFeature = "height = " + h + ",width = " + w + ",left=" + l + ",top=" + t
                        + ",model=yes,alwaysRaised=yes" + ",resizable= " + r + ",center=" + c
                        + ",dependent=yes,dialog=yes,modal=yes,close=0"
                        + ",status=" + s;

            var model = window.open(url, "modal", modelFeature, null);
            return model;
        };
    }

}

требуется jQuery, по крайней мере.

Ответ 4

вы можете проверить эту ссылку для jQuery Modal, чтобы использовать этот код, вам нужно включить jquery-ui javascript и css файлы