2009-09-06 105 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. 
});