原型/Scriptaculous:通过单击段落组 (

) 来选择它们

发布于 2024-07-14 17:40:45 字数 366 浏览 7 评论 0原文

给出了段落列表 (

)。 一旦用户单击段落 A,段落 A 的类别就会更改为“已激活”。 现在,用户选择段落 B,并且 A 和 B 之间的所有段落都将其类别更改为“已激活”。

再次单击 B,只有 A 仍属于“活动”类。

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

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

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

A list of paragraphs (<p>) is given. As soon as the user clicks on paragraph A the class of paragraph A changes to "activated". Now the user selects paragraph B and all the paragraphs between A and B change their class to "activated".

By clicking on B again, only A remains with the class "active".

By clicking on A the class "active" gets removed on all paragraphs between A and B (including A and B).

It shouldn't be possible to "deactivate" any paragraph between A and B. The selection between A and B should always be a uninterrupted list of selected paragraphs.

Can anyone give me a hint on how to realize this with Prototype/Scriptaculous? The application is implemented in Rails, so any hint in RJS would even be more appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

要走就滚别墨迹 2024-07-21 17:40:46

好的,与此同时,在同事的帮助下,我对这个问题提出了自己的答案:

<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 或更优雅的东西编写的解决方案。 :-)

OK, in the meantime and with the help of a coworker I came up with an own answer to this problem:

<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() is called everytime the page (or in my case a certain partial) is loaded.

Please don't hesitate to submit a solution written in "pure" RJS or something more elegant. :-)

-黛色若梦 2024-07-21 17:40:45

假设你的段落位于一个名为“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')
    }
}

Assuming your paragraphs are in a wrapper div called 'info': (I haven't tested it, but it would be something like this)

$('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')
    }
}
ヤ经典坏疍 2024-07-21 17:40:45

尝试这个

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

Try this

<!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>
猛虎独行 2024-07-21 17:40:45

我已经测试了下面的代码,它可以满足您的要求,尽管它有点复杂。 它的关键是将段落保存在一个数组中,这是使用 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>

I've tested the code below and it does what you want, although it's a bit convoluted. The key to it is holding the paragraphs in an array, which is achieved using Prototype's $$ function.

<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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文