如何正确到达数组的开头或结尾?如何传递当前所选项目的参考?

时间:2012-10-23 00:26:46

标签: javascript jquery ruby-on-rails coffeescript

感谢您花时间帮忙。 CoffeeScript版本是1.3.3; jQuery版本来自Rails 3.2.8 jquery-rails gem 2.1.3。

我有一系列诗歌,各自的链接存储在$ poems_for_year_hrefs中。我可以使用$ .each()获取$ poems_for_year_hrefs中元素的索引并存储在poemUrls中。

页面的下一个链接,单击时,用于将poemUrls的索引增加到下一个元素,并更新$ next_link的href属性。如果索引超过poemUrls的长度,则将索引设置回0以给出数组中的第一个元素。

页面的上一个链接,单击时,用于通过将poemUrl中的当前索引递减1来获取$ poems_for_year_hrefs中的下一个元素。然后它更新$ prev_link的href属性。如果当前索引小于或等于0,则转到poemUrls数组中的最后一个元素。

以下是CoffeeScript代码:

$(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')}"

和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>

我正在使用Ajax对主诗歌div进行更新。如果我点击诗歌中的第二首诗(id = 17),主诗歌div将更新,显示第二首诗的内容(id = 17)。如果我点击下一个链接,将返回在位置0的poemUrls中编入索引的第一首诗。然后我点击下一步,返回poemUrls的位置1中的诗然后再次返回并返回位置2,就像它应该的那样移动。一旦我到达数组的末尾,我单击下一个链接将索引计数循环回到0以到达poemUrls数组的开头,我需要单击下一步两次。第一次点击什么都不做。

如果我选择第三首诗,则会遇到同样的问题,然后点击上一个链接。索引从0开始,然后返回poemUrl数组的第一个位置。单击“上一步”,逐行将索引递减一次。获取第一个元素,然后我需要单击前两次以到达数组中的最后一个位置。

为什么我需要点击两次?它是一个失去上下文的变量吗?

* 另外如何将当前所选元素的引用传递给$ next_link.click,以便它知道当前元素的选择是什么,并且可以获得正确的下一个元素而不是从0开始?换句话说,如果我在诗歌中点击第二首诗(id = 17),我怎样才能获得$ next_link.click来返回第三首诗(id = 18),或者如果我点击之前获得$ prev_link .click返回第一首诗(id = 16)?*

CoffeeScript编译为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')));
  });
});

修改

    $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}"

测试结果 poemUrls数组包含:/ poetry / 2011 / 1st%20poem%20title%202011?id = 19,/ poetry / 2011 / 2nd%20poem%20title%202011?id = 20,/ poetry / 2011 / 3rd%20poem%20title %202011?ID = 21

点击索引为2的诗歌标题(数组中包含3首诗的最后一首诗) 当我打电话给$ prev_link.click时,prevPoemUrl是/ poetry / 2011 / 3rd%20poem%20title%202011?id = 21(数组中的最后一首诗) 当我拨打$ prev_link_click时,prev_link href未定义

我再次点击最后一首诗: 点击索引为2(最后一首诗)的诗歌标题

当我拨打$ next_link_click时,nextPoemUrl是:/ poetry / 2011 / 1st%20poem%20title%202011?id = 19

当我拨打$ next_link_click时,next_link href是:undefined

似乎prev返回索引的最后一首诗,然后返回索引的第一首诗 谢谢你的帮助!

2 个答案:

答案 0 :(得分:1)

你有off-by-one error。错误发生在,

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

在您的示例中,poemUrls.length 3 ,并且由于JavaScript数组从零开始(它们从零开始计数),因此有效索引为 0,1和2 即可。在将其设置为 0 之前,第一个代码段会让索引变为 3 。当第二个代码段达到 0 时,会将索引设置为 3 。更正的代码是,

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

修改

解决第二个问题,如果你想访问当前诗歌的兄弟姐妹,你可以使用你的数组和索引结构。快速的CoffeeScript解决方案将是,

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

答案 1 :(得分:0)

这是获取所点击的诗的当前位置的来源,并且相应地继续下一个和上一个链接。这是草稿,但有效:

$(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')