Возвращает значение из окна.

Недавно мы обнаружили, что Chrome больше не поддерживает window.showModalDialog, что является проблематичным, потому что наше корпоративное приложение использует этот метод.

Существует, по-видимому, краткое временное решение, которое позволяет восстановить showModalDialog, но это связано с изменением реестра, который является слишком сложным (и рискованным) четырьмя нашими обычными пользователями. Поэтому я не большой поклонник этого решения.

Долгосрочное решение, очевидно, должно удалить все вызовы этого устаревшего метода и заменить их удобным плагином jQuery (например, VistaPrint Skinny Modal Dialog plugin, например Другие предложения приветствуются, кстати).

Типичным сценарием, который мы используем модальным диалогом, является запрос пользователю подтверждения "Да/Нет" перед выполнением действия, которое не может быть отменено, попросить пользователя согласиться с условиями и условиями перед продолжением и т.д. Обычно событие onclick на Кнопка "Да" или "Хорошо" в модальном диалоге выглядит следующим образом:

window.returnValue = true;
window.close();

Аналогично, кнопка "Отмена" или "Нет" выглядит так:

window.returnValue = false;
window.close();

Тот факт, что мы можем вернуть значение из диалога, очень удобен, потому что он позволяет уведомлять "родительское" окно о том, нажал ли пользователь кнопку "ОК" или "Отменить":

var options = "center:1;status:1;menubar:0;toolbar:0;dialogWidth:875px;dialogHeight:650px";
var termsOfServiceAccepted = window.showModalDialog(myUrl, null, options);
if (termsOfServiceAccepted) {
    ... proceed ...
}

Последнее, что я расскажу о showModalDialog, это то, что он отлично работает, даже когда документ, отображаемый в диалоговом окне, происходит из другого домена. Для нас очень распространено, что наш javascript работает от http://the-client.com, но веб-страница "Условия обслуживания" находится в < а2 >

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

  • минимальное изменение кода в существующем JavaScript
  • всплывающее окно должно иметь возможность вернуть значение в "родительский". Обычно это значение является логическим, но может быть любым простым типом (например: string, int и т.д.). Решение
  • должно работать, даже если URL-адрес контента находится в другом домене

Вот что я до сих пор:

1) Добавьте в мой JavaScript следующий метод:

function OpenDialog(url, width, height, callback)
{
    var win = window.open(url, "MyDialog", width, height, "menubar=0,toolbar=0");
    var timer = setInterval(function ()
    {
        if (win.closed)
        {
            clearInterval(timer);
            var returnValue = win.returnValue;
            callback(returnValue);
        }
    }, 500);
}

Как вы можете видеть в этом методе, я стараюсь, чтобы всплывающее окно выглядело как похожее на диалог, по возможности, скрывая меню и панель инструментов, я устанавливаю время каждые 500 миллисекунд, чтобы проверить, закрыто ли окно пользователем, и если да, получите "returnValue" и вызовите обратный вызов.

2) замените все вызовы на showModalDialog следующим образом:

OpenDialog(myUrl, 875, 650, function (termsOfServiceAccepted)
{
    if (termsOfServiceAccepted)
    {
        ... proceed ....
    }
});

Четвертым параметром метода является обратный вызов, когда я проверяю, нажал ли пользователь кнопку "ОК", прежде чем разрешить ей продолжить.

Я знаю, что это долгий вопрос, но в основном это сводится к:

  • Что вы думаете о решении, которое я предлагаю?
  • В частности, как вы думаете, я смогу получить returnValue из окна, которое было открыто с помощью window.open?
  • Любая альтернатива, которую вы можете предложить?

Ответ 1

У меня есть две идеи, которые могут вам помочь, но первая связана с CORS, поэтому вы не сможете использовать ее из разных доменов, по крайней мере, вы можете получить доступ к обеим службам и настроить их.

ПЕРВАЯ ИДЕЯ:

Первый связан с этим родным api. Вы можете создать в родительском окне глобальную функцию, подобную этой:

window.callback = function (result) {
    //Code
}

Как вы можете видеть, он получает аргумент результата, который может содержать требуемое значение boolean. Вы можете открыть всплывающее окно, используя ту же самую старую функцию window.open(url). Обработчик события popup onlick может выглядеть следующим образом:

function() {
    //Do whatever you want.
    window.opener.callback(true); //or false
}

ВТОРАЯ ИДЕЯ: Решает проблему

Другая идея, которую я получил, - использовать этот другой собственный api, чтобы инициировать событие в родительском окне, когда всплывающее окно разрешается (более известный как обмен сообщениями между документами), Поэтому вы можете сделать это из родительского окна:

window.onmessage = function (e) {
    if (e.data) {
        //Code for true
    } else {
        //Code for false
    }
};

Таким образом, вы слушаете какое-либо опубликованное сообщение в этом окне и проверяете, являются ли данные, прикрепленные к сообщению, истинными (пользователь нажимает ok во всплывающем окне) или false (пользователь нажимает на отмену во всплывающем окне).

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

window.opener.postMessage(true, '*'); //or false

Я думаю, что это решение прекрасно соответствует вашим потребностям.

ИЗМЕНИТЬ Я написал, что второе решение было также привязано к CORS, но копало глубже Я понял, что обмен сообщениями между документами не привязан к CORS