0

Я пытаюсь применить изменения к DOM при нажатии на <tr>. При нажатии, она должна добавить data-state=enabled и data-display=expanded к щелкнули <tr> при применении data-state=disabled и data-display=collapsed к каждый<tr>.Изменение атрибута данных при щелчке элементов HTML

Таким образом, это должно выглядеть как выделение щелкнутой строки при отключении других строк.

Затем, когда выделена строка, и пользователь щелкает в другом месте, он должен сброса по умолчанию, т.е. data-state=enabled и data-display=collapsed для всех <tr> «s

В настоящее время у меня он работает так, что когда <tr> , эта строка подсвечивается, а все остальные отключены. Однако, сценарий не имеет сброса к умолчанию, потому что если щелкнуть другое <tr>, оно сразу подсвечивает это и отключает остальные.

Я хотел бы сделать это в javascript vanilla, но я также открыт для использования jQuery, если он значительно проще и не повлияет на производительность заметно.

Вот в JSbin с рабочим кодом, чтобы увидеть, где он по адресу: https://jsbin.com/kirati/

И код до сих пор:

<table class="table"> 
        <thead> 
         <tr> 
          <th class="sort-key asc"><a href="#">Pet Name </a></th> 
          <th><a href="#">Owner (Last, First)</a></th> 
          <th><a href="#">Species</a></th> 
          <th><a href="#">Breed</a></th> 
          <th><a href="#">ID</a></th> 
         </tr> 
        </thead> 
        <tbody> 
         <tr> 
          <td> 
           Fluffy 
           <div class="table-row__expanded-content"> 
            <data-key>Sex: </data-key> <data-value>Male</data-value><br /> 
            <data-key>DOB: </data-key> <data-value>12/08/2010</data-value> <br /> 
            <data-key>Weight: </data-key> <data-value>20 lbs</data-value> <br /> 
            <data-key>Location: </data-key> <data-value>Kennel 2B</data-value> <br /> 
            <data-key>Temperament: </data-key> <data-value>Aggresive</data-value> <br /> 
            <data-key>Allergies: </data-key> <data-value>Sulfa, Penicillin, Peanuts</data-value> 
           </div> 
          </td> 
          <td>Anderson, James</td> 
          <td>Dog</td> 
          <td>Bulldog-Shitzu</td> 
          <td>ABCDE1234567</td> 
         </tr> 
         <tr> 
          <td>Feather</td> 
          <td>Michelle Charlotte, <br /> Angel Vanessa</td> 
          <td>Cat</td> 
          <td>American Bobtail</td> 
          <td>FGHIJ1234567</td> 
         </tr> 
         <tr> 
          <td>Fluffer-Nutter</td> 
          <td>Rakerstraw, Rickey</td> 
          <td>Dog</td> 
          <td>American Eskimo</td> 
          <td>KLMNO1234567</td> 
         </tr> 
         <tr> 
          <td>Farley</td> 
          <td>Cunningham, Stephanie</td> 
          <td>Dog</td> 
          <td>Pomeranian</td> 
          <td>PQRST1234567</td> 
         </tr> 
         <tr> 
          <td>Fuzzy</td> 
          <td>Venice, Harding</td> 
          <td>Cat</td> 
          <td>Burmese</td> 
          <td>UVWXY1234567</td> 
         </tr> 
         <tr class="alphabet-label"> 

          <td>G</td> 
          <td></td> 
          <td></td> 
          <td></td> 
          <td></td> 
         </tr> 
         <tr> 
          <td>Goldie</td> 
          <td>Cherilyn, Mitchener</td> 
          <td>Dog</td> 
          <td>Chihuahua-Maltese</td> 
          <td>ZABCD1234567</td> 
         </tr> 
        </tbody> 
       </table> 

И Javascript

window.onload = function() { 

    var tablerow = document.body.getElementsByTagName('tr'); 
    console.log(tablerow); 

    // Convert the HTMLCollection into a true javascript Array, so we can do "stuff" with it  
    var tablerowArr = Array.prototype.slice.call(tablerow); 
    console.log(tablerowArr); 

// Do stuff 
    tablerowArr.forEach(function (value, i) { 
     console.log(i, value); 

     tablerow[i].onclick = function (e) { 
      //console.log("clicked!"); 


      var newArr = tablerowArr.slice(i, i + 1); 
      //console.log(tablerow); 
      console.log(i); 
      //console.log(tablerowArr); 
      console.log('newArr', newArr); 


      tablerowArr.forEach(function (value, i) { 

       // first reset all instances of data-XXX 
       tablerowArr[i].setAttribute('data-display', "collapsed"); 
       // tablerowArr[i].setAttribute('data-state', "enabled"); 

       // Set the <tr> data-display attribute to expanded/collapsed on click 
       newArr[0].setAttribute('data-display', tablerowArr[i].getAttribute('data-display') === "collapsed" ? "expanded" : "collapsed"); 
       //tablerowArr[i].setAttribute('data-display', tablerowArr[i].getAttribute('data-display') === "collapsed" ? "expanded" : "collapsed"); 

       // Set the <tr> data-state attribute to enabled/disabled on click 
       newArr[0].setAttribute('data-state', newArr[0].getAttribute('data-state') === "disabled" ? "enabled" : "enabled"); 
       tablerowArr[i].setAttribute('data-state', newArr[0].getAttribute('data-state') === "enabled" ? "disabled" : "enabled"); 

      }); 

      e.preventDefault(); 
     }; 
    }); 
}; 
+0

попробовать это решение, возможно, это может помочь [Как изменить данные элемента HTML Object значение атрибута в JavaScript] (http://stackoverflow.com/questions/4836290/how-to-change-html-object- element-data-attribute-value-in-javascript) или этот [Установить атрибут данных с использованием JavaScript] (http: // stackoverflow.com/questions/11286661/set-data-attribute-using-javascript) – Gardezi

+0

«используйте jQuery, если он значительно проще и не повлияет на производительность заметно» - он всегда значительно проще и не влияет на производительность –

+0

Я предпочитаю VanillaJS потому что это помогает мне лучше понимать JavaScript, а не полагаться на «волшебство» из классных библиотек, таких как jQuery. Конечно, есть время и место для библиотек, потому что они делают некоторые вещи очень легкими - но бывают случаи, когда pureJS просто отлично (и помогает моему пониманию расти). – TetraDev

ответ

1

Вот чистый Javascript пример ниже jsfiddle:

http://jsfiddle.net/pya9jzxm/14

var tbody = document.querySelector('tbody'); 
    var trs = tbody.querySelectorAll('tr'); 
    var tr, index = 0, length = trs.length; 
    for (; index < length; index++) { 
     tr = trs[index]; 
     tr.setAttribute('data-state', 'enabled'); 
     tr.setAttribute('data-display', 'collapsed'); 
     tr.addEventListener('click', 
      function() { 
       if (this.classList.contains('alphabet-label')) { 
        return; 
       } 
       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++) { 
        trs[trIndex].setAttribute('data-state', state); 
        trs[trIndex].setAttribute('data-display', 'collapsed'); 
       } 
       if (!hasExpanded) { 
        this.setAttribute('data-state', 'enabled'); 
        this.setAttribute('data-display', 'expanded'); 
       } 
      } 
     ); 
    } 
}; 
+0

Спасибо, я вижу, что он работает, чтобы выделить на клик, однако часть, которую я отсутствовала, получала ее, чтобы сбросить ее до значения по умолчанию после нажатия выделенной строки. то есть первый щелчок от выделенной строки делает каждую строку невыполненной, второй щелчок затем выделяет новую строку. – TetraDev

+0

ОК, так что даже щелчок по другой строке сначала отменяет выбор? Или просто щелкнуть от любой строки в области, которая не является строкой? – AtheistP3ace

+0

Обновлена ​​скрипка, при которой щелчок по другим строкам сначала удаляет подсветку. а затем нажмите снова, добавив его в новую строку. – AtheistP3ace

0

в JQuery:

$(function() { 
    $('html').click(function() { 
     /* return to default state */ 
     $('.table tbody tr').data('state', 'enabled').data('display', 'expanded'); 
    }); 
    $('.table tbody tr').on('click', function(e) { 
     /* stop the html click event */ 
     e.stopPropagation(); 
     /* set attributes for all rows */ 
     $('.table tbody tr').data('state', 'disabled').data('display', 'collapsed'); 
     /* set attributes for the clicked row */ 
     $(this).data('state', 'enabled').data('display', 'expanded'); 
    }); 
}); 

Я прокомментировал функцию, чтобы уточнить, как она работает.

+0

просто дважды проверьте $ (this) .data (вы не имеете в виду $ (this) .attr (? – Seabizkit

+0

Когда я добавил это в свой JSbin с загруженным jquery, скрипт не работал, используя (this) .data и (this) .attr - см. JS bin с исходным кодом: https://jsbin.com/xukiyoragu – TetraDev

+0

@ freedomn-m не возражаете, отправляя ссылку для поддержки своего заявления, поскольку у меня есть тот, который прямо противоречит вам. https: //api.jquery .com/data/ – Seabizkit

0

Использование ванильный JS и делегирование событий. DEMO

var tablerow = document.body.getElementsByTagName('tr'); 
// Convert the HTMLCollection into a true javascript Array, so we can do "stuff" with it  
var tablerowArr = Array.prototype.slice.call(tablerow); 
// store the highlighted row 
var highlighted; 

// extracted function to enable/disable rows 
var enable = function(row){ 
    row.setAttribute('data-display', "expanded"); 
    row.setAttribute('data-state', "enabled"); 
} 
var disable = function(row){ 
    row.setAttribute('data-display', "collapsed"); 
    row.setAttribute('data-state', "disabled"); 
} 
// on click anywhere 
document.body.addEventListener('click', function(e){ 
    var target = e.target; 
    // check if event target or any of its parents is a TR 
    while(target.parentNode && target.nodeName.toLowerCase() != 'tr'){ 
     target = target.parentNode; 
    } 
    // if s row was higlighted disable all rows 
    if(highlighted){ 
     tablerowArr.forEach( disable); 
     // and remove the reference to highlighted 
     highlighted = null; 
    } 
    // no row is highlighted 
    else { 
     tablerowArr.forEach(function(row){ 
      // if the event target is a row, highlight it 
      if(row == target) { 
       enable(row); 
       // and store it as the currently highlighted 
       highlighted = row; 
      } 
      // if it's not the event target then disable 
      else { 
       disable(row); 
      } 
     }); 
    } 
}); 
+0

Работает отлично, за исключением того, что также отсутствует «сброс до значения по умолчанию» после нажатия выделенной строки. то есть первый щелчок от выделенной строки делает каждую строку невыполненной, второй щелчок затем выделяет новую строку. – TetraDev

+0

@TetraDev Я сосредоточился на «щелчке в любом месте», чтобы удалить блики. Исправлено теперь, чтобы удалить подсветку при первом щелчке. – pawel

+0

Спасибо - эта часть работает. Но я не сообщал четко - при перезагрузке все строки должны вернуться к умолчанию 'data-state-enabled' и' data-display = collapsed'. Прямо сейчас, когда применяется «сброс», все строки отключены и сбрасываются (должны быть включены и свернуты) – TetraDev

0

Что очень Двойники в @LinkinTED

Пожалуйста, проверьте HTML, прежде чем сказать, что это не работает .. Я проверил это сам.

Могу ли я предложить вместо этого изменить класс ..., чтобы изменить эффекты.

$(function() { 

    var $row = $('.table tbody tr'); 

    $('html').click(function() { 
     $row.attr('state', 'enabled').attr('display', 'expanded'); 
    }); 

    $row.on('click', function(e) { 
     e.stopPropagation(); 
     $row 
      .attr('state', 'disabled') 
      .attr('display', 'collapsed'); 

     //console.log(e); 

     $(this) 
      .attr('state', 'enabled') 
      .attr('display', 'expanded'); 
    }); 
}); 
+0

Он работает, если я редактирую attr для состояния данных и отображения данных (это то, что мне нужно для моего CSS). Несмотря на то, что при переходе на другую строку после «подсвечивания» он просто пропускает «сброс». Он сбрасывается, если я нажимаю в любом месте DOM, который не является , но он также должен быть сброшен даже при нажатии на другой перед применением следующего выделения. – TetraDev

+0

OK, но это просто: выделить строку и показать скрытые данные при нажатии, если это так, я бы изменил это, чтобы добавлять и удалять классы вместо отработки атрибутов. Вы могли бы просто добавить чек для удовлетворения своих дополнительных требований. Также, если вам не нравится переменная rest, вы можете ее изменить. – Seabizkit

+0

Это не вопрос «проверки html», потому что OP использует * css *, который ищет атрибуты «состояние данных», поэтому 'attr (« state »)' не то же самое, что 'attr (« состояние данных » ")' –

Смежные вопросы