Using jQuery to find visible items
I have this code that shows a video player and that video's information and hides it when the back button is clicked. However, when I view another video, the back button does not pick up which div is visible the second time around. Does the :visible
selector have to be linked to .live()
in order for it to determine which div is visible? If not, why can't it find my visible div?
jQuery('ul.projects li').click(function() {
var videolist = jQuery(this).closest('ul');
var videoplayer = jQuery(videolist).prev();
var videoplayerID = jQuery(videoplayer).find("div:first").attr("id");
var filename = jQuery(this).find("img").attr("alt");
var infoclass = '.' + filename.replace(/ /g,'');
jwplayer(videoplayerID).setup({
'flashplayer': '/_/jw/player.swf',
'id': 'playerID',
'width': '258',
'height': '145',
'file': '/_/videos/' + filename + '.mp4',
'autostart': true,
'events': {
onComplete: function(event) {
jQuery(videoplayer).fadeOut(function() {
jQuery(infoclass).fadeOut();
jwplayer(videoplayerID).remove();
jQuery(videolist).fadeIn();
});
}
}
});
jQuery(videolist).fadeOut(function() {
jQuery(videoplayer).fadeIn();
jQuery(infoclass).fadeIn();
});
});
jQuery('.back-to-projects').click(function(e) {
e.preventDefault();
var videoplayer = jQuery(this).parent();
var videolist = jQuery(videoplayer).next();
var videoplayerID = jQuery(videoplayer).find("div:first").attr("id");
var videoinfo = '.' + jQuery(this).siblings("div:visible").not("#video-player-1_wrapper, #video-player-2_wrapper").attr("class");
alert(videoinfo);
jQuery(videoinfo).fadeOut();
jQuery(videoplayer).fadeOut(function() {
jwplayer(videoplayerID).remove();
jQuery(videolist).fadeIn();
});
});
and the html
<div class="video-container" style="display:none;">
<div id="video-player-1_wrapper" style="float:left;"></div>
<div class="DwightHoward" style="display:none;"><p>Dwight Howard, son.</p></div>
<div class="BrianDeegan" style="display:none;"><p>Brian Deegan, son.</p></div>
<div class="PatrickWillis" style="display:none;"><p>Patrick Willis, son.</p></div>
<div class="Castles" style="display:none;"><p>Castles, son.</p></div>
<div class="Springtime" style="display:none;"><p>Springtime, son.</p></div>
<div class="Powerbar" style="display:none;"><p>Powerbar, son.</p></div>
<a class="back-to-projects" href="" title="Back">Back</a>
</div>
<ul class="projects">
<li><img class="t" src="/_/img/elevator-pitch/thumbs/video/dwight-howard.jpg" alt="Dwight Howard" /></li>
<li><img class="t" src="/_/img/elevator-pitch/thumbs/video/brian-deegan.jpg" alt="Brian Deegan" /></li>
<li><img class="t" src="/_/img/elevator-pitch/thumbs/video/patrick-willis.jpg" alt="Patrick Willis" /></li>
<li><img clas开发者_C百科s="b" src="/_/img/elevator-pitch/thumbs/video/castles.jpg" alt="Castles" /></li>
<li><img class="b" src="/_/img/elevator-pitch/thumbs/video/springtime.jpg" alt="Springtime" /></li>
<li><img class="b" src="/_/img/elevator-pitch/thumbs/video/powerbar.jpg" alt="Powerbar" /></li>
</ul>
I ended up simplifying the process by add a class .visible
to the visible element, and then removing it when I wanted to hide it. So shoot me.
Unless there's some more HTML or JS missing, your code is quite complicated for what it needs to do. Here's a solution that involves a lot less JS (and better practices, see below), and only 1 extra HTML element (which creates better logical separation anyway).
var $videolist = jQuery('ul.projects');
var $videoplayer = jQuery('.video-container');
var videoplayerID = jQuery('#video-player-1_wrapper').attr('id');
jQuery('ul.projects li').click(function() {
var filename = jQuery(this).find("img").attr("alt");
var $infoclass = jQuery('.' + filename.replace(/ /g,''));
jwplayer(videoplayerID).setup({
'flashplayer': '/_/jw/player.swf',
'id': 'playerID',
'width': '258',
'height': '145',
'file': '/_/videos/' + filename + '.mp4',
'autostart': true,
'events': {
onComplete: function(event) {
$videoplayer.fadeOut(function() {
$infoclass.fadeOut();
jwplayer(videoplayerID).remove();
$videolist.fadeIn();
});
}
}
});
$videolist.fadeOut(function() {
$videoplayer.fadeIn();
$infoclass.fadeIn();
});
});
jQuery('.back-to-projects').click(function(e) {
e.preventDefault();
jQuery('.info div:visible').fadeOut();
$videoplayer.fadeOut(function() {
jwplayer(videoplayerID).remove();
$videolist.fadeIn();
});
});
<div class="video-container" style="display:none;">
<div id="video-player-1_wrapper" style="float:left;"></div>
<div class="info">
<div class="DwightHoward" style="display:none;"><p>Dwight Howard, son.</p></div>
<div class="BrianDeegan" style="display:none;"><p>Brian Deegan, son.</p></div>
<div class="PatrickWillis" style="display:none;"><p>Patrick Willis, son.</p></div>
<div class="Castles" style="display:none;"><p>Castles, son.</p></div>
<div class="Springtime" style="display:none;"><p>Springtime, son.</p></div>
<div class="Powerbar" style="display:none;"><p>Powerbar, son.</p></div>
</div>
<a class="back-to-projects" href="" title="Back">Back</a>
</div>
<ul class="projects">
<li><img class="t" src="/_/img/elevator-pitch/thumbs/video/dwight-howard.jpg" alt="Dwight Howard" /></li>
<li><img class="t" src="/_/img/elevator-pitch/thumbs/video/brian-deegan.jpg" alt="Brian Deegan" /></li>
<li><img class="t" src="/_/img/elevator-pitch/thumbs/video/patrick-willis.jpg" alt="Patrick Willis" /></li>
<li><img class="b" src="/_/img/elevator-pitch/thumbs/video/castles.jpg" alt="Castles" /></li>
<li><img class="b" src="/_/img/elevator-pitch/thumbs/video/springtime.jpg" alt="Springtime" /></li>
<li><img class="b" src="/_/img/elevator-pitch/thumbs/video/powerbar.jpg" alt="Powerbar" /></li>
</ul>
A few points:
You were doing a lot of DOM traversal that wasn't necessary when you could have just directly used selectors by ID/class which is what I did above.
You were also duplicating some vars instead of declaring them above the click events.
The other big issue with your code was doubling up on jQuery objects.
Example:
var videolist = jQuery(this).closest('ul');
var videoplayer = jQuery(videolist).prev();
The first line returns a jQuery object (videolist). There's no reason to wrap that in jQuery() on the next line. You can safely do:
var videolist = jQuery(this).closest('ul');
var videoplayer = videolist.prev();
If you look at my code, I use $var to reference a jQuery object. It's purely a personal/style decision, but it helps to quickly tell whether a variable is a jQuery object or not.
Read here for more info about the jQuery object type: http://api.jquery.com/Types/#jQuery
精彩评论