Reputation: 2884
I have a CSS sucker fish side-menu on my page. When the user clicks on an item in the page, I'm popping up a jQuery UI dialog box and inside a div on the page I am loading an HTML page through jQuery AJAX.
In Chrome the focus shifts away from the menu and onto the jQuery UI dialog box whenever I click on an item on the menu.
But in IE and Opera the focus remains on the menu even after I have clicked on the item. The jQuery UI dialog box is unable to shift the focus away from the menu hence it remains open and obstructs the view of the user.
Please take a look at the attached image.
As you can see I even added an text-box and grabbed the focus there, but even so there is no change.
As requested, here is a link to the website.
Example: When you open the website in IE 9, and you click on say Technologies > MySQL or Technologies > MSSQL, the menu doesn't close, but it should because I'm opening up a modal dialog while loading the page behind in the div. But if you open the page in chrome, and try the same thing, the menu closes, as it should. Attaching relevant code snippets:-
/**********************************************
Function to load an html page inside a div
**********************************************/
function loadPageInDiv(containerDiv, pageToLoad, divToLoadIn, loadingDialog, callBackFunction) {
var parentDiv = $("#" + containerDiv);
var loadDiv = $("#" + divToLoadIn);
var dialogBox = $("#" + loadingDialog);
// Show dialog box first, then fadeOut, then load, then fadeIn,the close.
$(dialogBox).data('loadDiv', loadDiv).dialog("open");
$(loadDiv).load(pageToLoad, function (response, status, xhr) {
if (response == "error") {
$(dialogBox).dialog('close');
}
else {
if (callBackFunction != null) {
callBackFunction();
}
checkAndDisplay(loadingDialog, divToLoadIn);
}
});
}
Function to initialize the jquery-ui dialog box.
/**************************************
Function to initialize the dialog box
*****************************************/
function initializePleaseWaitDialog() {
$("#osmPleaseWait").dialog({
autoOpen: false,
modal: true,
dialogClass: 'noTitleDialog',
draggable: false,
resizable: false
});
}
Function to toggle DIV display
/***************************************
Function to toggle div display
****************************************/
function checkAndDisplay(dialogToHide, divToShow) {
$("#" + divToShow).css('display', 'block');
$("#" + dialogToHide).dialog("close");
}
UPDATE #3: I tried another way, On the click event of the menu items, I am hiding all the secondary divs.
$(".osmMenuObject,.mainCatHeaderWithoutChild").click(function () {
// Currently Selected
$(".osmMenuObject,.mainCatHeaderWithoutChild").removeClass("osmServiceListSelected");
$(this).addClass("osmServiceListSelected");
// Hiding the div**
$(".secondaryMenuContainer").css('display', 'none');
var pageToLoad = $(this).children("input[type='hidden']").val();
loadPageInDiv("serviceLoadDivContainer", pageToLoad, "serviceLoadDiv", "osmPleaseWait");
return false;
});
I have then updated the code in checkAndDisplay
, to remove the display attribute I added earlier, but it still doesn't work.
function checkAndDisplay(dialogToHide, divToShow) {
$("#" + dialogToHide).dialog("close");
$("#" + divToShow).css('display', 'block');
$(".secondaryMenuContainer").css('display', '');
}
HERE is the markup for the page.
<div class="osmListContainerSpecial">
<div class="osmListHeader" id="osmListHeaderServices">
Our Services
</div>
<div class="mainCatHeader">
Software Development
</div>
<%-- Technologies --%>
<div class="secondCatHeader">
Technologies
<div class="secondaryMenuContainer" id="softwareDevTech">
<div class="secondaryMenu" style="COLOR: #3e3e3e" id="techMenu">
<div class="osmMenuObject">
.NET/ C#
<input type="hidden" value="ServicesHTML/SoftwareDevelopment/Applications/techCSharp.html" />
<div class="shortMenuDesc">
Our primary area of expertise, with over 5 years of experience.</div>
</div>
<div class="osmMenuObject">
MS-SQL
<input type="hidden" value="ServicesHTML/SoftwareDevelopment/Applications/techMsSQL.html" />
<div class="shortMenuDesc">
We have been working with SQL for over 6 years now.</div>
</div>
<div class="osmMenuObject">
MySQL
<input type="hidden" value="ServicesHTML/SoftwareDevelopment/Applications/techMySQL.html" />
<div class="shortMenuDesc">
Open Source Database for faster, hassle-free deployment.</div>
</div>
<div class="osmMenuObject">
Silverlight
<input type="hidden" value="ServicesHTML/SoftwareDevelopment/Applications/techSilverlight.html" />
<div class="shortMenuDesc">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sit.</div>
</div>
<div class="osmMenuObject">
MVC
<input type="hidden" value="ServicesHTML/SoftwareDevelopment/Applications/techMVC.html" />
<div class="shortMenuDesc">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sit.</div>
</div>
<div class="osmMenuObject">
Azure
<input type="hidden" value="ServicesHTML/SoftwareDevelopment/Applications/techAzure.html" />
<div class="shortMenuDesc">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sit.</div>
</div>
</div>
</div>
</div>
<%-- Applications --%>
<div class="secondCatHeader">
Applications
<div class="secondaryMenuContainer" id="softwareDevApp">
<div class="secondaryMenu">
<div id="appMsCRM" class="osmMenuObject">
Microsoft CRM
<input type="hidden" value="ServicesHTML/SoftwareDevelopment/Technologies/appMsCRM.html" />
<div class="shortMenuDesc">
Our primary area of expertise, with over 5 years of experience.</div>
</div>
<div id="appQb" class="osmMenuObject">
QuickBooks
<input type="hidden" value="ServicesHTML/SoftwareDevelopment/Technologies/appQb.html" />
<div class="shortMenuDesc">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sit.</div>
</div>
<div id="appGP" class="osmMenuObject">
Great Plains
<input type="hidden" value="ServicesHTML/SoftwareDevelopment/Technologies/appGp.html" />
<div class="shortMenuDesc">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sit.</div>
</div>
<div id="appSP" class="osmMenuObject">
Sharepoint
<input type="hidden" value="ServicesHTML/SoftwareDevelopment/Technologies/appSp.html" />
<div class="shortMenuDesc">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sit.</div>
</div>
<div id="appXero" class="osmMenuObject">
Xero
<input type="hidden" value="ServicesHTML/SoftwareDevelopment/Technologies/appXero.html" />
<div class="shortMenuDesc">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sit.</div>
</div>
<div id="appFB" class="osmMenuObject">
Freshbooks
<input type="hidden" value="ServicesHTML/SoftwareDevelopment/Technologies/appFb.html" />
<div class="shortMenuDesc">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sit.</div>
</div>
<div id="appSF" class="osmMenuObject">
SalesForce
<input type="hidden" value="ServicesHTML/SoftwareDevelopment/Technologies/appSF.html" />
<div class="shortMenuDesc">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sit.</div>
</div>
<div id="appNav" class="osmMenuObject">
Navision
<input type="hidden" value="ServicesHTML/SoftwareDevelopment/Technologies/appNavision.html" />
<div class="shortMenuDesc">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sit.</div>
</div>
</div>
</div>
</div>
<%-- Independent Software Testing --%>
<div class="mainCatHeaderWithoutChild">
Independent Software Testing
<input type="hidden" value="ServicesHTML/Testing.html" />
</div>
<%-- Technnical Documentation --%>
<div class="mainCatHeaderWithoutChild">
Technnical Documentation
<input type="hidden" value="ServicesHTML/Documentation.html" />
</div>
<%-- Case Studies --%>
<div class="mainCatHeaderWithChild">
Case Studies
<div class="secondaryMenuContainer">
<div class="secondaryMenu" style="COLOR: #3e3e3e">
<div class="osmMenuObject">
Media - Astral
<input type="hidden" value="ServicesHTML/CaseStudies/csAstral.html" />
<div class="shortMenuDesc">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sit.</div>
</div>
<div class="osmMenuObject">
Waste Disposal - RGMRM
<input type="hidden" value="ServicesHTML/CaseStudies/csRGMRM.html" />
<div class="shortMenuDesc">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sit.</div>
</div>
<div class="osmMenuObject">
Insurance - IAAH
<input type="hidden" value="ServicesHTML/CaseStudies/csIAAH.html" />
<div class="shortMenuDesc">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sit.</div>
</div>
<div class="osmMenuObject">
Housing Providers - TalonPro
<input type="hidden" value="ServicesHTML/CaseStudies/csTalonPro.html" />
<div class="shortMenuDesc">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sit.</div>
</div>
<div class="osmMenuObject">
Education and Training - Met Film
<input type="hidden" value="ServicesHTML/CaseStudies/csMetFilm.html" />
<div class="shortMenuDesc">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sit.</div>
</div>
<div class="osmMenuObject">
Industry - Bates
<input type="hidden" value="ServicesHTML/CaseStudies/csBates.html" />
<div class="shortMenuDesc">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sit.</div>
</div>
<div class="osmMenuObject">
Industry - Atdec
<input type="hidden" value="ServicesHTML/CaseStudies/csAtdec.html" />
<div class="shortMenuDesc">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sit.</div>
</div>
</div>
</div>
</div>
</div>
Please let me know if you need any other code, or have any other queries.
Upvotes: 13
Views: 1005
Reputation: 2884
Okay since there hasn't been a proper workaround. Here's what I did to circumvent problem. Some may think that it's slightly hack-y but I couldn't find any other solution.
If you check my 3rd update I am hiding the secondary menu,
$(".osmMenuObject,.mainCatHeaderWithoutChild").click(function () {
// Currently Selected
$(".osmMenuObject,.mainCatHeaderWithoutChild").removeClass("osmServiceListSelected");
$(this).addClass("osmServiceListSelected");
// Hiding the div || THIS WAS NEW
$(".secondaryMenuContainer").css('display', 'none');
var pageToLoad = $(this).children("input[type='hidden']").val();
loadPageInDiv("serviceLoadDivContainer", pageToLoad, "serviceLoadDiv", "osmPleaseWait");
return false;
});
Now in the document.ready()
event itself, I'm adding another event.
$(".secondCatHeader,.mainCatHeaderWithChild").hover(function () {
$(this).children(".secondaryMenuContainer").css('display', '');
})
Now what this will do is, whenever we hover over one of the menu items, and it has a children with the class .secondaryMenuContainer
, it'll clear the inline display from that class. So the display:none
that I had set earlier will be cleared. I've tested this with IE 9.0 and Opera, and it seems to be working properly.
Thanks everyone.
Upvotes: 2
Reputation: 2066
It appears to be a racing condition. I'm not sure about the "why" part, but this seems to overcome the problem:
Replace your checkAndDisplay function with the following version:
function checkAndDisplay(dialogToHide, divToShow) {
$("#" + divToShow).css('display', 'block');
setTimeout(function(){
$("#" + dialogToHide).dialog("close");
},500);
}
Edit: Seems there is a bug with Internet Explorer not refreshing the "hover" state, except on mouse move. Here is a reproducable sample. Try clicking on the green area in different browsers and NOT move the mouse. http://jsfiddle.net/5LR8Z/
I didn't find any solution for that particular bug. As a workaround, I would try manually closing the menu (set a variable on the click handler to know which menu to close on your checkAndDisplay function).
Upvotes: 3
Reputation: 133
From what I can tell, you have a CSS conflict between line 1101 and line 1109. You've set .secondaryMenuContainer
to DISPLAY: none;
but then set it to DISPLAY: block;
upon .secondCatHeader:hover;
The jQuery UI dialog box doesn't negate the hover
condition, and so your .secondaryMenuContainer
never reverts to DISPLAY: none;
$(".secondaryMenuContainer").css('display', '');
didn't work because it sets an invalid inline style, so the browser reverts to displaying a valid external style, in this case DISPLAY: block;
since the user's hover
is still unbroken. If you want the .secondaryMenuContainer
to simply cascade back to its DISPLAY: none;
state you will have to break the user's hover.
One method would be to create an empty div
when your Dialog Box loads; one with a z-index higher than your .secondaryMenuContainer
that occupies the entire window. You would then remove that div
when the Dialog Box fades out. That should break the user's hover and allow the div's style to cascade back to DISPLAY: none;
EDIT: Since this is jQuery UI that modal box should be loading a .ui-widget-overlay
which does exactly what I've described. The function is being called in the stack at e.widget._createOverlay @jquery-ui-1.10.1.custom.min.js:6
but it's not stopping page interaction the way it's supposed to.
Upvotes: 1