Skip to main content
2 of 2
added 856 characters in body

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.