12762

jquery slide show - why does this code work?

I was in the middle of coding a slideshow in javascript using jquery, when I ran into something that was doing what my several lines of code was doing in a couple lines.

Problem is, I don't comprehend how it works so I can modify it.

var imgs = [ 'image1.jpg', 'image2.jpg', 'image3.jpg']; var cnt = imgs.length; $(function() { setInterval(Slider, 4000); }); function Slider() { $('#imageSlide').fadeOut("slow", function() { $(this).attr('src', imgs[(imgs.length++) % cnt]).fadeIn("slow"); }); }

This is the line that gets me:

[(imgs.length++) % cnt]

I'm reading that as

3+1 % 3 = 1

Now every time it executes, none of that code appears to be modifying any of the variables. cnt will always equal imgs.length (3), imgs.length++ doesn't actually modify it, it just adds one for that single execution, correct?

So matter how many times it executes, it will always be imgs[1] yet when I execute the code, it runs properly through all the array objects.

<strong>EDIT:</strong>

I simply added alert(imgs.length); and confirmed that ++ does actually change the variable, but it still doesn't make sense to me.

The first run, imgs.length = 4 after ++. 4 % 3 = 1 so it should run array object [1] not [0]?

Second run, 5 % 3 = 2

Third run, 6 % 3 = 0

etc etc.. but it shouldn't ever reset. However, if I put a alert(imgs.length % cnt); it only returns 0, 1, 2 than it resets.

Why?

Answer1:

the return value of imgs.length++ is 3 therefore 3 % 3 = 0 but imgs.length will be 4 and the imgs array will contain 4 items.

try it in console:

var x = [ 1, 2, 3 ] x.length++ => 3 x.length++ => 4 x.length++ => 5 x [1, 2, 3, undefined, undefined, undefined]

so every time imgs.length++ is called itt will append one item to the array. so not a nice code but short :)

<strong>EDIT</strong>: the why is easy to answer, in the start it contains cnt number of elements, so the code will step on every image and the starts from the beginning of it. so if the imgs array contains 5 items it will step through the 5 items and starts from the beginning.

the only problem with this code, that the array will be increased every time and the memory will be eaten by the browser.

Answer2:

I'm sure you're aware that imgs.length++, if it were applied to any other variable, would be adding one to it, modifying the original variable.

var x = 1; alert(x++); // alerts 1 alert(x); // alerts 2

Sure enough, that's what's going on.

The script increments the length of the imgs array on every run, so it moves from 3 to 4 to 5 to 6, etc. I'm not an expert on Javascript internals, so I'm not sure if that has any effect on performance, but if you understand that length is, in fact, a writable property, it all makes sense.

Answer3:

(imgs.length++) % cnt

will cause the images to loop through every image, over and over.

the percentage sign (%) in JavaScript means it uses Modulus (division remainder) operator.

Examples:

    <li>0 % 3 = 0</li> <li>1 % 3 = 1</li> <li>2 % 3 = 2</li> <li>3 % 3 = 0</li> <li>4 % 3 = 1</li> <li>5 % 3 = 2 etc...</li> </ul>

    Answer4:

    Well, every 4:th second that the function Slider runs it expands the array, so you get:

    3+1 % 3 = 1 4+1 % 3 = 2 5+1 % 3 = 0

    and so on :)

    Answer5:

    I'm not 100% sure in javascript but every other language I know imgs.length++ is the same as saying imgs.length = imgs.length + 1 so that should be getting modified.

    I'd consider it a "clever trick" that should be documented if used at all. <strike> It kinda breaks the semantics of what length means, so while logically correct to a computer it doesn't quite make sense in relation to the property name</strike>

    So I guess it actually does change the length, but I still wouldn't recommend using it without documenting it. A more clear method would be to declare a new var i = 0 and replace imgs.length++ with i++, because although it doesn't probably matter in this case, if you're doing anything else with the array, the length is now probably not what you expect it to be.

    <strong>Regarding the edit:</strong> 6 % 3 is 0 not 3. Modulo (in programming, slightly different in purely math term) means divide and take the remainder. 6 / 3 = 2 with a remainder of 0. 7 / 3 = 2 with a remainder of 1. 8 / 3 = 2 with a remainder of 2. 9 / 3 = 3 with a remainder of 0,

    Answer6:

    If you want your code to be more readable in the future, I would personally suggest you change your code to something like this:

    var imgs = [ 'image1.jpg', 'image2.jpg', 'image3.jpg']; var i = 0; $(function() { // This is a shortcut for $(document).ready(); setInterval(Slider, 4000); }); function Slider() { $('#imageSlide').fadeOut("slow", function() { i = (i+1) % imgs.length; $(this).attr('src', imgs[i]).fadeIn("slow"); }); }

Recommend

  • How to search for a record and then delete it
  • Process.PrivateMemorySize64 returning committed memory instead of private
  • How to run .java file with Variable Name
  • Embedded Google Maps in Rails not responsive
  • Retrieving specified columns from a list of csv files to create a data data frame in R
  • Filter strings with regex before casting to numeric
  • C# program and C++ DLL compiled for 32-bit system crash on 64-bit system
  • WPF ICommand CanExecute(): RaiseCanExecuteChanged() or automatic handling via DispatchTimer?
  • How solve “Qt: Untested Windows version 10.0 detected!”
  • How to use JavaScript to determine whether a file exists in a directory?
  • How to define and use opencv mat of user type
  • Functions in global context
  • FileReader+canvas image loading problem
  • Fetching methods from BroadcastReceiver to update UI
  • Get object from AWS S3 as a stream
  • Javascript Callbacks with Object constructor
  • Cassandra Data Model
  • How can I use Kendo UI with Razor?
  • Symfony2: How to get request parameter
  • Weird JavaScript statement, what does it mean?
  • How do you troubleshoot character encoding problems?
  • GridView Sorting works once only
  • Calling of Constructors in a Java
  • SVN: Merging two branches together
  • Hibernate gives error error as “Access to DialectResolutionInfo cannot be null when 'hibernate.
  • AT Commands to Send SMS not working in Windows 8.1
  • Compare two NSDates in iPhone
  • Traverse Array and Display in markup
  • How to format a variable of double type
  • Transpose CSV data with awk (pivot transformation)
  • Rails 2: use form_for to build a form covering multiple objects of the same class
  • WPF Applying a trigger on binding failure
  • Why can't I rebase on to an ancestor of source changesets if on a different branch?
  • How do I configure my settings file to work with unit tests?
  • How to CLICK on IE download dialog box i.e.(Open, Save, Save As…)
  • Getting Messege Twice Using IMvxMessenger
  • Can Visual Studio XAML designer handle font family names with spaces as a resource?
  • Is it possible to post an object from jquery to bottle.py?
  • How to Embed XSL into XML
  • Python/Django TangoWithDjango Models and Databases