2015-12-29 54 views
1

當頁面包含單個表格時,我有兩個腳本可以很好地工作。但是,現在我需要在支持相同功能的同一頁面上放置多個表格。將腳本轉換爲獨立處理多個表格

我需要一些幫助轉換這兩個腳本與同一頁面上的多個表的工作,同時保持相同的功能。

第一個腳本被稱爲「TABLE數據狀態」。 第二個腳本被稱爲「SORT TABLE DATA」。

當前JSBin: https://jsbin.com/noyoluhasa/1/edit?html,js,output

// =================================================================== 
// =================== TABLE DATA STATES ============================= 
// =================================================================== 

// Answer to my question on Stackoverflow: 
// http://stackoverflow.com/questions/33128718/change-data-attribute-on-click-of-html-elements 
// JsFiddle: http://jsfiddle.net/pya9jzxm/14 

// Get all rows into the array except the <thead> row 
var tbody = document.querySelector('tbody'); 
var trs = tbody.querySelectorAll('tr'); 
var tr, index = 0, length = trs.length; 
// Start the loop 
for (; index < length; index++) { 
    tr = trs[index]; 
    // Set the attributes to default state 
    tr.setAttribute('data-state', 'enabled'); 
    tr.setAttribute('data-display', 'collapsed'); 
    tr.addEventListener('click', 
     function() { 
      // If its the row alphabet-label, skip it 
      if (this.classList.contains('alphabet-label')) { 
       return; 
      } 
      // Conditional logic to make the rows reset after clicking away from highlighted row 
      var trIndex = 0, trLength = trs.length, hasExpanded = false; 
      var state = 'disabled'; 
      if (tbody.querySelectorAll('[data-display="expanded"]').length > 0) { 
       hasExpanded = true; 
       state = 'enabled'; 
      } 
      for (; trIndex < trLength; trIndex++) { 
       // Set all rows to disabled on click of any row 
       trs[trIndex].setAttribute('data-state', state); 
       // Reset the display of all rows 
       trs[trIndex].setAttribute('data-display', 'collapsed'); 
      } 
      if (!hasExpanded) { 
       // Set the clicked row to active highlighted state 
       this.setAttribute('data-state', 'enabled'); 
       this.setAttribute('data-display', 'expanded'); 
      } 
     } 
    ); 
} 


// =================================================================== 
// =================== SORT TABLE DATA =============================== 
// =================================================================== 
// For reference: 
// this.setAttribute('data-state', this.getAttribute('data-state').contains === "enabled" ? "disabled" : "enabled"); 

// Adds icon to clicked <th> 
// VanillaJS version - opted for jquery.tablesorter plugin due to flexibility and ease of use 
var thsort = document.querySelectorAll('th') 
//console.log(thsort); 
var sort, sortIndex = 0, sortlength = thsort.length; 
for (; sortIndex < sortlength; sortIndex++) { 
    sort = thsort[sortIndex]; 
    //console.log(sort); 
    // On click to sort table column, do this: 
    sort.addEventListener('click', 
     function() { 
      var rm, rmIndex = 0; 
      for (; rmIndex < sortlength; rmIndex++) { 
       rmsort = thsort[rmIndex]; 
       // Remove sort icon from other <th> elements 
       rmsort.classList.remove('sort-key'); 
       // Add sort icon to this <th> 
       this.classList.add('sort-key'); 
       //console.log(rmsort); 


       // Conditional logic to switch asc desc label 
       var state = 'asc', prevState = 'desc', hasAsc, prevState; 
       if (this.classList.contains('asc')) { 
        hasAsc = true; 
        state = 'desc'; 
        prevState = 'asc'; 

        //console.log(prevState); 

       } 
       // Set all rows to disabled on click of any row 
       this.classList.add(state); 
       this.classList.remove(prevState); 

       //if (hasAsc) { 
       // // Set the clicked row to active highlighted state 
       // this.setAttribute('class', state); 
       //} 
      } 
     } 
    ); 
} 

我想包裝我的代碼在這段代碼中,除了與thisTable更換的tbody實例,但隨後的腳本只是工作的表的最後一個實例:

var alltables = document.querySelectorAll('tbody') 
console.log(alltables); 
var thisTable, sortIndex = 0, sortlength = alltables.length; 
for (; sortIndex < sortlength; sortIndex++) { 
    thisTable = alltables[sortIndex]; 
    // original code here 
} 

回答

1

所以這真的只是一個範圍的問題。您在事件處理程序中引用tbodytrs的此NodeList,但由於多個表,這些值隨時間而改變。當這些處理程序被調用,它看到tbody它首先檢查該變量是否是其當前範圍的一部分,而不是。所以它會檢查下一個示波器直到找到它。但它發現的是隨着時間的推移該變量的最後一個值。

解決這個問題的最簡單的方法就是圍繞你原來的代碼塊的功能,給它範圍的調用時,並調用該函數傳遞當前表,它爲每個表。那麼函數在其範圍內唯一的事情就是我們關心的表格,並且我們在該函數中創建的每個變量(如trs)都將僅在該特定函數調用的範圍內。

看看下面的代碼,並檢查了小提琴,讓我知道,如果您有任何關於它的問題。你可以看到我用所有表的該循環您最初的想法只是我發現基礎上,table類的表,查詢的表其tbody並通過了我們的configureTable功能。

小提琴:https://jsfiddle.net/rbpc5vfu/

ConfigureTable功能:

function configureTable (tbody) { 
    var trs = tbody.querySelectorAll('tr'); 
    var tr, index = 0, 
     length = trs.length; 
    // Start the loop 
    for (; index < length; index++) { 
     tr = trs[index]; 
     // Set the attributes to default state 
     tr.setAttribute('data-state', 'enabled'); 
     tr.setAttribute('data-display', 'collapsed'); 
     tr.addEventListener('click', 
      function() { 
       // If its the row alphabet-label, skip it 
       if (this.classList.contains('alphabet-label')) { 
        return; 
       } 
       // Conditional logic to make the rows reset after clicking away from highlighted row 
       var trIndex = 0, 
        trLength = trs.length, 
        hasExpanded = false; 
       var state = 'disabled'; 
       if (tbody.querySelectorAll('[data-display="expanded"]').length > 0) { 
        hasExpanded = true; 
        state = 'enabled'; 
       } 
       for (; trIndex < trLength; trIndex++) { 
        // Set all rows to disabled on click of any row 
        trs[trIndex].setAttribute('data-state', state); 
        // Reset the display of all rows 
        trs[trIndex].setAttribute('data-display', 'collapsed'); 
       } 
       if (!hasExpanded) { 
        // Set the clicked row to active highlighted state 
        this.setAttribute('data-state', 'enabled'); 
        this.setAttribute('data-display', 'expanded'); 
       } 
      } 
     ); 
    } 


    // =================================================================== 
    // =================== SORT TABLE DATA =============================== 
    // =================================================================== 
    // For reference: 
    // this.setAttribute('data-state', this.getAttribute('data-state').contains === "enabled" ? "disabled" : "enabled"); 

    // Adds icon to clicked <th> 
    // VanillaJS version - opted for jquery.tablesorter plugin due to flexibility and ease of use 
    var thsort = tbody.querySelectorAll('th'); 
     //console.log(thsort); 
    var sort, sortIndex = 0, 
     sortlength = thsort.length; 
    for (; sortIndex < sortlength; sortIndex++) { 
     sort = thsort[sortIndex]; 
     //console.log(sort); 
     // On click to sort table column, do this: 
     sort.addEventListener('click', 
      function() { 
       var rm, rmIndex = 0; 
       for (; rmIndex < sortlength; rmIndex++) { 
        rmsort = thsort[rmIndex]; 
        // Remove sort icon from other <th> elements 
        rmsort.classList.remove('sort-key'); 
        // Add sort icon to this <th> 
        this.classList.add('sort-key'); 
        //console.log(rmsort); 


        // Conditional logic to switch asc desc label 
        var state = 'asc', 
         prevState = 'desc', 
         hasAsc, prevState; 
        if (this.classList.contains('asc')) { 
         hasAsc = true; 
         state = 'desc'; 
         prevState = 'asc'; 

         //console.log(prevState); 

        } 
        // Set all rows to disabled on click of any row 
        this.classList.add(state); 
        this.classList.remove(prevState); 

        //if (hasAsc) { 
        // // Set the clicked row to active highlighted state 
        // this.setAttribute('class', state); 
        //} 
       } 
      } 
     ); 
    } 
} 

負載初始化表:

var alltables = document.querySelectorAll('.table'); 
var thisTable, sortIndex = 0, sortlength = alltables.length; 
for (; sortIndex < sortlength; sortIndex++) { 
    thisTable = alltables[sortIndex]; 
    var tbody = thisTable.querySelector('tbody'); 
    configureTable(tbody); 
} 

正如你可以看到我真的沒有太大變化,如果你看。我只是將你的原始代碼包裝在一個功能塊中。然後從上面偷走你的循環,找到所有的表,爲每個表找到它的tbody,並調用我們的新函數將tbody傳遞給它。瞧。範圍!

+0

老兄!謝謝!這很有意義,它完美地工作。我非常感謝你的幫助! – TetraDev

+0

所以,如果我理解正確,沒有在代碼中包裝一個函數,那麼每次腳本發現一個新表時,所有的值都會改變,所以它只會引用它找到的表的最後一個實例。但是通過將代碼封裝在一個函數中,然後將每個表單獨傳遞給該函數,我們通過爲每個表創建一個範圍來解決該問題,確保變量不會被其他表所改變。感謝您的解釋:-) – TetraDev

+1

沒錯。循環隨着時間的推移而改變這些值。通過添加函數範圍,我們保證當那些事件處理程序查找這些變量的範圍時,它們仍然保持我們期望的值。樂於幫助!!很高興它爲你工作。 – AtheistP3ace