DEV Community

Discussion on: Use components without a frontend framework

Collapse
 
souksyp profile image
Souk Syp. • Edited

I read 3 times and unless I’m blind, I don’t see where you applied BEM in javascript.

Also the $ sign here has nothing to do with jQuery I guess.. just a naming convention to point out that it holds an element.

Collapse
 
malteriechmann profile image
Malte Riechmann

Regarding the $ sign. Yes, I use it to point out which variables hold DOM elements.

Collapse
 
malteriechmann profile image
Malte Riechmann • Edited

Thanks for your comment. It made me smile. You are not blind. You are right. I did not go into details with applying BEM to JavaScript, although I said so: »I am going to show you how to use it for JavaScript, too«.

The JavaScript part in my post does show how to create an isolated environment for each instance of a block. To go further, maybe a small teaser for a gallery block can help.

(function () {

  var initializeGallery = function($gallery) {
    var $galleryNextButton = $gallery.querySelector('.gallery__next-button'),
      $galleryPreviousButton = $gallery.querySelector('.gallery__previous-button'),
      $galleryItems = $gallery.querySelector('.gallery__items');

    $galleryNextButton.addEventListener('click', function() {
      // …
    });

    $galleryPreviousButton.addEventListener('click', function() {
      // …
    });
  };

  document.addEventListener('DOMContentLoaded', function() {
    var $galleries = document.querySelectorAll('.gallery');

    for (var i = $galleries.length - 1; i >= 0; i--) {
      initializeGallery($galleries[i]);
    }
  });

}());
Enter fullscreen mode Exit fullscreen mode
Collapse
 
souksyp profile image
Souk Syp.

Thanks for this example (extended) and kudos to this loop counting backward 😆

for (var i = $cards.length - 1; i >= 0; i--){...}

Collapse
 
peerreynders profile image
peerreynders • Edited

Another practice that may be worth considering is using JavaScript Hooks (though it isn't universally accepted; see also Decoupling Your HTML, CSS, and JavaScript).

<section class="gallery js-gallery">
  <!-- other block elements -->
  <div>
    <button class="gallery__previous-button" name="previous-button">Previous</button>
    <button class="gallery__next-button" name="next-button">Next</button>
  </div>
  <div class="gallery__items">
    <!-- more -->
  </div>
</section>
Enter fullscreen mode Exit fullscreen mode

so

document.addEventListener('DOMContentLoaded', function() {
  var $galleries = document.querySelectorAll('.js-gallery');
  for (var i = $galleries.length - 1; i >= 0; i--) {
    initializeGallery($galleries[i]);
  }
});
Enter fullscreen mode Exit fullscreen mode

Now superficially this may come across as redundant but as stated by Harry Roberts:

I have known occasions before when trying to refactor some CSS has unwittingly removed JS functionality because the two were tied to each other—it was impossible to have one without the other.

It could also be seen as helpful that the js-* classes within the HTML clearly identify those blocks (or elements) that have behavioural enhancements (i.e. are "JavaScript components").

It isn't always necessary to use class-based JavaScript hooks on elements inside a block. Given that a block/component instance is already scoped on a particular fragment of the DOM it is possible to more easily select on non-class features or the fragment's internal structure to bind element behaviour.

var $galleryNextButton = $gallery.querySelector('button[name="next-button"]'),
    $galleryPreviousButton = $gallery.querySelector('button[name="previous-button"]'),
    $galleryItems = $gallery.lastElementChild;
Enter fullscreen mode Exit fullscreen mode

See also:

Thread Thread
 
malteriechmann profile image
Malte Riechmann

Thanks for the insights. I once tried the js- prefix, but did not like it that much. I like to use same classes for JavaScript and CSS.

And also thanks for showing me how to use syntax highlighting at DEV. I will update my post as soon as possible.