问题
Ok, so I have a form that loads from a request through a zip code widget from another page. THe widget populates two of the form fields immediately, on submit, on the new page. My problem is that I have a pretty complicated piece of flash on there as well that has ONE main issue. My flash is essentially a pie chart that lights up on mouseOver events and onClick events in the form check boxes. It works like it should except for the fact that on initially loading the page the javascript will not see the pre-populated check box and perform the corresponding highlighting action. This only happens in fields that are populated through the widgets, if a user checks the boxes it works fine as I have an onClick event handler attached to it. I wrote a preselect function that will determine if the field is preselected or not by a widget and then pass that on down the line to highlight it correctly (which it does as long as I have the alert functioning). Now, if I add an alert inside of the script (it doesn't matter where, as I've tried them in every function) it works like it suppose to and sees the fields that are populated immediately by the widget and highlights the corresponding field as it is suppose to. Why would an alert box be the only thing keeping this working. It is the simplest of alerts, but removing that breaks my code. Any ideas? Here is my code: (I placed three * on either side of the alert that I am talking about)
YAHOO.namespace("SOME.Place.QuoteRequest");
/**
* @projectDescription SOME.util.QuoteRequest is the namespace for all quote request related functions. This is a supplemental controller for quote request pages.
* @return (object) function executes automatically when parsed and returns references to it's public members
* @author web development
* @version 1.0
*/
SOME.PLACE.QuoteRequest = function () {
/**
* shortcuts to global objects
*/
var Dom = YAHOO.util.Dom, Event = YAHOO.util.Event;
/**
* Function to add the special error handler to the zip code area of the form. Zip code errors display in this area. Also the continue button is sometimes a submit and sometimes a button depending on whether the rest of the form is visible.
* @param {Object} frm the quote request form object
*/
var addQuoteRequestZipCodeHandler = function(frm){
if(frm.continueBtn){
Event.addListener(frm.submitBtn, "click", function(e){
var errP = Dom.get("error"), errMsg;
if(errP) errP.parentNode.removeChild(errP);
errMsg = SOME.util.Forms.validateFormField(this.zipCode.name, frm)
if(errMsg){
Event.preventDefault(e);
var p = document.createElement("p");
p.id = "error";
var pText = document.createTextNode(errMsg);
p.appendChild(pText);
Dom.insertBefore(p, "quoteZipLabel");
}
},frm, true);
}
};
/**
* Function to manage the interaction between the product checkboxes and the financial security flash wheel
*/
var CheckboxCollection = function()
{
var odom = Dom.get("finwheel");
var ochklist = Dom.getElementsByClassName("checkbox", "input", odom);
var boolArray = [false,false,false,false,false,false];
var ctr = 0;
for(var c = 0 ; c < ochklist.length ; c++)
{
switch(ochklist[c].value.toUpperCase())
{
case "AUTO": case "HOME": case "UMBRELLA": case "FARM": case "BUSINESS": //[Auto , Farm/Ranch/Crop, Home/Reuters, Umbrella, business]
if(ochklist[c].checked && ctr == 0)
{
***alert("auto checked");***
boolArray[ctr] = ochklist[c].checked;
ctr = ctr+1;
}
break;
case "LIFE": // [Life]
if(ctr == 0)
{
boolArray[ctr] = false;
ctr = ctr+1;
}
if(ochklist[c].checked && ctr == 1)
{
boolArray[ctr] = ochklist[c].checked;
ctr = ctr+1;
}
break;
case "DI": case "LTC": case "MEDSUP": // [disability income , Medicare , Long term]
if(ctr == 1)
{
boolArray[ctr] = false;
ctr = ctr+1;
}
if(ochklist[c].checked && ctr == 2)
{
boolArray[ctr] = ochklist[c].checked;
ctr = ctr+1;
}
break;
case "RETIREMENT":
if(ctr == 2)
{
boolArray[ctr] = false;
ctr = ctr+1;
}
if(ochklist[c].checked && ctr == 3)
{
boolArray[ctr] = ochklist[c].checked;
ctr = ctr+1;
}
break;
case "EDUCATION":
if(ctr == 3)
{
boolArray[ctr] = false;
ctr = ctr+1;
}
if(ochklist[c].checked && ctr == 4)
{
boolArray[ctr] = ochklist[c].checked;
ctr = ctr+1;
}
break;
case "FINANCIAL":
if(ctr == 4)
{
boolArray[ctr] = false;
ctr = ctr+1;
}
if(ochklist[c].checked && ctr == 5)
{
boolArray[ctr] = ochklist[c].checked;
ctr = ctr+1;
}
break;
}
}
return boolArray;
};
/**
* Function to add handlers to highlight the flash wheel
* @param {Object} frm the quote request form object
*/
var addQuoteRequestProductHandlers = function(frm){
if(document.URL.indexOf("@financialSecurityPlan") >= 0){
document.getElementById("finSection").style.display = "none";
}
var imgs = Dom.getElementsByClassName("infoImg", "IMG", "quoteRequest");
var oflash = Dom.get("flashfsWheel");
for(var i=0; i<imgs.length; i++){
Event.addListener(imgs[i], 'mouseover', function(e){
var titlenm = this.parentNode.id.substring(0,this.parentNode.id.indexOf("Title"));
if(oflash) oflash.HighlightWheel(titlenm,"true","TITLE");
});
Event.addListener(imgs[i], 'mouseout', function(e){
var titlenm = this.parentNode.id.substring(0,this.parentNode.id.indexOf("Title"));
if(oflash) oflash.HighlightWheel(titlenm,"false","TITLE");
});
}
// Check to make sure pre-selected check box higlights corresponding flash pieces
var preselect = CheckboxCollection();
if(!preselect[5])
{
for(var f = 0 ; f < preselect.length ; f++ )
{
if(f == 0)
oflash.HighlightWheel("property",preselect[f],"CLICK");
else if(f == 1)
oflash.HighlightWheel("income",preselect[f],"CLICK");
else if(f == 2)
oflash.HighlightWheel("health",preselect[f],"CLICK");
else if(f == 3)
oflash.HighlightWheel("retirement",preselect[f],"CLICK");
else if(f == 4)
oflash.HighlightWheel("education",preselect[f],"CLICK");
}
}
var secs = Dom.getElementsByClassName("formSection", "DIV", frm);
Event.addListener(secs[2], "click", function(e) {
var elTarget = Event.getTarget(e);
var oflash = Dom.get("flashfsWheel");
if(elTarget.nodeName.toUpperCase() == "INPUT"){
elTarget.value = elTarget.value.toLowerCase();
//(pass elTarget.checked as the parm to say whether to light up or turn off)
if(elTarget.value == "auto" || elTarget.value == "home" || elTarget.value == "farm" || elTarget.value == "umbrella" || elTarget.value == "business"){
//call flash piece to light up property piece
var bool = CheckboxCollection();
if( oflash && !bool[5] ) oflash.HighlightWheel("property",bool[0],"CLICK");
if(bool[0]) frm.needs[0].value = "property";
else frm.needs[0].value = "";
}
else if (elTarget.value == "life"){
//call flash to light up income piece
var bool = CheckboxCollection();
if(oflash && !bool[5]) oflash.HighlightWheel("income",bool[1],"CLICK");
if(bool[1]) frm.needs[1].value= "income";
else frm.needs[1].value= "";
}
else if(elTarget.value == "di" || elTarget.value == "ltc" || elTarget.value == "medsup"){
//call flash to light up health piece
var bool = CheckboxCollection();
if(oflash && !bool[5]) oflash.HighlightWheel("health",bool[2],"CLICK");
if(bool[2]) frm.needs[2].value= "health";
else frm.needs[2].value= "";
}
else if(elTarget.value == "retirement"){
var bool = CheckboxCollection();
if(oflash && !bool[5] ) oflash.HighlightWheel("retirement",bool[3],"CLICK");
if(bool[3]) frm.needs[3].value= "retirementSavings";
else frm.needs[3].value= "";
}
else if(elTarget.value == "education"){
var bool = CheckboxCollection();
if(oflash && !bool[5] ) oflash.HighlightWheel("education",bool[4],"CLICK");
if(bool[4]) frm.needs[4].value= "education";
else frm.needs[4].value= "";
}
else if(elTarget.value == "financial"){
var bool = CheckboxCollection();
if(oflash) oflash.HighlightWheel("center",bool[5],"CLICK");
if(!bool[5])
{
for(var f = 0 ; f < bool.length ; f++ )
{
if(f == 0)
oflash.HighlightWheel("property",bool[f],"CLICK");
else if(f == 1)
oflash.HighlightWheel("income",bool[f],"CLICK");
else if(f == 2)
oflash.HighlightWheel("health",bool[f],"CLICK");
else if(f == 3)
oflash.HighlightWheel("retirement",bool[f],"CLICK");
else if(f == 4)
oflash.HighlightWheel("education",bool[f],"CLICK");
}
}
//call flash to light up whole thing
}
}
});
};
/**
* External method to call to highlight a product group for use by the financial needs flash wheel
* id is the id of the product group title to highlight - propertyTitle, incomeTitle, healthTitle, retirementTitle, educationTitle, financialTitle
* highlight is a boolean true or false to highlight or turn off highlight
*/
var highlightProductGroup = function(id, highlight){
if(highlight)
Dom.addClass(id, id + "Highlight");
else
Dom.removeClass(id, id+ "Highlight");
};
/**
* function to kick off additional controllers for the quote request form
* @param {Object} frm the quote request form object
*/
var init = function(frm){
//add zip code handler
addQuoteRequestZipCodeHandler(frm);
if(frm.submitBtn){
var quoteRep = Dom.get("quoteRep");
if(quoteRep){
//add flash wheel
var output = '';
if(SOME.domain.indexOf("cottonstates") != -1){
output += '<object height="370" width="390" data="flash/cottonStates/fiveNeedsWheel2.swf" type="application/x-shockwave-flash" id="flashfsWheel"><param value="flash/SOMEStates/fiveNeedsWheel2.swf" name="movie"/><param value="always" name="allowScriptAccess"/><param name="wmode" value="window"/><a class="external" href="http://www.adobe.com/go/getflashplayer"><img alt="Get Flash Player" src="images/button_getFlashPlayer.gif"/></a></object>';
//create the autocomplete object
SOME.widget.AutoComplete.init(quoteRep, "acResults", "/SiteController?url=/@AutoCompleteCS&forward=agentList.jsp", frm );
}else{
output += '<object height="370" width="390" data="flash/financial/fiveNeedsWheel2.swf" type="application/x-shockwave-flash" id="flashfsWheel"><param value="flash/financial/fiveNeedsWheel2.swf" name="movie"/><param value="always" name="allowScriptAccess"/><param name="wmode" value="window"/><a class="external" href="http://www.adobe.com/go/getflashplayer"><img alt="Get Flash Player" src="images/button_getFlashPlayer.gif"/></a></object>';
//create the autocomplete object
SOME.widget.AutoComplete.init(quoteRep, "acResults", "/SiteController?url=/@allRepresentativesAutoComplete&forward=agentList.jsp", frm );
}
if(document.getElementById("fsWheel"))
document.getElementById("fsWheel").innerHTML = output;
Dom.addClass(["infoPos5", "quoteEmailLabel", "quoteEmail"], "noDisplay");
}
//add phone or email handler
SOME.util.Forms.initPhoneEmailFields(frm.phone, frm.customerEmail, true);
//add flash product handlers
addQuoteRequestProductHandlers(frm);
//add submit handler
Event.addListener(frm.submitBtn, "click", function(e){
var errs = SOME.util.Forms.validateForm(frm, {replaceErrorCodes: true, autoInsert : true, insertNode : Dom.getElementsByClassName("formSection")[0], showErrorHeader: true});
if(errs.length > 0){
Event.preventDefault(e);
window.scrollTo(0,0);
}
else{
this.businessSubject.value = this.businessSubject.value + frm.firstName.value + " " + frm.lastName.value;
}
},frm, true);
}
};
/**
* return the public members of this singleton
*/
return {
init:init,
highlightProductGroup:highlightProductGroup
};
}();
回答1:
Just a guess, but could it be that the script is executing and trying to communicate with Flash before the Flash object is loaded, and by putting the alert in there you're breaking the execution long enough for the Flash to load?
If so you have a few options:
- Delay the execution of the the script until the Flash element is loaded.
- Execute the script immediately and write any changes to the checkboxes to a flashvar that Flash can read on startup
- Execute the script immediately, but instead of calling to Flash, store the values and have Flash call back to the page using ExternalInterface when it is loaded and ready to display.
来源:https://stackoverflow.com/questions/6864516/issues-with-javascript-properly-loading-and-seeing-everything