2014-09-10 3 views
11

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

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

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

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

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, но веб-страница «Условия обслуживания» от http://the-enterprise-vendor.com

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

  • минимальное изменение кода в существующий JavaScript
  • всплывающее окно должно быть в состоянии вернуть значение «родительских». Обычно это значение является логическим, но это может быть любой простой тип (например: строка, 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 .... 
    } 
}); 

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

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

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

Взгляните на этот ответ: HTTP://stackoverflow.com/a/9276310/1086511 – Rodrigo

+0

В зависимости от того, будете ли вы продолжать использовать только в хроме, вы можете пойти с 'showModal' и'

': http://stackoverflow.com/questions/43183930/how- to-use-showmodal-to-full-block-content-outside-as-sold – cregox

ответ

12

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

FIRST IDEA:

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

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

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

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

ВТОРОЙ IDEA: Решает проблему

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

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

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

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

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

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

EDIT Я написал, что второе решение было также связано с CORS, но копать глубже я понял, что обмен сообщениями между документами не привязан к CORS

+0

Я пробовал вашу первую идею, но получаю «Доступ запрещен» при попытке вызвать метод «обратного вызова». Переходя к вашему второму предложению ... – desautelsj

+1

Я пробовал вашу вторую идею с некоторым успехом.Я смог «postMessage» из всплывающего окна в его открыватель, но, по-видимому, IE (как это ни невероятно) не поддерживает сообщения между разными окнами (вы получаете сообщение об ошибке об неизвестном интерфейсе). Итак, моим решением будет обнаружение поддержки showModalDialog и использование решения для обмена сообщениями, только если модальные диалоги не поддерживаются. – desautelsj

+0

Можно ли построить полные двунаправленные протоколы связи между двумя окнами, используя эту технику (вторая идея)? – Victoria

Смежные вопросы