1

给出了段落列表(<p>)。一旦用户点击段落A,段落A的类别就变为“已激活”。现在用户选择段落 B 并且 A 和 B 之间的所有段落都将其类更改为“已激活”。

通过再次单击 B,只有 A 保持“活动”类。

通过单击 A,A 和 B 之间的所有段落(包括 A 和 B)中的“活动”类将被删除。

不可能“停用” A 和 B 之间的任何段落。A 和 B 之间的选择应该始终是所选段落的不间断列表。

谁能给我一个关于如何使用 Prototype/Scriptaculous 实现这一点的提示?该应用程序是在 Rails 中实现的,因此 RJS 中的任何提示都将更加感激!

4

4 回答 4

1

假设您的段落位于名为“info”的包装 div 中:(我尚未对其进行测试,但它会是这样的)

$('info').select('P').each(function(element) {
    Event.observe(element,'click',function(event){
        flipIt(event)
    })
})

function flipIt(evt) {  
    var element = evt.element();
    if($(element).hasClassName('active')) {
        $(element).removeClassName('active')
    }
    else {
        $(element).addClassName('active')
    }
}
于 2009-03-10T17:15:49.433 回答
1

我已经测试了下面的代码,它可以满足您的需求,尽管它有点复杂。它的关键是将段落保存在一个数组中,这是使用 Prototype 的$$函数实现的。

<style type="text/css">
  .activated {
    background-color: yellow;
  }
</style>
.
.
.
<div id="container">
  <p>This is paragraph 1.</p>
  <p>This is paragraph 2.</p>
  <p>This is paragraph 3.</p>
  <p>This is paragraph 4.</p>
  <p>This is paragraph 5.</p>
  <p>This is paragraph 6.</p>
</div>
<script type="text/javascript">
  Event.observe(document, "dom:loaded", function() {
    var paragraphs = $$("#container p");
    paragraphs.each(function(paragraph, index) {
      paragraph.observe("click", function(event) {

        // A clicked; toggle activated class on A
        if (index == 0) {
          toggleStyle(paragraphs[0]);

          // A clicked; remove activated class from A + 1 through to B
          // if present
          for (var i = 1; i <= paragraphs.length; i++) {
            if (paragraphs[i] && paragraphs[i].hasClassName("activated")) {
              paragraphs[i].removeClassName("activated");
            }
          }
        }

        // A + 1 clicked; toggle activated class on A + 1
        if (index > 0 && paragraphs[0].hasClassName("activated")) {
          for (var i = 1; i <= index; i++) {
            toggleStyle(paragraphs[i]);
          }
        }
      });
    });
  });

  function toggleStyle(paragraph) {
    if (paragraph.hasClassName("activated")) {
      paragraph.removeClassName("activated");
    } else {
      paragraph.addClassName("activated");
    }
  }
</script>
于 2009-03-11T09:48:48.017 回答
1

试试这个

<!DOCTYPE HTMP PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
 <head>
  <%= javascript_include_tag :defaults %>
 </head>
 <body>

<style type="text/css">
  .active {
    background-color: maroon;
  }
</style>

<div id="info">
<p>
1 ald fhasdfd sfhjfh afhd fhasjfhjsdah fadfhasd<br/>
fasdhfhsdf ajhajkfh dfhdasjf fhdasf asdf<br/>
asdfh hsdjkhf dhfasdfh asdjfkdhfjkasd<br/>
fsdhf jksdhf sdfjkh asfsdf asdfasdfasdh<br/>
</p>
<p>
2 ald fhasdfd sfhjfh afhd fhasjfhjsdah fadfhasd<br>
fasdhfhsdf ajhajkfh dfhdasjf fhdasf asdf<br/>
asdfh hsdjkhf dhfasdfh asdjfkdhfjkasd<br/>
fsdhf jksdhf sdfjkh asfsdf asdfasdfasdh<br/>
</p>
<p>
3 ald fhasdfd sfhjfh afhd fhasjfhjsdah fadfhasd<br>
fasdhfhsdf ajhajkfh dfhdasjf fhdasf asdf<br/>
asdfh hsdjkhf dhfasdfh asdjfkdhfjkasd<br/>
fsdhf jksdhf sdfjkh asfsdf asdfasdfasdh<br/>
</p>
<p>
4 ald fhasdfd sfhjfh afhd fhasjfhjsdah fadfhasd<br>
fasdhfhsdf ajhajkfh dfhdasjf fhdasf asdf<br/>
asdfh hsdjkhf dhfasdfh asdjfkdhfjkasd<br/>
fsdhf jksdhf sdfjkh asfsdf asdfasdfasdh<br/>
</p>
</div>
<%javascript_tag :defer => 'defer' do -%>
  $('info').select('P').each(function(element) {
    Event.observe(element,'click',function(event){
        flipIt(event)
    })
})

function flipIt(evt) {

    var element = evt.element();
    var all = $('info').select('P');
    var first = -1;
    var last = -1;
    var clicked = 0;
    for ( i=0;i<all.size();i++ ) {
         if( all[i].hasClassName('active') && first == -1   )
           first = i;
         if( all[i].hasClassName('active') && first != i  )
           last = i;
         if ( all[i] == element){
              clicked = i;
          }
    }
   if ( first == clicked && last == -1 ){
        all[clicked].removeClassName('active');
       return;

}
   if ( first  == -1 && last == -1 ) {
        all[clicked].addClassName('active');
        return;
}
   if ( last < clicked  && first != -1 ){
      for (i=first;i<=clicked;i++)
        all[i].addClassName('active');
      return;
   }
   if (last == clicked && first != -1 ) {
      for (i=first+1;i<=clicked;i++)
        all[i].removeClassName('active');
    return; }
}

<%end%>
 </body>
</html>
于 2009-03-11T10:23:52.160 回答
0

好的,与此同时,在同事的帮助下,我想出了一个自己的答案来解决这个问题:

<script type="text/javascript">
    // holds paragraph A (first selected paragraph)
    var a_selected = null;
    // holds paragraph B (second selected paragraph)
    var b_selected = null;
    // holds all 'active' paragraphs
    var selected_paras = [];

    function class_flipper_init() {
        // reset paragraphs A and B
        a_selected = null;
        b_selected = null;
        var paragraphs = $$("#foobar p");
        paragraphs.each(function(paragraph, index) {
            // if user clicks on a paragraph
            paragraph.observe("click", function(event) {
                // if A and B are 'active': reset everything.
                if(b_selected != null) {
                    selected_paras.each(function(i) {
                        toggleStyle(i);
                    })
                    a_selected = null
                    b_selected = null
                    return
                }
                // if A is 'active'
                if(a_selected != null) {
                    // if A is 'active' and selected B is below A:
                    // select all paragraphs between A and B
                    if(a_selected < index) {
                        b_selected = index;
                        for (var i = a_selected + 1; i <= index; i++ ) {
                            toggleStyle(paragraphs[i])
                        }
                    }
                    // if A is 'active' and selected B is above A: 
                    // select all paragraphs between A and B
                    else if(a_selected > index) {
                        b_selected = index;
                        for (var i = a_selected - 1; i >= index; i-- ) {
                            toggleStyle(paragraphs[i])
                        }
                    }
                    // if A == B
                    else {
                        toggleStyle(paragraph)
                        a_selected = null
                    }
                }
                // if A is selected
                else {
                    a_selected = index;
                    toggleStyle(paragraph)
                }
            });
        });
    }

    function toggleStyle(paragraph) {
        // remove active class
        if (paragraph.hasClassName("active")) {
            paragraph.removeClassName("active");
            selected_paras = selected_paras.without(paragraph)
        } 
        // set active class
        else {
            paragraph.addClassName("active");
            selected_paras.push(paragraph)
        }
    }
</script>

class_flipper_init()每次加载页面(或者在我的情况下是某个部分)时都会调用它。

请不要犹豫,提交用“纯” RJS 或更优雅的方式编写的解决方案。:-)

于 2009-03-11T16:00:16.440 回答