Change data-attribute on click of HTML elements

徘徊边缘 提交于 2019-12-25 13:17:15

问题


I am trying to apply changes to the DOM when a <tr> is clicked. When clicked, it should add data-state=enabled and data-display=expanded to the clicked <tr> while applying data-state=disabled and data-display=collapsed to every other <tr>.

So it should look like highlighting the clicked row while disabling the other rows.

Then, when a row is highlighted, and a user clicks elsewhere, it should reset to default, i.e. data-state=enabled and data-display=collapsed for all <tr>'s

Currently, I have it working so that when a <tr> is clicked, that row is highlighted and all others disabled. However, the script is missing the reset to default because if another <tr> is clicked, it immediately highlights that one and disables the rest.

I would like to do this in vanilla javascript but I am also open to using jQuery if it is substantially easier and won't affect performance noticably.

Here is the JSbin with working code to see where it's at: https://jsbin.com/kirati/

And the code so far:

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

And the 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();
        };
    });
};

回答1:


Here is a pure javascript example in the below 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');
                }
            }
        );
    }
};



回答2:


in 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');
    });
});

I've commented the function, to clarify how it works.




回答3:


Which is very simular to @LinkinTED

Please inspect the html before you say this does not work.. I've tested it myself.

May i suggest that you instead modify the class... to change the effects.

$(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');
    });
});



回答4:


Using vanilla JS and event delegation. 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 ); 
            }
        });
    }
});


来源:https://stackoverflow.com/questions/33128718/change-data-attribute-on-click-of-html-elements

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!