Как я могу сделать так, чтобы действие Ember считалось доверенным событием, чтобы window.open завершился успешно?

Мое приложение ember должно открывать окно (через внешний JS API), и соответствующая инструкция API должна вызываться действием контроллера, поскольку затем оно должно перейти на другой маршрут.

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

Итак, если отказаться от Ember и отладить с помощью jQuery и предположить, что инструкция window.open() находится в MyLib.login(), этот код A работает:

$('#mybutton').click(() ->
  MyLib.login()
)

но этот код B не делает:

$.myNamespace = {
  myLoginFunction: () ->
    MyLib.login()
}

$('#mybutton').click(() ->
  $.myNamespace.myLoginFunction()
)

и действие ember также не будет работать, генерируя тот же код, что и B, который после отладки заключается в том, что window.open() вернет неопределенный объект.

Мои вопросы:

  • Можно ли заставить код B работать? (что имело бы большой смысл по причинам факторизации)
  • Есть ли способ, которым действие Ember также может работать?

PS: для большей прозрачности библиотека, о которой я говорю, — это Deezer JavaScript SDK.

PPS: простите мой CoffeeScript


person Dirty Henry    schedule 07.11.2014    source источник
comment
Вы уверены, что это действие действительно может открыть окно? jsbin.com/nocuhadejo/1   -  person Mateusz Nowak    schedule 10.11.2014
comment
Попробуйте $('#mybutton').click($.myNamespace.myLoginFunction)   -  person Mateusz Nowak    schedule 10.11.2014
comment
Вы правы, действие может открыть окно, ср. мой ответ для деталей.   -  person Dirty Henry    schedule 13.11.2014


Ответы (2)


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

Я знаком только с тем, как работает блокировщик всплывающих окон в Firefox (изначально реализованный в ошибке 252326). и с тех пор почти не изменился), однако другие браузеры аналогичны. Идея проста: всплывающие окна могут открываться только в ответ на явное действие пользователя. Это выходит за рамки доверенных событий, такими действиями считаются только щелчки мыши и нажатия клавиш. Все остальные всплывающие окна считаются нежелательными и будут заблокированы.

Итак, чтобы ответить на ваш вопрос:

Как я могу сделать так, чтобы действие Ember считалось доверенным событием, чтобы window.open завершился успешно?

Любой код, запускаемый в ответ на действие пользователя (имеется в виду синхронное выполнение кода), может открывать всплывающие окна. Что касается другого кода, например. отложенные действия (в том числе асинхронные обратные вызовы для синхронного кода, выполняемого в ответ на действие пользователя) или код, реагирующий на события, сгенерированные приложением — блокировщик всплывающих окон не пропустит его, и вы ничего не сможете с этим поделать. Веб-приложение не может подделывать доверенные события, так же как оно не может по своему желанию обойти блокировщик всплывающих окон (любое из них будет проблемой безопасности).

Есть ли способ, которым действие Ember также может работать?

У вас есть по существу два варианта:

  1. window.open() вернет null в Firefox, если он заблокирован (поведение в других браузерах может быть другим). Вы можете обнаружить это и попросить пользователя добавить ваш сайт в исключения блокировщика всплывающих окон. Однако большинство из них проигнорируют такие просьбы.
  2. Вы меняете способ работы вашего веб-приложения. Например. вы можете открыть пустое всплывающее окно, когда пользователь нажимает кнопку «Войти», но только позже заполнить его реальным содержимым. Или вы можете переместить действие входа во всплывающее окно. Или вы можете вообще отказаться от всплывающих окон и вместо этого отображать слой в главном окне. Твой выбор.

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

person Wladimir Palant    schedule 10.11.2014
comment
Спасибо за Ваш ответ. Это было очень ценно при отладке моей ситуации. (см. мой ответ) - person Dirty Henry; 13.11.2014

Спасибо всем за ваши комментарии и отзывы. Тем не менее, работая над своей проблемой, я могу ответить на свои вопросы.

Действия Ember ЯВЛЯЮТСЯ считающимися доверенными действиями, когда они инициируются кликом или другими пользовательскими событиями.

Моя проблема была какой-то глупой. Я понял, что моя функция login сначала вызывала функцию loginStatus, а реальный вход в систему выполнялся в асинхронном обратном вызове в зависимости от результата ответа loginStatus. Имеет смысл, что обратный вызов потерял атрибут «доверенный».

person Dirty Henry    schedule 13.11.2014
comment
И чем ваш ответ отличается от того, что я написал? То, что вы сделали, это как раз мое второе предложение. - person Wladimir Palant; 13.11.2014
comment
Это не совсем то, что я сделал, но достаточно честно, я постараюсь отредактировать ваш ответ, чтобы он не вводил в заблуждение (например, вы не можете быть менее настойчивым) и принять его. - person Dirty Henry; 13.11.2014