Skip to content

Instantly share code, notes, and snippets.

@datchley
Last active August 29, 2015 14:07
Show Gist options
  • Select an option

  • Save datchley/8299b27961fbf44b0684 to your computer and use it in GitHub Desktop.

Select an option

Save datchley/8299b27961fbf44b0684 to your computer and use it in GitHub Desktop.
jQuery extension - $.moveTo() and a `DOMChanged` event implementation
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
.moveable {
border: 1px solid red;
display: inline-block;
padding: 2px;
font-family: sans-serif;
}
#moveto {
border: 1px solid green;
height: 100px;
width: 100%;
}
.controls {
margin-top: 20px;
}
</style>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<meta charset="utf-8">
</head>
<body>
<div class="moveable" id="moveme1">Move Me 1</div>
<div class="moveable" id="moveme2">Move Me 2</div>
<div class="moveable" id="moveme3">Move Me 3</div>
<hr/>
<div id="moveto"></div>
<div class="controls">
<button id="btn-inside">Move Inside</button>
<button id="btn-before">Move Before</button>
<button id="btn-after">Move After</button>
</div>
<script src="moveto.jquery.js"></script>
<script>
var $target = $('#moveto');
// Listen for DOM changes on our target
$target.on('DOMChanged', function(ev, data) {
console.log("[debug] DOMChanged fired: %o", data);
});
// detach and move elements in and around a target
$('#btn-inside').click(function() {
$('#moveme1').moveTo($target, 'inside');
});
$('#btn-before').click(function() {
$('#moveme2').moveTo($target,'before');
});
$('#btn-after').click(function() {
$('#moveme3').moveTo($target,'after');
});
</script>
</body>
</html>
!function (factory) {
if (typeof exports == 'object') {
factory(require('jquery'));
} else if (typeof define == 'function' && define.amd) {
define(['jquery'], factory);
} else {
factory(jQuery);
}
}(function($) {
'use strict';
/**
* isDOM - Check if an object is a DOM Node/Element
* @param obj {mixed} - the object to check
* @return {boolean} - true if obj is a DOM Element
*/
function isDOM(obj) {
try {
return obj instanceof HTMLElement;
} catch(e) {
return (typeof obj === "object") &&
(obj['nodeType'] && obj.nodeType === 1) &&
(obj['style'] && typeof obj.style === "object");
}
}
/**
* after - AOP method to fire a function after an existing
* function already defined in jQuery's $.fn environment.
* @param method {string} - the name of the jQuery method
* @param fn {function} - the function to execute 'after' the jQuery method
* @return {jQuery} - the standard context object of the call
*/
function after(method, fn) {
var _orig = $.fn[method];
if (fn && _orig) {
$.fn[method] = function() {
var args = [].slice.call(arguments),
results;
results = _orig.apply(this, args);
fn.apply(this, args);
return results;
};
}
}
/**
* fireDOMChanged - fires a 'DOMChanged' event on the element
* passing in an event data object denoting the type of method
* called originally that triggered the event.
* @param el {jQuery|selector} - the element to trigger the event on
* @param type {string} - the original method name called that triggered the event
* @return {jQuery} - object the event is fired on
*/
function fireDOMChanged(el, method) {
return $(el).trigger('DOMChanged', { 'method': method });
}
// jQuery manipulation methods to augment
var hooks = [
'append',
'before',
'prepend',
'after',
'html',
'remove',
'empty'
]
// Wrap each original jQuery method to call our fireDOMChanged()
// method after executing, passing the original method name
hooks.forEach(function(hook) {
after(hook, function() {
return fireDOMChanged(this, hook);
});
});
$.fn.extend({
/**
* moveTo - move the element to another element, it's positioning
* determined by the location passed in, either 'before', 'inside'
* or 'after'.
* @param el {jQuery|selector} - the target element to move to
* @param location {string} - one of inside, before or after
* @param [wrap=undefined] {HTML|Element|jQuery} - optionally wrap the moved elements
* @return {jQuery} the original context
*/
moveTo: function(el, location, wrap) {
if (!el && !location) {
throw Error('missing argument to $.moveTo');
}
var mmap = {
'before': 'insertBefore',
'after': 'insertAfter',
'inside': 'appendTo'
},
method = mmap[location],
target = el.jquery ? el : $(el),
source = this.detach();
return (wrap && (wrap.jquery || isDOM(wrap) || typeof wrap === 'string'))
? source[method](target).wrapAll(wrap)
: source[method](target);
}
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment