Here's a step-by-step conversion from your code to the JS-only code of youmightnotneedjquery.com.
function changeClass() {
document.getElementById("message").className += " dropzone-wrap";
document.getElementById("dragNdrop").className += " dropzone-content";
}
Your method here can only ever be used to add "dropzone-wrap" and "dropzone-content". Consider a different approach, where you provide the DOM Element
and CSS Classes
as parameters.
Consider two such methods - one to add the class (from $.addClass()
), and one to remove it ($.removeClass()
).
// http://youmightnotneedjquery.com/#add_class
function addClass(el, className) {
if (el.classList)
el.classList.add(className);
else
el.className += ' ' + className;
}
// http://youmightnotneedjquery.com/#remove_class
function removeClass(el, className) {
if (el.classList)
el.classList.remove(className);
else
el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
}
Note that I'd remove the class before adding it, as that code does not protect against long repeated classname strings.
Anyway, let's continue with your code:
window.onload = function() {
document.getElementById("ToggleTxTDrop").addEventListener( 'click' , changeClass );
}
Using onload
works, but it isn't the right way to do it. With jQuery this should be $(window).on('load', function() { ... });
... with native Javascript, it isn't much different (.addEventListener
).
For the function code itself, create a handler method that uses the addClass()
abstraction method to replace your old changeClass()
functionality:
function txtDropClicked(evt) {
addClass(document.getElementById('message'), 'dropzone-wrap');
addClass(document.getElementById('dragNdrop'), 'dropzone-content');
}
window.addEventListener('load', function() {
document.getElementById("ToggleTxTDrop").addEventListener( 'click' , txtDropClicked );
});
Now we have your classes being added on click; let's update the onfocus handler in the same fashion:
/* lets remove the previous classes when on focus */
function removeClassesOnFocus(evt) {
// evt.target is the element that triggered the event. We bound to #message.
removeClass(evt.target, 'dropzone-wrap');
removeClass(evt.target.parentNode, 'dropzone-content');
}
// this bit really should wait for `window.load` too.
document.getElementById('message').addEventListener('focus', removeClassesOnFocus);
If the classes are there nothing should happen
To address that, the removeClassesOnFocus
function could be reworked to look up the element if it isn't provided.
function txtDropClicked(evt) {
removeClassesOnFocus(false);
addClass(document.getElementById('message'), 'dropzone-wrap');
addClass(document.getElementById('dragNdrop'), 'dropzone-content');
}
function removeClassesOnFocus(evt) {
// evt.target is the element that triggered the event. We bound to #message.
var message = (evt === false) ? document.getElementById('message') : evt.target;
removeClass(message, 'dropzone-wrap');
removeClass(message.parentNode, 'dropzone-content');
}
The full converted code:
// http://youmightnotneedjquery.com/#add_class
function addClass(el, className) {
if (el.classList) { el.classList.add(className); }
else { el.className += ' ' + className; }
}
// http://youmightnotneedjquery.com/#remove_class
function removeClass(el, className) {
if (el.classList) { el.classList.remove(className); }
else { el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); }
}
// When the txtDrop toggle is clicked, add these classes to the message and drag/drop thing.
function txtDropClicked(evt) {
removeClassesOnFocus(false);
addClass(document.getElementById('message'), 'dropzone-wrap');
addClass(document.getElementById('dragNdrop'), 'dropzone-content');
}
// Removes the classes after the message receives focus.
function removeClassesOnFocus(evt) {
// evt.target is the element that triggered the event. We bound to #message.
var message = (evt === false) ? document.getElementById('message') : evt.target;
removeClass(message, 'dropzone-wrap');
removeClass(message.parentNode, 'dropzone-content');
}
// Attach the click handler to txtDrop toggle when the page loads.
window.addEventListener('load', function() {
document.getElementById("ToggleTxTDrop").addEventListener( 'click' , txtDropClicked );
document.getElementById('message').addEventListener('focus', removeClassesOnFocus);
});
It is worth noting that you can use inline functions as handlers, too - and not define txtDropClicked
or removeClassesOnFocus
. Either way, the point of each method is to perform a single task, and to do that in the most reusable manner possible.