0

Currently on my portfolio I have separate functions to open seperate lightboxes.

$(".project.clientA").click(function(){     
    $(".lightbox.clientA").addClass("open", 500);
});

$(".project.clientB").click(function(){     
    $(".lightbox.clientB").addClass("open", 500);
});

$(".project.clientC").click(function(){     
    $(".lightbox.clientC").addClass("open", 500);
});

Because I have a function like this for each project, when you have a lot of projects, this makes the code get pretty long. I'm wondering if there is a way to templatize this into one function that works for all clients (clientA, clientB, clientC, etc) by saying something like this.

$(".project.whateverclient").click(function(){      
    $(".lightbox.sameclient").addClass("open", 500);
});

Hope this makes sense.

user2749195
  • 43
  • 2
  • 5

3 Answers3

0

Splitting the class may help.
For "project clientA", make it "project client nameOfA".
Then you can use the selector $(".project.client")

But if you cannot do this, a jQuery wildcard way, which is worse in performance, will be:

$('.project[class*=client]')

For the second task, you have to know the actual client name from inside the function body, this should help:

Array.from(this.classList).filter(x => x.startsWith('client'))
COY
  • 684
  • 3
  • 10
0

Give them a common className and define click listener only for that class like this

$('.button').click(event => {
  $(event.target).addClass('open');

  // for testing
  let dataBtn = $(event.target).attr('data-btn');
  console.log(`You click ${dataBtn} and class 'open' add to it.`);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="button" data-btn="firstBtn">submit</button>
<button class="button" data-btn="secondBtn">submit2</button>
<button class="button" data-btn="thirdBtn">submit3</button>
<button class="button" data-btn="fourthBtn">submit4</button>
Robin
  • 4,902
  • 2
  • 27
  • 43
0

Take a look at the below snippet. This solution assumes that you cannot or will not change your class name or mark-up structure; otherwise, one of the other posted solutions is probably better.

$(".trigger[class^='project'], .trigger[class*=' project']").click(function(e){
    const target = e.target;
    const classlist = target.classList;
    const project = [...classlist].find(className => className.startsWith('project'));
    $(`.target.${project}`).addClass("open", 500);
});
.trigger {
  display: inline-block;
  background-color: red;
  margin-right: 10px;
  height: 30px;
  width: 30px;
}

.target {
  display: inline-block;
  background-color: pink;
  margin-right: 10px;
  height: 30px;
  width: 30px;
}

.target.open {
  background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <div class="projectA trigger"></div>
  <div class="trigger projectB"></div>
  <div class="trigger projectC"></div>
</div>

<div>
  <div class="target projectA"></div>
  <div class="target projectB"></div>
  <div class="target projectC"></div>
</div>

Let's unpack the JS:

// Trick to find divs with the class 'trigger' and a class starting with 'project'
// https://stackoverflow.com/questions/2178416/using-starts-with-selector-on-individual-class-names
$(".trigger[class^='project'], .trigger[class*=' project']").click(function(e){
    // get the clicked DOM element
    const target = e.target;
    // get all the classes for the clicked element
    const classlist = target.classList;
    // find the class that denotes the specific project by finding the class that
    // starts with 'project'
    const project = [...classlist].find(className => className.startsWith('project'));
    // find the element that has class 'target' and the matched 'project' class and add
    // the class 'open'
    $(`.target.${project}`).addClass("open", 500);
});
Alexander Nied
  • 12,804
  • 4
  • 25
  • 45
  • Thanks Alex, this is solid. But maybe I should've clarified the client naming was anonymized and structured alphabetically for the purpose of this post. They actually will be the naming of the actual companies. Here is the more accurate syntax of the classnames: Triggers: .project.apple .project.facebook .project.google Targets: .lightbox.apple .lightbox.facebook .lightbox.google How would I adjust your code accordingly? – user2749195 Mar 08 '20 at 04:45