Skip to content

Instantly share code, notes, and snippets.

@jhartman86
Last active August 29, 2015 14:27
Show Gist options
  • Save jhartman86/1aee90a4635638ae8154 to your computer and use it in GitHub Desktop.
Save jhartman86/1aee90a4635638ae8154 to your computer and use it in GitHub Desktop.
Solutions for js skill set evaluation
/**
* Consider this function the place where you go through and customize things
* after an external script has created some defaults, but you need to customize
* things. Everything has to occur w/in this function. If there are things you
* would change entirely to make it more understandable, do so. Also, assume you
* can use the latest ECMA script standards (no shitty IE8 support, or 9 for
* that matter).
*/
runtime.initialize(function( $, markupData ){
/**
* Disable animation on the accordion (it slides up and down by default; it
* should immediately snap open). Easiest route being to select the DOM element
* and use jQueryUI's API to just disable it. Put a comment for future people
* who maintain this code as to why it might be confusing.
*/
// --- code here ---
/** SOLUTION ***************************************************************
* Its confusing b/c there are two jQuery's included; but only one (and not
* the one passed as the $ var into this function) has the jQuery UI accordion
* bound to its .data() method, where we can properly access and turn off the
* animate setting via jQueryUI's API.
**************************************************************************/
jQuery('aside').accordion("option","animate", false);
/**
* Callback hell; we run into this all_the_time. Try giving this a refactor;
* with the goal being to a) remove nesting of callbacks, and b) that when
* you console log _value, it should have {valIs:12}. Key thing is that it
* has to return a _consistent_ result; as you never know the timing in which
* method1,2,3 will execute unless they're nested like this.
*/
var input = 4;
this.method1(input, function( _input ){
this.method2(_input, function( _input2 ){
this.method3(_input2, function( _input3 ){
console.log(_input3);
});
});
});
/** SOLUTION ***************************************************************
* All the methods that need to run in order accept args: func(val, callback);
* this lets us use a fairly simple function to build a kind of promise
* factory that we can *chain*. It might not be the most readable/elegant
* function, but it does make the end result very readable, and it scales
* so we can add as many more things in order as we want vs ever-deeper
* nested callbacks. NOTE: this is *definitely* not the only way to do
* this. Important thing is we want to see if candidate can find a way to
* flatten out nested callbacks.
**************************************************************************/
function inOrder(callable){
return function(_value){
var df = $.Deferred();
callable(_value, function( newVal ){
df.resolve(newVal);
});
return df.promise();
};
}
var input = 4;
inOrder(this.method1)(input).
then(inOrder(this.method2)).
then(inOrder(this.method3)).
done(function(result){
console.log('result: ', result);
});
/**
* The variable `markupData` contains a large array of objects (9999 to be
* specific) like so:
* [{classes: 'alpha beta gamma', content: 'lorem ipsum ...'}, ..., ...]
* -------------------------------------------------------------------------
* Task is to loop through all the objects in the array and generate DOM
* markup inside the <main> element, *after* the <h4></h4> tag, like:
* <div class="alpha beta gamma" data-index="{index}">
* <span>lorem ipsum</span>
* </div>
* WITHOUT using jQuery. {index} is the 0-based index of the item you're
* looping through.
* -------------------------------------------------------------------------
* IMPORTANT: performance matters. Beyond just not using jQuery, the real
* criteria for this is doing it in the fastest/most-performant way possible.
* Obviously 9999 is a somewhat arbitrarily large number; the key is
* generating code that runs FAST in the browser. So - write the solution
* wrapped inside the trackTime method, which will use chrome devtools'
* console.time() method to do a rough benchmark of its performance (you'll
* see the time logged to the console). I believe Firefox supports
* console.time() as well, but not sure, so best bet is to use Chrome for
* working on this.
*/
this.trackTime(function(){
// --- code here ---
});
/** SOLUTION ***************************************************************
* Criteria we're looking at:
* 1) Since we specified performance-critical, is documentFragment being
* used to minimize the number of repaints the browser has to do?
* 2) For generating the <span> tag - is it being done w/ innerHTML and then
* parsing a string that contains the <span> tags inside (which is slower),
* or is the node being generated with createElement (which is faster).
* NOTE: this is kind of subjective, as using innerHTML increases readability
* and really shouldn't be considered bad practice (we do it all the time),
* but for manipulating a few thousand nodes, its significantly slower.
* 3) If they're NOT using documentFragment, are they appending the nodes to
* <main> tag on every iteration of the loop (major no-no), or is there
* some other clever way of getting around that?
**************************************************************************/
this.trackTime(function(){
var frag = document.createDocumentFragment();
for( var key in markupData ){
var div = document.createElement('div'),
span = document.createElement('span');
div.className = markupData[key].classes;
div.setAttribute('data-index', key);
span.innerText = markupData[key].content;
div.appendChild(span);
frag.appendChild(div);
}
document.querySelector('main').appendChild(frag);
});
/**
* Lastly, again w/out jQuery, bind click listeners that fire *once*
* and console.log() the value stored in the data-index attribute whenever one
* of the <div>s just created gets clicked, _but_ do not use an external
* variable to track the state of whether something has already been
* clicked or not. i.e.: no doing:
* var isClicked = false;
* ... <code> ...
* if(clicked === false){
* <code>;
* isClicked = true;
* }
*/
// --- code here ---
/** SOLUTION ***************************************************************
* We're looking for code that uses removeEventListener to
* unbind after one click.
**************************************************************************/
var nodeList = document.querySelectorAll('main > div'),
nodeArray = Array.prototype.slice.call(nodeList),
onClick = function(){
console.log(this.getAttribute('data-index'));
this.removeEventListener('click', onClick);
};
for(var i = 0, l = nodeArray.length; i < l; i++){
nodeArray[i].addEventListener('click', onClick);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment