JQuery show() not working with live()
I am having a very specific problem in JQuery
The code below is used to Show/Hid开发者_开发问答e a div
. The trigger to show/hide the div
will have the same ID as the div, and have classes (as selectors) showTrigger/hideTrigger
respectively.
wireActionPanelv3 = function(panel, fnDoThisOnShow, fnDoThisOnHide) {
var id = $(panel).attr("id");
var showTrigger = $('#' + id + '.showTrigger');
var hideTrigger = $('#' + id + '.hideTrigger');
$(showTrigger).live('click', function(event) {
if (fnDoThisOnShow != null) fnDoThisOnShow();
$(panel).slideDown("fast");
return false;
});
$(hideTrigger).live('click', function(event) {
if (fnDoThisOnHide != null) fnDoThisOnHide();
$(panel).slideUp("fast");
return false;
});
};
This is how I call this function
wireActionPanelv3($('div[id="configure-filter"]'),null, null);
When the page first loads, this works perfectly when the triggers are clicked. Everything fine till now.
There are some actions which refresh the div
in context. Now, when I click on the show/hide trigger, the code enters the click event above, but it does not show me the div back.
When I use bind
instead of live
, and call the initialization again it works. I wanted to use live
as I don't need to bother about the reinitialization again.
What fact am I missing about live
which can explain this behavior to me?
Live is going to rig up the the cleanest selector it can. This is your problem: will have the same ID as the div
...elements can't have the same ID, that's invalid HTML. .live()
is trying to rig up based on ID since it should be unique and failing.
Since live()
actually lives up at the DOM level, it has to have something it can uniquely identify events by as the bubble up, since that's how it catches the event. When you assign what should be guaranteed to be unique to multiple elements, you're going to get unpredictable behavior.
in jquery 1.3 live can only be attached to one selector for one event. You may try something like this. Try to combine it to one event or upgrade to 1.4 if you didn't already :)
Greetings, Joe
edit: something like this?
$("#id").live("click", function(event) {
if ($(this).is(":visible")) {
$(panel).slideDown("fast");
} else {
$(panel).slideUp("fast");
}
});
You may include your function call in the same style.
I think I got some insight into the problem.
When the panel
is defined as $('div[id="configure-filter"]')
, it creates a jQuery object which has a unique Identifier assigned to it. It is defined as uniqueId
and uniqueNumber
in the object.
When the content is refreshed, the panel
although existing on the page does not map to correct uniqueId
, which is why any actions on the panel
do not work.
To get around this, you should also refresh the jQuery object in such cases.
This is the code change I had to do...
wireActionPanelv3 = function(panelSelector, context, fnDoThisOnShow, fnDoThisOnHide) {
var panel = $(panelSelector, context);
var id = $(panel).attr("id");
var showTrigger = $('#' + id + '.showTrigger');
var hideTrigger = $('#' + id + '.hideTrigger');
$(showTrigger).live('click', function(event) {
panel = $(panelSelector, context);
if (fnDoThisOnShow != null) fnDoThisOnShow();
$(panel).slideDown("fast");
return false;
});
$(hideTrigger).live('click', function(event) {
panel = $(panelSelector, context);
if (fnDoThisOnHide != null) fnDoThisOnHide();
$(panel).slideUp("fast");
return false;
});
};
I am reinitializing the panel using the selectors.
And it is used as ...
wireActionPanelv3('div[id="configure-filter"]', controlContext, function() {
...blah blah ...
}, null);
Here I simply pass the selector as a string.
If someone has a better explanation to this, please share.
精彩评论