Reputation: 3790
One of the things I'm working on for an upcoming project is a callout/tooltip system. In theory, it's a simple little thing. You take some markup like this:
<script src='jQuery 1.10.1'></script>
<a href='#' id='callout-link'>Click Me</a>
<div id='callout-id' class='callout hidden'>
This is my tooltip text.
</div>
/* CSS Styling... */
.callout {
position: absolute;
z-index: 2;
}
.hidden {
display: none;
}
...and bind it up in JavaScript so that whenever you click some link it toggles visibility.
// ...Page Script...
var $link = $('#callout-link'),
$callout = $('#callout-id');
$(document).ready(function () {
var callout = new MyCallout($link, $callout);
callout.bindToControlClick();
});
// ...Object Definition...
var MyCallout = function ($control, $callout) {
init();
// Public Scope...
var pub = {};
pub.$actionControl = $control;
pub.$callout = $callout;
pub.bindToControlClick = function () {
pub.$actionControl.click(function (e) {
e.preventDefault();
e.stopPropagation();
toggleCallout();
});
}
// Private Scope...
function init() {
// The callout-content subdiv is necessary for other operations that are
// likely not relevant to the problem I am encountering.
if($callout.children('.callout-content').length == 0)
$callout.wrapInner('<div class="callout-content" />');
}
function toggleCallout() {
if(pub.$callout.is(':hidden')) {
// Show is actually more complicated than this, but that's not the problem.
pub.$callout.show();
} else {
pub.$callout.hide();
}
}
return pub;
};
The problem is that, while the callout is initially hidden from view, and appears on click, attempting to toggle the callout off fails. When I add a breakpoint and watch value in the Chrome debugger for $callout.is(':hidden')
, even if the element is visible the watch value evaluates to true
.
Based on jQuery's entry for the :hidden selector, it appears that a number of properties are being checked at any given time, which brings me to the Question: what is it in my setup that's managing to fool jQuery's :hidden
selector into always believing the callout to be hidden, even when such is no longer the case?
EDIT: Since I notice a recent question of mine in the side panel, my team has since ensured that our app is running in IE9 Standards mode, so environment should not be a problem this go-round.
EDIT 2: Fiddle of the problematic code (UPDATED! Problem reproduced in full.)
Upvotes: 2
Views: 262
Reputation: 8189
Try using hasClass instead :
function toggleCallout() {
if(pub.$callout.hasClass('hidden')) {
pub.$callout.removeClass('hidden');
} else {
pub.$callout.addClass('hidden');
}
}
Or even quicker with toggleClass :
function toggleCallout() {
pub.$callout.toggleClass('hidden');
}
Also make sure to put your MyCallout
declaration before using it, otherwise you will get an error like
Uncaught TypeError: undefined is not a function
when calling
var callout = new MyCallout($link, $callout);
The working Fiddle
Upvotes: 2
Reputation: 3790
The problem was actually a CSS problem - while my code is sane (as the jsFiddle in my OP shows), the .callout
div was rendering with default dimensions of width: 0; height: 0
, which causes :hidden
to select the element.
All I had to do was add the following CSS to solve my problem:
.callout {
width: 1em;
height: 1em;
/* ...As before... */
}
Lesson: Always inspect elements! What looks like a script error, may in fact be something else entirely.
Upvotes: 0