A flexible, light-weight module for creating custom components
Not every project needs the full arsenal of a front-end framework.
Performance can suffer from loading all of those unused bits of JavaScript.
Development can slow from steep learning curves.
A project that
- has little dynamic content to display OR
- has a back-end templating solution (PHP, JavaServer Pages, ASP.NET, etc.)
may be biting off more front-end framework than it will ever need to chew.
Chances are a front-end framework is being loaded simply to offer means to add custom functionality. This is where FrenchDipJS shines like a freshly baked baguette.
FrenchDip is a component wrapper that ties JavaScript classes defined in your project to instances of assigned DOM elements. This allows you to basically build your own framework.
Displays two different numbers
HTML
Use the "data-frenchdip" attribute to request the JavaScript Class that needs to be invoked for an element.
<p>Displays two different numbers</p>
<div class="your-class-name"
data-frenchdip="YourClass"></div>
<div class="your-class-name"
data-frenchdip="YourClass"></div>
JavaScript
Create a JavaScript Class and register it with FrenchDip, provide the Class itself and then its name as a string.
function YourClass() {
// this.root - node tied to an instance
// this.options - node's data-attr values
this.root.innerHTML = Math.random();
}
FrenchDip.register(YourClass, 'YourClass');
FrenchDipJS collects registered DOM elements, forEach's through them, and invokes a new instance of the requested Class for each one.
If the name property is set on a registered component, the string form isn’t required as a second argument for FrenchDip.register(YourClass). If the name property is not set, FrenchDip requires the name as a string FrenchDip.register(YourClass, 'YourClass').
Manual install from GitHub
Bower install: bower install french-dip --save
Be sure FrenchDip loads before your app's JavaScript, otherwise it can get read in anywhere in your document. Head, body, below the footer, it's all good.
<!-- French Dip -->
<script src="french-dip/french-dip.js"></script>
<!-- App JS -->
<script src="scripts/app.js"></script>
Bruce Wayne
...for 3 seconds anyway
<div class="demo--js"
data-frenchdip="DemoJS"
data-heading="nananana Batman"
data-new-src="batman.png"
data-interval="3000">
<img src="bruce-wayne.png"/>
<p class="heading">Bruce Wayne</p>
</div>
Bruce Wayne
Changes once
<div class="demo--js"
data-frenchdip="DemoJS"
data-heading="Batman Beyond"
data-new-src="batman-beyond.png">
<img src="bruce-wayne.png"/>
<p class="heading">Bruce Wayne</p>
</div>
/** JavaScript Class pattern */
function DemoJS() {
var heading = this.root.querySelectorAll('h4')[0],
img = this.root.querySelectorAll('img')[0],
newHead = this.options.heading,
newSrc = this.options.newSrc,
oldHead, oldSrc;
if (this.options.interval) {
runInterval(this.options.interval);
} else {
runTimeout();
}
function runInterval(interval) {
setInterval(swapAssets, interval);
}
function runTimeout() {
setTimeout(swapAssets, 1000);
}
function swapAssets() {
oldHead = heading.innerHTML;
oldSrc = img.getAttribute('src');
heading.innerHTML = newHead;
img.setAttribute('src', newSrc);
newHead = oldHead;
newSrc = oldSrc;
}
}
/** Register Class with FrenchDipJS */
FrenchDip.register(DemoJS, 'DemoJS');
Bruce Wayne
Changes once
<div class="demo--es62015"
data-frenchdip="DemoES2015"
data-heading="Batman"
data-new-src="batman.png">
<img src="bruce-wayne.png"/>
<p class="heading">Bruce Wayne</p>
</div>
Bruce Wayne
Changes once
<div class="demo--es62015"
data-frenchdip="DemoES2015"
data-heading="Batman"
data-new-src="fireproof.png">
<img src="bruce-wayne.png"/>
<p class="heading">Bruce Wayne</p>
</div>
/** ES2015 Class */
class DemoES2015 {
constructor() {
this.heading = this.root.querySelectorAll('.heading')[0];
this.img = this.root.querySelectorAll('img')[0];
this.options = this.options;
setTimeout(() => {
this.swapAssets();
}, 1000);
}
swapAssets() {
this.heading.innerHTML = this.options.heading;
this.img.setAttribute('src', this.options.newSrc);
}
}
/** Register Class with FrenchDipJS */
FrenchDip.register(DemoES2015, 'DemoES2015');
Bruce Wayne
For a dark knight, click here!
<div class="demo--jquery"
data-frenchdip="DemoJQ"
data-new-src="demo/images/batman.png">
<img src="bruce-wayne.png"/>
<p class="heading">Bruce Wayne</p>
</div>
/** JQuery */
var DemoJQ = DemoJQ;
$.extend(DemoJQ.prototype, {
heading: 'Batman via $.onClick'
});
/** Register Class with FrenchDipJS */
FrenchDip.register(DemoJQ, 'DemoJQ'); // Register DemoJQ Class with FrenchDip
function DemoJQ() {
this.$root = $(this.root);
this.$heading = $(this.$root.find('.heading').get(0));
this.$img = $(this.$root.find('img').get(0));
this.$root.on('click', $.proxy(swapAssets, this));
}
function swapAssets() {
this.$heading.html(this.heading);
this.$img.attr('src', this.options.newSrc);
this.$root.off();
}