Internet Explorer chamando window.onbeforeunload em chamadas window.open e AJAX
-
11-09-2019 - |
Pergunta
Ok, passei um tempo resolvendo esse problema e foi isso que reuni:
Se você fizer uma chamada AJAX no IE7 e tiver uma função window.onbeforeunload especificada, ela chamará a função onbeforeunload.
Se você tentar abrir uma nova janela com window.open SEM perturbar a janela atual, o onbeforeunload será chamado.
Alguém sabe como parar isso?Eu até tentei definir uma variável como TRUE e verificar essa variável na minha função onbeforeunload e ela ainda funciona!Eu só preciso parar a execução desse método para chamadas AJAX e chamadas de novas janelas.
Solução
Outra opção, provavelmente mais simples, é retornar false ao abrir o pop-up:
<a onclick="window.open(...); return false;" href="javascript:;" >my link</a>
Isso parece impedir o IE de pensar que você está saindo da página e acionando o evento.Todas as outras opções não eram particularmente viáveis para mim.
Outras dicas
OK, eu tenho tido esse problema. Eu tenho um trabalho (bastante bagunçado) para isso.
No meu caso, quero bloquear a navegação às vezes, e não outros.
Então, estou configurando uma bandeira na janela para me dizer se quero que ela seja bloqueada. Então, onde você está fazendo sua janela.
Eu tenho o script Java (ShowHelp) sendo expulso de um link:
<a href="javascript:ShowHelp('argument')" >HERE</a>
OnBeforeUnload é chamado antes do showhelp, então eu usei o OnClick para definir a bandeira
<a onclick="window.allowExit = true;" href="javascript:ShowHelp('argument')" >HERE</a>
Feio como pecado, mas parece funcionar!
Esta não é uma solução, mas uma explicação para quem está interessado. Acabei de executar um teste rápido no IE 7, e ele dispara o evento OneBeforeUnload sempre que um link for clicado, a menos que o href vá a algum lugar na mesma página: ou seja, a menos que contenha um #. Portanto, meu palpite é que os engenheiros do IE estavam pensando que, quando alguém clica em um link que não está em outro lugar da página, eles devem estar deixando a página; nesse caso, a página está prestes a descarregar. Escusado será dizer que há problemas óbvios com esse pensamento.
Imaginei que você só precisa despertar a janela.
Acabei de desativar o recurso no IE.
Eu tive o mesmo problema, no meu caso, toda a solicitação vem da chamada do Ajax, isso simplifica a solução, porque quando eu corrigi o porto com o botão padrão, fiz uma função recursiva para redirecionar todo o clique para minha função centralizada e depois despojar o clique de Rigth. Também estou copiando a solução para o Ajax Call Supporting Href Problem. Esta solução evita retornar à página anterior. Coloque o código dentro de um arquivo chamado backbutton, JS qualquer comentário Escreva para mparma@usa.net com o assunto: backbutton javascript
<!-- backbutton developed by Manuel Parma 2011-06-10 -->
<!-- email: mparma@usa.net -->
<!-- Add the next line into the <body> section as a first line -->
<!-- <script type="text/javascript" src="<path>/backbutton.js"></script> -->
<!-- Address used when backtoLogin is 1 or when there is not previous page from site -->
var returningAddress = "http://my returning address"
<!-- Message to display when an external action (back button, forward button, backspace) move without press the application buttons -->
var backButtonMessage = "Using the browser's Back button may cause a loss in data. Please use the Back and Continue buttons at the bottom of the form."
<!-- 0=no / 1=yes (assume per default that the back button will be pressed -->
<!-- and come into action if this was NOT the case) -->
var backButtonPressed = 1;
<!--This var when is setted to 1 avoid to captureEvent set backbuttonPressed to 1, otherwise unload event cannot detect the right state of backButtonPressed-->
var onbeforeunloadeventFired = 0;
<!--Indicate to logic back to first page (login) when its value is 1 otherwise the logic back to previous page out of the site-->
var backtoLogin = 0;
var DoPostBackWithOptionsHook = null;
var DoPostBackHook = null;
<!-- Check the previous status -->
if (window.name == ""){
<!-- When window.name is empty, this is indicating the first call of site -->
window.name = "L0001";
}
else {
if (window.name == "L0000_back"){
<!-- In this condition the page is returning after a foward button press -->
setBackButton(0);
window.name = "";
<!-- the system reload the page to clean the data -->
window.location.href = returningAddress;
}
else {
if (window.name.indexOf("_back") > 4){
<!-- when the word back is present, the previous call is sending a message that the back button was pressed and the site is going out -->
<!-- get the internal counter -->
var sLastValue = modifynamevalue(0);
<!-- set the count to go back -->
var iCountBack = -(sLastValue * 1);
if (backtoLogin == 1) {iCountBack++;};
if (window.history.length - 2 < -iCountBack) {
iCountBack = -(window.history.length - 2);
}
<!-- the site is flag that first page needs to reload -->
window.name = "L0000_back";
setBackButton(0);
<!-- the site is returning to the first page or previous -->
window.history.go(iCountBack);
}
else {
<!-- increase the internal counter -->
var sLastValue = modifynamevalue(+1);
window.name = "L" + sLastValue;
}
}
}
<!-- Set the events needed to manage the back and forwar button situations -->
$(document).ready(function(){
if (typeof(Sys) == "object") {
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(beginRequest);
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequest);
window.onbeforeunload = onbeforeunloadEvent;
window.onunload = unloadEvent;
DoPostBackWithOptionsHook = WebForm_DoPostBackWithOptions;
WebForm_DoPostBackWithOptions = WebForm_DoPostBackWithOptionsHook;
doPostBackHook = __doPostBack;
__doPostBack = __doPostBackHook;
}
});
function WebForm_DoPostBackWithOptionsHook(options) {
setBackButton(0);
return DoPostBackWithOptionsHook(options)
}
function __doPostBackHook(eventTarget, eventArgument) {
if (backButtonPressed == 1) {
setBackButton(0);
}
return doPostBackHook(eventTarget, eventArgument)
}
function beginRequest(sender, args) {
setBackButton(0);
<!-- setting onbeforeunloadeventFired = 1 I take care to avoid anyone changed the Backbutton until endrequest -->
onbeforeunloadeventFired = 1;
}
function endRequest(sender, args) {
onbeforeunloadeventFired = 0;
setBackButton(1);
}
<!-- unload event handler -->
function unloadEvent(evt) {
<!-- double coundition using onbeforeunloadeventFired == 1 garantee avoid problemas with redirect operations -->
if ((backButtonPressed == 1) && (onbeforeunloadeventFired == 1)) {
<!-- decrement the internal counter -->
var sLastValue = modifynamevalue(-1);
window.name = "L" + sLastValue + "_back";
}
if (DoPostBackWithOptionsHook !== null) {
WebForm_DoPostBackWithOptions = DoPostBackWithOptionsHook;
};
if (doPostBackHook !== null) {
__doPostBack = doPostBackHook;
};
}
<!-- on before unload -->
function onbeforeunloadEvent(evt) {
onbeforeunloadeventFired = 1;
if (backButtonPressed == 1) {
return backButtonMessage;
};
}
<!-- used to set right backButtonPressed-->
function setBackButton(value){
if (value == 0) {
backButtonPressed = 0;
}
else {
if (onbeforeunloadeventFired == 0) {
backButtonPressed = 1;
}
}
}
<!-- increment and decrment the internal counter stored into windows.name -->
function modifynamevalue(iIncrement){
var iCount = (window.name.substring(1, 5) * 1) + iIncrement;
if (iCount < 0) {
iCount = 0;
}
var sNewValue = iCount.toString();
sNewValue = "0000".substring(0, 4 - sNewValue.length) + sNewValue;
return sNewValue;
}
Sid_M disse um ponto válido, com o design do navegador, temos que projetar nosso aplicativo de acordo.
Por que ir para a Anchor Tag & Href para janelas pop -up, basta usar o método OnClick na etiqueta ou até mesmo tag e chamadas de janela.open
Exemplo simples de um dos meus aplicativos
<td class="popuplink" onMouseOver="this.style.cursor='hand'" onclick="javascript:openMe('img/howitworks.png', 'pndpopup', 600,650)"><u> How it works</u></td>
Você tentou remover o manipulador do evento "onbeforeunload" antes de ligar para o window.open? Isso pode ajudar, mas eu nunca testei.
Isso poderia muito possível resolver seu problema!
Porque eu tive um problema semelhante e isso fez o caminho!
window.onbeforeunload = warnFunction;
var warnRequired = true;
function warnFunction () {
if (warnRequired) return ("Please Stay! Don't go!");
return ;
}
E sempre que faço uma chamada de Ajax ou estou com outra janela, basta definir o WarnRequired como False.
Outra coisa, esteja ciente ao fazer uma chamada de Ajax de que ela é sincronizada, caso contrário, a variável pode ainda não ter sido definida! (Um gotcha desagradável!)