2009-09-06 75 views
5

我想允许用户点击一个起点,然后点击一个终点,并能够在选定的两点之间操作各种表单元素。如何使用jquery遍历dom中两个已知元素之间的元素?

该页面是一个有许多行的表格,每行包含相关信息来操纵/保存该行中问题的答案。每行都有一个隐藏的输入值,以及Yes/No单选按钮,主要用于不熟练的用户。具有该问题的TD小区允许用户点击或切换是,否,空。所以基本上我留下页面上的单选按钮来显示是/否,并使用隐藏字段来存储值(1,0,-1)

这是我用来设置问题单元格时的答案被点击。

$(".question").bind("click dblclick", function(e) { 

     var newClassName = "AnswerUnknown"; 

     var hiddenAnswerId = $(this).attr('id').replace("question", "answer"); 

     var answer = parseInt($("#" + hiddenAnswerId).val()); 

     var newValue; 

     switch (answer) { 
      case -1: 
       newClassName = "AnswerCorrect"; 
       newValue = 1; 
       $("#" + $(this).attr('id').replace("answer", "radioYes")).attr('checked', 'checked'); 
       $("#" + $(this).attr('id').replace("answer", "radioNo")).attr('checked', ''); 
       break; 
      case 1: 
       newClassName = "AnswerWrong"; 
       newValue = 0; 
       $("#" + $(this).attr('id').replace("answer", "radioYes")).attr('checked', ''); 
       $("#" + $(this).attr('id').replace("answer", "radioNo")).attr('checked', 'checked'); 
       break; 
      default: 
       newClassName = "AnswerEmpty"; 
       newValue = -1; 
       $("#" + $(this).attr('id').replace("answer", "radioYes")).attr('checked', ''); 
       $("#" + $(this).attr('id').replace("answer", "radioNo")).attr('checked', ''); 
     } 
     $("#" + hiddenAnswerId).val(newValue); 
     $(this).removeClass().addClass(newClassName); 
    }); 

现在我想允许用户点击一个起点,有一个答案填入下面所有的问题到任何地方点击第二项。可能是10个问题,或20个问题,这是一个未知的变量。可能有一个页面上有130个问题,连续20个问​​题可能是“是”。如上所述,每一行都有一个“问题”单元,并且之前的单元是单元单元。

我知道如何根据绑定到下面列出的click/dblclick事件的jquery选择器/函数来设置起始元素和结束元素。

我不确定的是如何遍历dom或选择我需要在页面上的两个选定点之间操作的所有元素。

var StartItem; 
    var EndItem; 

    $(".item").bind("click dblclick", function(e) { 

     var StartClassName = "AnswerUnknown"; 
     var EndClassName = "AnswerUnknown"; 
     var StartAnswerId; 
     var EndAnswerId; 
     var StartAnswer; 

     if (StartItem === undefined) { 
      StartItem = this; 
      StartAnswerId = $(this).attr('id').replace("item", "rs"); 
      StartAnswer = parseInt($("#" + StartAnswerId).val()); 
     } 
     else { 
      if (EndItem === undefined) { 
       EndItem = this; 
       EndAnswerId = $(this).attr('id').replace("item", "rs"); 
       EndAnswer = parseInt($("#" + EndAnswerId).val()); 
      } 
     } 


     if (StartItem == this) { 
      $(this).removeClass().addClass(StartClassName); 
     } 

     if (EndItem == this) { 
      $(this).removeClass().addClass(EndClassName); 
     } 
    }); 

回答

2

恕我直言,最好的办法是做下面的事情。你可以遍历类名称为“item”的元素集合,当你找到你的开始元素时,你可以开始进行你所描述的处理。既然你有'这',你可以采取这个ID,并做你在你的问题。点击功能。

 var counter = 0; 

    // This will loop over each element with classname "item", so make sure you take that into account 
      $('.item').each(function(i) { 
     // function returns this, but you can see what index your on with 'i' 
       if (this == StartItem) { 
        // You can start processing rows 
        counter = 1; 
       } 
       else { 
        if (counter > 0) { 
         // Process rows/items after the first item above 
         counter = counter + 1; 
        } 
       } 
       if (this == EndItem) { 
        counter = 0 
        // Finish up processing if any 
        //Break out of each; 
       } 

      }); 
+0

我能够利用它来做我所需要的。 – Breadtruck 2009-09-06 21:14:50

0

听起来最简单的方法是将起始类添加到起始元素,并将结束类添加到结束元素。然后,当遍历开始和结束之间的元素时,可以检查开始或结束类名称并执行/阻止适当的操作。

编辑:

事情是这样的插件会做到这一点。该插件假定定义范围界限的两个元素都具有相同的父元素并且具有相同的元素类型(nodeName)。您可以使用自己的开始和结束类名称,或者只使用默认的“开始”和“结束”。

(function($) { 

    $.fn.rangeSelector = function(options) { 

    var settings = $.extend({ startClass : 'start', endClass: 'end'},options||{}); 
    var name = this[0].nodeName.split(':'); 
    name = name[name.length -1]; 
    var startIndex = $(name + '.' + settings.startClass).prevAll().length; 
    var endIndex = $(name + '.' + settings.endClass).prevAll().length + 1; 
    return this.slice(startIndex,endIndex); 
    } 

})(jQuery); 

,然后你可以使用像这样

/* 
* will get all textboxes between textboxes 
* with className start and end, inclusive 
*/ 
$('input:text').rangeSelector(); 

这里有一个Working Demo。如果您想查看代码,请在网址的末尾添加/编辑。我正在考虑编写一个实用程序来返回一个基于startClass,endClass和元素类型参数的jQuery对象来包含这些参数,但这对您所需要的东西来说可能是过度的。

编辑2:

在您的评论的光,我可以跟你通过它

  1. 得到包含相关元素而你的情况,我相信一个jQuery对象是文字输入,所以它会是类似$('parent > input:text')的地方,其中parent是父元素(传入输入:如果插件依赖索引,则在父元素外部的页面中有其他文本输入时,文本本身无法正常工作)。

  2. 您可以在选项传递反对rangeSelector不同的开始和结束的类名,如果你想(像.rangeSelector({ start: "myStartClass", end: "myEndClass"}),或简单地使用在这种情况下,你不需要任何对象传递默认startend

  3. 的设置变量融合了的在选项传递的对象的属性的默认值(其被定义为一个对象的属性)(或无属性的对象,如果没有选择对象被定义)。

  4. 计算我们在jQuery对象中处理和存储的元素的类型name变量。这是通过将jQuery对象中第一个元素的nodeName字符串拆分为数组并将名称分配给数组中最后一个字符串项的值来完成的。

  5. 计算标记为startend类名称的项目的开始和结束索引。这种情况下的索引是指元素在其父代中的基于0的位置。

  6. 仅返回开始和结束索引(含)之间的jQuery对象中作为jQuery对象的所有元素(以便可以链接更多的jQuery命令)。这使用slice()命令,该函数在Array.slice()对数组执行的jQuery对象上的功能相同。

+0

所以我会用什么方法来遍历,我知道什么是eleme因为我在我的代码中设置了开始和结束元素。 – Breadtruck 2009-09-06 18:38:13

+0

@Russ:我用马特的代码来破解我需要做的事情,但我会重新审视你的东西,因为一旦我有时间思考,你的方式可能会是更优雅的解决方案! – Breadtruck 2009-09-06 21:16:39

0

的问题是有点老了,但这里是我用我的项目的解决方案:

jQuery选择

(function ($) { 
    $.fn.between = function (elm0, elm1) { 
     var index0 = $(this).index(elm0); 
     var index1 = $(this).index(elm1); 

     if (index0 <= index1) 
      return this.slice(index0, index1 + 1); 
     else 
      return this.slice(index1, index0 + 1); 
    } 
})(jQuery); 

使用

$('body').between($('#someid'), $('#someid2')).each(function() { 
    // Do what you want. 
});