Mixing javascript with jquery

2019-02-25 08:55发布

问题:

On a click I assign a class to my element (SVG PATH) using pure javascript:

this.getElement().classList.add('active');

The new class is part of a series of other classes it already has. However once this new class is added to the clicked element, it should also give a class .active to other elements in the html which have any matching classes with the clicked element itself.

html:

<button class="1600 1500"></button>
<button class="1600 1300 1200"></button>
<button class="1300 1200 1700 1800"></button>    
<button class="1300 1200 1100 1900"></button>

<div class="1600 1700 item leaflet"></div>

I don't know which button has a matching class since those classes are dynamic too. All I know is that the div will have any class matching any button's class.

The thing is that for specific reasons I am using pure javascript to assign a new class name on click on the div (works):

this.getElement().classList.add('active');

So the following won't work:

this.click(function() {
  var classes = this.attr('class').split(' ')
  classes.forEach(function(elem) {
    $('.' + elem).addClass('active');
  });
});

This how i call the click:

function onEachFeature(feature, layer) {
    layer.on({
        click: panelShow
    });
}

function panelShow(e) {
    // This works, the class is added to the clicked element
    this.getElement().classList.add('active');
}

But I have buttons outside this and needs to have a class active as per the question.

Desired after the div click

<div class="1600 1700 item leaflet active"></div>

<button class="1600 1500 active"></button>
<button class="1600 1300 1200 active"></button>
<button class="1300 1200 1700 1800 active"></button>
<button class="1300 1200 1100 1900"></button>

This is how I deal with the opposite, clicking on the buttons (and works):

var date;
$("button").on("click", function(b) {

    date = $(this).attr("data-date");

    $('path').attr('class', function(index, classNames) {
        return classNames.replace('active', '');
    });

   $("svg ." + date).attr('class', function(index, classNames) {
        return classNames + ' active';
    });

    $(".btn").removeClass("active");
    $(this).addClass("active");
 });

NOTE

In real life on the buttons I am using data attribute but consider it as a class for the example question on here, it's just a paste from a more complex code I have.

Also I am using leafletsJS, that's why the javascript click in the function above.

回答1:

One option is:

var buttons = [].slice.call(document.querySelectorAll('.buttons button'));

function panelShow(e) {
  $("path").removeClass("active");
  var clickedPath = this.getElement();
  clickedPath.classList.add("active");
  var datum = (clickedPath.getAttribute('class').match(/\d+/g) || [])[0];
  buttons.forEach(function(btn) {
    var method = btn.getAttribute('data-date') === datum ? 'add' : 'remove';
    btn.classList[method]('active');
  });
}


回答2:

You should try to get the classList of the clicked element and then iterate to find element with matching classes like

function panelShow(e) {
    var classes = this.getElement().getAttribute('class').split(" "); // Split to return array of all classes of the clicked element so we can loop through
    for(var i = 0; i < classes.length; i++) {
        var singleclass = document.querySelector("." + classes[i]);
        for(var j = 0; j < singleclass.length; j++){
            // Test if the element has the class 'active' before adding if it doesn't
            if(!(' ' + singleclass[j].className + ' ').indexOf(' ' + 'active' + ' ') > -1)
                singleclass[j].className += ' active';
        };
    }
}

EDIT My bad! As pointed out in the comment, I have updated my answer. My syntax was compeletly wrong as I forgot to split my class list and add "." to my querySelector! I am assuming you don't want to use jQuery for some reason. I hope this helps anyone.