If you don't want to change too much of your code, I think toggeling a flag is OK. The following is a simple, pragmatic approach.
Example form:
<input type="text" class="form" ...>
<input type="text" class="form" ...>
<select class="form" ...>
<option value=""></option>
...
</select>
Monitor changes in both iFrames:
(function(){
// This can be optimized to check against saved values on blur
$("body").on("change", ".form", function(evt){
window.top.$(window.top).trigger("change-form"); // trigger custom event in parent page
});
}());
Parent page:
(function(){
var dirty = false
$(window).on("change-form", function(){
dirty = true;
});
window.onbeforeunload = function(e) {
// Notify user only if forms are dirty
return dirty ? 'All unsaved data will be lost.' : undefined;
};
}());
This code is braindump, it's untested.
Note: If your pages are served from different domains than the parent page you'll run into cross site scripting issues. In that case you're not able to access the parent page's Javascript. Then you have to use postMessage() to send messages to your parent page's domain.
I'd suggest you to take a look at Backbone.js:
Edit 1:
Backbone can help you managing the state of your form. In Backbone a Model will represent your form data. A View - representing your form (form's inputs) - is bound to that Model. It will monitor your form fields and set() attributes on the model. A Backbone Model has its own state, you can check if the form has chnaged using e.g. the changed() method. Separating Model and View in your application is always a good idea, it helps separating the responsibilities.
I just wanted to give you another idea.
Edit 2:
Fixed the code that triggers an event in the top window. I was not sure if $(window.top)
works. It does not work. I'm not sure why. I've tested it and this code is correct:
window.top.$(window.top). ...
I've updated the above code.