In Scalable and Modular Architecture for CSS (SMACSS), Jonathan Snook teaches that a "state" class such as the one you proposed with .js-link
is the best approach.
The relevant discussion is in the section on State Rules:
Sub-module styles are applied to an element at render time and then are never changed again. State styles, however, are applied to elements to indicate a change in state while the page is still running on the client machine.
For example, clicking on a tab will activate that tab. Therefore, an is-active or is-tab-active class is appropriate. Clicking on a dialog close button will hide the dialog. Therefore, an is-hidden class is appropriate.
This contradicts what two commenters said. CSS code and classes should be flexible; CSS developers should be able to refactor and improve code without worrying about breaking functionality not related to presentation.
The point made by @ArunPJohny supports the state class approach. Engines are unfortunately not optimized to recognize data-
attributes any more than they are to recognize arbitrary custom attributes, such as foo-
.