tags:

views:

70

answers:

2

I have been looking for awhile, and I am just too new with JQuery and javascript to figure out where I am going wrong. Any help will be greatly appreciated. I have the script below, which works great for one element. How can I modify this to work with multiple elements? If I have multiple elements on the page the slider will scroll everything, not just the elements within the one container. I know I could technically just make new variables and new class names for each method but that is messy and I know there has to be a smarter way.

<script type="text/javascript" charset="utf-8">
    window.onload = function () {
        var container = $('div.sliderGallery');
        var ul = $('ul', container);

        var itemsWidth = ul.innerWidth() - container.outerWidth();

        $('.slider', container).slider({
            min: 0,
            max: itemsWidth,
            handle: '.handle',
            stop: function (event, ui) {
                ul.animate({'left' : ui.value * -1}, 500);
            },
            slide: function (event, ui) {
                ul.css('left', ui.value * -1);
            }
        });  
    };
</script>

And here is the html.

<div class="sliderGallery">

  <ul id="audio-downloads">
    <li><a href="#">Audio Title</a></li>
    <li><a href="#">Audio Title</a></li>
    <li><a href="#">Audio Title</a></li>
    <li><a href="#">Audio Title</a></li>
    <li><a href="#">Audio Title</a></li>
    <li><a href="#">Audio Title</a></li>
    <li><a href="#">Audio Title</a></li>
    <li><a href="#">Audio Title</a></li>
    <li><a href="#">Audio Title</a></li>
  </ul>

  <div class="slider">
    <div class="handle"></div>
  </div>

</div>

<div class="sliderGallery">

  <ul id="audio-downloads">
    <li><a href="#">Audio Title</a></li>
    <li><a href="#">Audio Title</a></li>
    <li><a href="#">Audio Title</a></li>
    <li><a href="#">Audio Title</a></li>
    <li><a href="#">Audio Title</a></li>
    <li><a href="#">Audio Title</a></li>
    <li><a href="#">Audio Title</a></li>
    <li><a href="#">Audio Title</a></li>
    <li><a href="#">Audio Title</a></li>
  </ul>

  <div class="slider">
    <div class="handle"></div>
  </div>

</div>
A: 

Try something like this - this converts your code into a plugin which can be selectively applied in the load script:

<script type="text/javascript" charset="utf-8">
    // This replaces window.load:
    $(function() {
        // Matches each slider gallery and applies one plugin to each.
        $('.sliderGallery').sliderGallery();
    });

    // Your very own jQuery plugin
    $.fn.sliderGallery = function() {
        var container = $(this); // $(this) is the element you applied the plugin to.
        var ul = $('ul', container);

        var itemsWidth = ul.innerWidth() - container.outerWidth();

        $('.slider', container).slider({
            min: 0,
            max: itemsWidth,
            handle: '.handle',
            stop: function (event, ui) {
                ul.animate({'left' : ui.value * -1}, 500);
            },
            slide: function (event, ui) {
                ul.css('left', ui.value * -1);
            }
        });  
    };
</script>

Hope this helps.

Chris Smith
This didn't fix anything, you just moved code around :) You need the `this.each` loop
Doug Neiner
Thanks for this though, this still helped me understand roughly how plugins work and how I may use them in the future :)
jaasum
Ahh yes - sorry about that. That'll teach me to do stackoverflow whilst drunk.
Chris Smith
+1  A: 

Update Also just noticed you are using window.onload. In jQuery you should use $(document).ready() or its alias $(function()).

You just need to use an each() to run through the collection of sliderGallery elements:

$(function(){ // This replaces your window.onload function wrapper
   $('div.sliderGallery').each(function(){
      var ul = $('ul', this);

      var itemsWidth = ul.innerWidth() - $(this).outerWidth();

      $('.slider', this).slider({
          min: 0,
          max: itemsWidth,
          handle: '.handle',
          stop: function (event, ui) {
              ul.animate({'left' : ui.value * -1}, 500);
          },
          slide: function (event, ui) {
              ul.css('left', ui.value * -1);
          }
      }); 
   });
})

In the each callback function, this = the current DOM node. If you need it as a jQuery object in that context, use $(this).

Doug Neiner
You still use `container` which isn't defined anymore.
jitter
@jitter, great catch. Missed that one!
Doug Neiner
This has nearly fixed it! And that actually makes a deal of sense. The only problem now is that it's a slider, and now the slider won't follow the mouse when you drag it. Does that make sense? I can get them to scroll independently of each other, but the slider won't move with the mouse. I am using the latest versions of jQuery and jQuery UI
jaasum
In doing some research I realize .slider is a function from the jquery UI. It appears to be working the way it should except it's not moving the handle div with the mouse. Either my syntax is wrong or maybe it could be a css issue? Not sure (still a newbie at this).
jaasum
@jassum If you post your code somewhere and paste a link, I can take a look at it for you.
Doug Neiner
No live link at the moment, I can get one if it comes to that. Here is a screen shot of the code... http://grab.by/ZsVHTML is the same as above. I messed around the CSS a bit and it doesn't seem to be that. I reverted to an older version of jQuery UI and the slider worked again, but wouldn't move the UL. I am thinking it's a some kind of semantic error on my part, can't seem to find an answer in the documentation :/
jaasum
Okay, I figured out my problem, it was with the jQuery UI. Apparently in the newer version (I was going off of an older version) the slider handle is a script-generated anchor tag, not an element you define. So I just had to take out the div.handle and style a.ui-slider-handle and everything is working like a charm. Thanks for your patience and help! I really appreciate it.
jaasum
@Jaasum glad you figured it out!
Doug Neiner