简体   繁体   中英

How do I get to the beginning or end of the array properly? How do I pass in a reference of currently selected item?

Thanks for taking time to help out. CoffeeScript version is 1.3.3; jQuery version is from Rails 3.2.8 jquery-rails gem 2.1.3.

I have an array of poems with their respective links stored in $poems_for_year_hrefs. I am able to grab the index of the elements in $poems_for_year_hrefs using $.each() and storing in poemUrls.

The page's next link, when clicked on, is used to increment the index of poemUrls to the next element and update the $next_link's href attribute. If the index exceeds the length of the poemUrls, then the index is set back to 0 to give the first element in the array.

The page's previous link, when clicked on, is used to obtain the next element in the $poems_for_year_hrefs by decrementing the current index in poemUrl by 1. Then it updates the $prev_link's href attribute. If the current index is less than or equal to 0 it goes to the last element in the poemUrls array.

Here is the CoffeeScript code:

$(document).ready ->
    $poem_years = $('#poems-for-year ul li a')
    $poem = $('#main-poem').hide()
    $poem_years.click -> 
      $poem.eq(0).fadeIn('slow', -> 
        $poem.slideDown('slow')
     )
     console.log "Clicked on a poem title with index of #{$poem_years.index(@)}"

    $poems_for_year_hrefs = $('#poems-for-year ul li a[href]')

    index = $poems_for_year_hrefs.index(@)
    poemUrls = []
    $($poems_for_year_hrefs).each((i)->
      poemUrls[i] = $(@).attr('href')
      poemUrls.join(",")
    )
    console.log "The poemUrls array contains: #{poemUrls}"

    $next_link = $('#previous-next li a').last()
    $next_link.click ->
      if index >= poemUrls.length
        index = 0
        $next_link.attr('href', poemUrls[index]).attr('href')
      else
        index += 1
        console.log "$next_link was clicked on!"
        $next_link.attr('href', poemUrls[index]).attr('href')
        console.log "$next_link href was set to #{$next_link.attr('href')}"

    $prev_link = $('#previous-next li a').first()
    $prev_link.click ->
      if index <= 0
        index = poemUrls.length
        $prev_link.attr('href', poemUrls[index]).attr('href')
      else
        index -= 1
        console.log "$prev_link was clicked on!"
        $prev_link.attr('href', poemUrls[index]).attr('href')
      console.log "$prev_link href was set to #{$prev_link.attr('href')}"

and the HTML:

    <!DOCTYPE html>
    <html>
    <head>
    <title>...</title>
    <link href="/assets/application.css?body=1" media="all" rel="stylesheet" type="text/css" />
    <script src="/assets/jquery.js?body=1" type="text/javascript"></script>
    <script src="/assets/jquery_ujs.js?body=1" type="text/javascript"></script>
    <script src="/assets/poetry.js?body=1" type="text/javascript"></script>
    <script src="/assets/application.js?body=1" type="text/javascript"></script>
    <meta content="authenticity_token" name="csrf-param" />
    <meta content="XcXpd5Fg50gvWP8tVLB0/HOfBxoPaTOJ9q37zArrrFo=" name="csrf-token" />
    </head>
    <body>
    <div>
    <div id="content">
    <h1>poetry</h1>
    <section id="poem-selections">
    <article id="archives">
    <nav id="archive-year-nav">
    <ul>
    <li><a href="/poetry/2011">2011</a>
    <li><a href="/poetry/2012">2012</a>
    </ul>
    </nav>

    <div id="poems-for-year">
    <ul>
    <li><a href="/poetry/2012/1st%20poem%20title?id=16" data-remote="true">1st poem   title</a>
    </li>
    <li><a href="/poetry/2012/2nd%20poem%20title?id=17" data-remote="true">2nd poem  title</a>
    </li>
    <li><a href="/poetry/2012/3rd%20poem%20title?id=18" data-remote="true">3rd poem   title</a>
    </li>
    </ul>

   </div>
   </article>

   </section>

   <section id="main">

   <article>
   <div id="main-poem">
   <h3>2nd poem title</h3>
   <p>2nd poem verse</p>
   </div>
   <nav>
   <ul id="previous-next">
   <li><a href="/poetry/2012/previous_poem/2nd%20poem%20title?id=17" data-  remote="true">previous</a></li>
   <li><a href="/poetry/2012/next_poem/2nd%20poem%20title?id=17" data-remote="true">next</a>      </li>
   </ul>
   </nav>

   </article>

   </section>
   </div>
   </body>
   </html>

I am using Ajax to make updates to the main-poem div. If I click on the 2nd poem (id=17) in poems-for-year div, the main-poem div will update, showing the contents of the 2nd poem (id=17). If I click on the next link, the first poem that's indexed in the poemUrls at position 0 is returned. Then I click next and the poem in position 1 of the poemUrls is returned and then next again and the position 2 is returned moves along like it should. Once I reach the end of the array, I click the next link to cycle the index count back to 0 to reach the beginning of the poemUrls array, I need to click next twice. The first click does nothing.

The same issue is experienced, if I select the 3rd poem, then click the previous link. The index starts at 0 and then returns the 1st position of the poemUrl array. Click previous, goes through array decrementing the index by one. Gets to the 1st element, then I need to click previous twice to get to the last position in the array.

Why do I need to click it twice? Is it a variable that loses context?

* Also how can I pass the reference of the currently selected element to $next_link.click so it knows what the current element selected is and can get the proper next element rather than starting at 0? In other words, if I click on the 2nd poem (id=17) in poems-for-year, how can I get $next_link.click to return the 3rd poem (id=18), or if I click previous get $prev_link.click to return the 1st poem (id=16)?*

The CoffeeScript compiled to JavaScript:

$(document).ready(function() {
  var $next_link, $poem, $poem_years, $poems_for_year_hrefs, $prev_link, index, poemUrls;
  $poem_years = $('#poems-for-year ul li a');
  $poem = $('#main-poem').hide();
  $poem_years.click(function() {
    $poem.eq(0).fadeIn('slow', function() {
      return $poem.slideDown('slow');
    });
    return console.log("Clicked on a poem title with index of " + ($poem_years.index(this)));
  });
  $poems_for_year_hrefs = $('#poems-for-year ul li a[href]');
  index = $poems_for_year_hrefs.index(this);
  poemUrls = [];
  $($poems_for_year_hrefs).each(function(i) {
    poemUrls[i] = $(this).attr('href');
    return poemUrls.join(",");
  });
  console.log("The poemUrls array contains: " + poemUrls);
  $next_link = $('#previous-next li a').last();
  $next_link.click(function() {
    if (index >= poemUrls.length) {
      index = 0;
      return $next_link.attr('href', poemUrls[index]).attr('href');
    } else {
      index += 1;
      console.log("$next_link was clicked on!");
      $next_link.attr('href', poemUrls[index]).attr('href');
      return console.log("$next_link href was set to " + ($next_link.attr('href')));
    }
  });
  $prev_link = $('#previous-next li a').first();
  return $prev_link.click(function() {
    if (index <= 0) {
      index = poemUrls.length;
      $prev_link.attr('href', poemUrls[index]).attr('href');
    } else {
      index -= 1;
      console.log("$prev_link was clicked on!");
      $prev_link.attr('href', poemUrls[index]).attr('href');
    }
    return console.log("$prev_link href was set to " + ($prev_link.attr('href')));
  });
});

Edit

    $next_link = $('#previous-next li a').last()
    $next_link.click ->
      nextPoemUrl = poemUrls[ if index >= poemUrls.length - 1 then 0 else index + 1 ]
      console.log "When I call $next_link_click, nextPoemUrl is: #{nextPoemUrl}"
      $next_link.attr('href', nextPoemUrl).attr('href')
      console.log "When I call $next_link_click, next_link href is: #{$next_link.href}"

    $prev_link = $('#previous-next li a').first()
    $prev_link.click ->
      prevPoemUrl = poemUrls[ if index <= poemUrls.length - 1 then 0 else index - 1 ]
      console.log "When I call $prev_link.click, prevPoemUrl is #{prevPoemUrl}"
      $prev_link.attr('href', prevPoemUrl).attr('href')
      console.log "When I call $prev_link_click, prev_link href is #{$prev_link.href}"

Testing results: The poemUrls array contains these: /poetry/2011/1st%20poem%20title%202011?id=19,/poetry/2011/2nd%20poem%20title%202011?id=20,/poetry/2011/3rd%20poem%20title%202011?id=21

Clicked on a poem title with index of 2 (last poem in array containing 3 poems) When I call $prev_link.click, prevPoemUrl is /poetry/2011/3rd%20poem%20title%202011?id=21 (last poem in array) When I call $prev_link_click, prev_link href is undefined

I click on the last poem again: Clicked on a poem title with index of 2 (last poem)

When I call $next_link_click, nextPoemUrl is: /poetry/2011/1st%20poem%20title%202011?id=19

When I call $next_link_click, next_link href is: undefined

Seems that the prev returns the last poem indexed and next returns the first poem indexed Thanks for your help!

You have an off-by-one error . The errors are at,

if index >= poemUrls.length
    index = 0
...
if index <= 0
    index = poemUrls.length

In your example, poemUrls.length is 3 , and since JavaScript arrays are zero-based (they start counting at zero) the valid indexes are 0, 1, and 2 . The first snippet will let the index get to 3 before setting it to 0 . The second snippet will set the index to 3 when it reaches 0 . The corrected code is,

if index >= poemUrls.length - 1
    index = 0
...
if index <= 0
    index = poemUrls.length - 1

Edit

Addressing the second question, if you want to access the siblings of the current poem, you can use your array and index structure. The quick CoffeeScript solution would be,

prevPoemUrl = poemUrls[ if index <= 0 then poemUrls.length - 1 else index - 1 ]
nextPoemUrl = poemUrls[ if index >= poemUrls.length - 1 then 0 else index + 1 ]

Here's the source for getting the current position of the clicked poem, and having the next and previous link proceed accordingly. It's a rough draft, but works:

$(document).ready ->
    $poem_years = $('#poems-for-year ul li a')
    $poem = $('#main-poem').hide()
    $poem_years.click -> 
      $poem.eq(0).fadeIn('slow', -> 
        $poem.slideDown('slow')
      )
      console.log "Clicked on a poem title with index of #{$poem_years.index(@)}" # <-- where gets current index of clicked poem title!
      $poems_for_year_hrefs = $('#poems-for-year ul li a[href]')
      index = $poem_years.index(@) # <-- Assign the current reference to the index variable
      poemUrls = []
      $($poems_for_year_hrefs).each((i)->
        poemUrls[i] = $(@).attr('href')
        poemUrls.join(",")
      )

      console.log "The poemUrls array contains these: #{poemUrls}"

      $prev_link = $('#previous-next li a').first()
      $prev_link.click ->
       console.log "the prevPoemUrl is: #{poemUrls[index]}"
       if index <= 0
         index = poemUrls.length - 1
         $prev_link.attr('href', poemUrls[index]).attr('href')
         $('#main-poem').hide().fadeIn('slow')
         console.log "$prev_link href when <= poemUrls.length was set to #{$prev_link.attr('href')}"
         console.log "The poemUrls when <= poemUrls.length is: #{poemUrls[index]}"
       else
         index -= 1
         console.log "$prev_link was clicked on!"
         $prev_link.attr('href', poemUrls[index]).attr('href')
         $('#main-poem').hide().fadeIn('slow')
         console.log "$prev_link href was set to #{$prev_link.attr('href')}"   
         console.log "The poemUrls poemUrls.length is: #{poemUrls[index]}"

      $next_link = $('#previous-next li a').last()
      $next_link.click ->
        if index >= poemUrls.length - 1
          index = 0
          $next_link.attr('href', poemUrls[index]).attr('href')
          $('#main-poem').hide().fadeIn('slow')
          console.log "$next_link href when >= poemUrls.length was set to #{$next_link.attr('href')}"
          console.log "The poemUrl when >= poemUrls.length is: #{poemUrls[index]}"
        else
          index += 1
          console.log "$next_link was clicked on!"
          $next_link.attr('href', poemUrls[index]).attr('href')
          console.log "$next_link href was set to #{$next_link.attr('href')}"
          console.log "The poemUrls when < poemUrls.length is: #{poemUrls[index]}"
          $('#main-poem').hide().fadeIn('slow')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM