开发者

How to attach submit listener to all forms including those in iframes and nested iframes

开发者 https://www.devze.com 2023-04-07 15:55 出处:网络
I want to attach an event listener to every form on my site so that when a form is submitted, a confirm box will pop up asking if the user is sure they want to proceed.If the user is not sure, I don\'

I want to attach an event listener to every form on my site so that when a form is submitted, a confirm box will pop up asking if the user is sure they want to proceed. If the user is not sure, I don't want the form to fire.

So far I have this code:

window.onload = function() {
  for(var i=0; i<document.forms.length; i++){
    document.forms[i].addEventListener("submit",formSubmit,false);
  }
}

function formSubmit(e) {
  if (confirm("Are you sure?")) {
    return tr开发者_Go百科ue;
  }
  return false;
}

Notes:

  1. I can't use jQuery
  2. I can't use an onDOMReady type function because the iframes may not have loaded yet - so window.onload is my only option (I think?)
  3. This code does not work because when the "Are you sure?" confirm box pops up when I submit a form, whichever button I click, the form still submits.
  4. This code also does not work because it does not pick up forms inside iframes. I need to not only catch forms within iframes, but also forms that may be within iframes that are within iframes...

I've tried this:

var frame = document.getElementById("frameID").contentDocument;
for(var i=0; i<frame.forms.length; i++){
  frame.forms[i].addEventListener("submit",formSubmit,false);
}

But it only works for the first frame, and it doesn't seem to work if I have got to the page via the "Back" button. Is that something to do with the way wondow.onload works?

Thanks for your help in advance!

Update

From the answer given by @Jan Pfeifer I have the following code which solves the problem of the form still submitting even when you choose "Cancel", but it does not add the listener to every form in every frame properly. I'm starting a bounty for this - can anyone make it work for nested iframes in every browser?

function attach(wnd,handler){
  for(var i=0; i<wnd.document.forms.length; i++){
    var form = wnd.document.forms[i];
    form.addEventListener('submit',handler,false);
  }

  for(var i=0; i<wnd.frames.length; i++){
    var iwnd = wnd.frames[i];               
    attach(iwnd,handler);
  }
}

function formSubmit(e){
  if(!confirm('Are you sure?')) {
    e.returnValue = false;
    if(e.preventDefault) e.preventDefault();
    return false;
  }
  return true;
}

window.addEventListener('load',function(){attach(window,formSubmit);},false);


So I've managed to solve this myself.

There were two main problems:

  1. wnd.frames[i] was sometimes returning the window of the iframe and sometimes the document depending on the browser - I've changed the method of selecting the iframe to wnd.document.getElementsByTagName("iframe")[i].contentWindow which is more reliable if a bit wordy.
  2. Chrome and IE both stopped execution if the returned window had an undefined document or name so I've added a simple if statement to catch this.

The result is this:

function attach(wnd,handler){
  if (!(wnd.document === undefined)) {
    for(var i=0; i<wnd.document.forms.length; i++){
      var form = wnd.document.forms[i];
      form.addEventListener('submit',handler,false);
      alert("Found form in " + wnd.name);
    }

    for(var i=0; i<wnd.document.getElementsByTagName("iframe").length; i++){
      var iwnd = wnd.document.getElementsByTagName("iframe")[i].contentWindow;
      alert("Found " + iwnd.name + " in " + wnd.name);
      attach(iwnd,handler);
    }
  }
}

function formSubmit(e){
  if(!confirm('Are you sure?')) {
    e.returnValue = false;
    if(e.preventDefault) e.preventDefault();
    return false;
  }
  return true;
}

window.addEventListener('load', function(){
  attach(window,formSubmit);
},false);


You will need recursion. attach function will add handler to every form and call itself on every iframe to do the same with it. Return value is not passed, so you will need to cancel the event manually.

UPDATE Corrected errors

     function attach(wnd,handler){
        for(var i=0; i<wnd.document.forms.length; i++){
            var form = wnd.document.forms[i];
                form.addEventListener('submit', handler,false);
        }

        for(var i=0; i<wnd.frames.length; i++){
            var iwnd = wnd.frames[i];               
            attach(iwnd,handler);
        }
     }

     function formSubmit(e){
        if(!confirm('Are you sure?')) {
       e.returnValue = false;
           if(e.preventDefault) e.preventDefault();
           return false;
           }
           return true;
     }

     window.addEventListener('load', function(){attach(window,formSubmit);},false);
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号