I inherited Javascript and jQuery for a sliding belt (carousel) module. Basically, left and right navigation arrows would appear to the sides of the belt if there were more slides to show.
The jQuery and Javascript code was originally a singleton, so I decided to convert it into a jQuery plug-in in case the belt HTML markup was instantiated more than once. We have a CMS, so multiple belt modules theoretically could be placed on the same template.
Below is test page with two belts on the same page and the associated Javascript jQuery. My problem is that when you click on the arrows or the slides, both belts respond instead of the belt I interacted with.
What I would like to do is when I attach my plug-in to a DIV, I want each belt to operate independently of each other (i.e keep its own local variables, functions, etc.).
I am not sure what I am missing here. Can somebody point out my mistake and explain what I am doing wrong? (You should be able to copy and paste the code into jsFiddle to see how it currently works.)
Thank you for reading.
<html>
<head>
<title>Belt Test</title>
<style type="text/css">
div.belt { height: 95px; padding: 16px 0 6px 0; position: relative; width: 619px; }
div.belt span.scrollLeft,
div.belt span.scrollRight { display: none; padding-top: 30px; text-align: center; width: 48px; }
div.belt span.scrollLeft { float: left; }
div.belt span.scrollRight { float: right; }
div.belt span.scrollLeft a,
div.belt span.scrollRight a { background-color: transparent; background-repeat: no-repeat; background-image: url('http://img4.realsimple.com/static/i/gallery-sprite2.gif'); display: block; height: 24px; margin: 0 auto; outline: 0; width: 24px; text-decoration: none; }
div.belt span.scrollLeft a { background-position: -3px -679px; }
div.belt span.scrollRight a { background-position: -3px -650px; }
div.belt span.scrollLeft a:hover { background-position: -3px -737px; text-decoration: none; }
div.belt span.scrollRight a:hover { background-position: -3px -708px; text-decoration: none; }
div.belt div.wrapper { height: 87px; overflow: hidden; margin: 0 48px; position: relative; width: 522px; }
div.belt ul { height:87px; left: 0px; list-style-type: none; margin: 0; padding: 0; position: absolute; top: 0px; }
div.belt li { display:inline;float:left;padding:6px;}
div.belt li.selected { border: 1px solid #0099fe; padding: 5px; }
div.belt li a,
div.belt li a:hover { outline:none; text-decoration:none; }
div.belt li img { cursor: pointer; display: block; height: 75px; width: 75px; }
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript">
(function($) {
/**
* @description jQuery Belt plug-in - Add default global belt behavior to ul-style belt where each click on the belt is a page refresh.
* This is a fixed belt with no customization allowed. Attach this plug-in to the div encapsulating the UL.
*/
$.fn.globalbelt = function() {
/* Inside .each(), this keyword refers to current DOM object */
return this.each(function() {
/* We save a reference to the current div element and use it for traversal later */
var self = this;
/* Variable initialization */
var slides = $('ul', self).find('li').size(), /* calc # of slides */
pages = Math.ceil(slides / 6), /* calc # of pages */
pageWidth = 522, /* width of one slide page */
shiftDuration = 400, /* animation duration */
currentPage = 1, /* current slide page */
beltSize = slides * 87; /* sets the width of the entire belt */
$('ul', self).css('width', beltSize + 'px');
/* hides/shows scrolling arrows */
setScrollButtons = function(){
if (currentPage <= 1) {
$('.scrollLeft', self).hide();
} else {
$('.scrollLeft', self).show();
}
if (currentPage >= pages) {
$('.scrollRight', self).hide();
} else {
$('.scrollRight', self).show();
}
}
/* hide / show buttons */
setScrollButtons();
/* Button event handler to scroll left */
$('.scrollLeft a', self).click(function(event){
currentPage--;
setScrollButtons();
$('ul', self).animate({ left: '+=' + pageWidth }, shiftDuration);
return false;
});
/* Button event handler to scroll right */
$('.scrollRight a', self).click(function(event){
currentPage++;
setScrollButtons();
$('ul', self).animate({ left: '-=' + pageWidth }, shiftDuration);
return false;
});
}); /* return this */
} /* End plug-in */
})(jQuery);
/* Implicitly iterate and bind the plug in to each div that match the selector */
$(document).ready(function() {
$('.belt').globalbelt();
});
</script>
</head>
<body>
<开发者_JS百科;div class="belt">
<span class="scrollLeft">
<a href="#"> </a>
</span>
<span class="scrollRight">
<a href="#"> </a>
</span>
<div class="wrapper">
<ul>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
</ul>
</div>
</div>
<div class="belt">
<span class="scrollLeft">
<a href="#"> </a>
</span>
<span class="scrollRight">
<a href="#"> </a>
</span>
<div class="wrapper">
<ul>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
<li><a href="#"><img src="http://l.yimg.com/a/p/fi/39/03/54.jpg" title="1" alt="1" border="0" height="75" width="75" /></a></li>
</ul>
</div>
</div>
</body>
</html>
This should be doable without IDs. You just have to go up the DOM to find the specific div you are in, get the element object reference, and then only perform the action in that specific sub-tree of the DOM.
So in your click function you would add:
$('.scrollLeft a', self).click(function(event){
var parentDiv = $(this).parents(".belt");
currentPage--;
setScrollButtons(parentDiv);
//...rest of your code...
So now you have a reference to the specific belt element which you pass to your helper function. You can modify your helper function in the following way:
setScrollButtons = function(parentDiv){
if (currentPage <= 1) {
parentDiv.find('.scrollLeft', self).hide();
} else {
parentDiv.find('.scrollLeft', self).show();
}
if (currentPage >= pages) {
parentDiv.find('.scrollRight', self).hide();
} else {
parentDiv.find('.scrollRight', self).show();
}
}
That way you are still only selecting by class, but you are limiting the elements jQuery is selecting from to the sub-tree of parentDiv.
Barring any JS scoping issues, that should work. If you run into scoping issues, you probably need to refactor the code.
I've never heard the term 'belt' for that. It's usually referred to as a carousel.
That said, in jQuery, you'd instantiate each one by selecting it individually (either via a unique ID, or a CSS3 selector, or grabbing all of them and traversing through them in jQuery) and then pass the settings/variables for each as you go.
So, instead of:
$('.belt').globalbelt();
I'd suggest:
$('#belt1').globalbelt();
$('#belt2').globalbelt();
$('#belt3').globalbelt();
The reason for both the belts responding is because the code binds to both the clicks.
In the function for designated event handlers to scroll left, specify the target as the div where the event occurs. The current code does not have that "context" information.
change the event handlers to
$('.scrollLeft a', self).click(function(event){
self = event.currentTarget.parentElement.parentElement;
currentPage--;
setScrollButtons();
$('ul', self).animate({ left: '+=' + pageWidth }, shiftDuration);
return false;
});
This will work as expected.
精彩评论