Here's the DYNTAR code itself, fully commented. Please, use the forums for any comments, questions or suggestions you may have. I'm particulary concerned about any wrong assumption I may have made about cross-browser issues. Thanks
/**
* A single object is enough. It should minimize the possibility to
* conflict with any other javascript snippet running on the same
* page.
*/
var DYNTAR = {
/**
* Used to keep the current state during drag operations.
*/
is: false,
/**
* Minimum height for textareas.
*/
min: 50,
/**
* Initialization.
*/
init: function() {
/**
* Only if the browser supports all objects/methods that we need later...
* see: http://www.quirksmode.org/js/support.html
*/
with(document) if (getElementsByTagName && createElement && insertBefore && appendChild) {
/**
* AFAIK, the traditional model works on all browsers
* see: http://www.quirksmode.org/js/events_tradmod.html
*/
// Save the previous onload handler.
this.oldload = window.onload;
// Now, install our onload handler.
window.onload = this.onload;
}
},
/**
* Window onload handler
*/
onload: function() {
// Invoke any previously installed onload handler.
if (DYNTAR.oldload) {DYNTAR.oldload();DYNTAR.oldload=null;}
// Obtain the list of textareas present on the page.
var x = document.getElementsByTagName('textarea');
// Attempt to attach the DYNTAR behaviour to all textareas.
for (var i=0;i<x.length;i++) {DYNTAR.attach(x[i]);}
},
/**
* This is where the DOM magic happens. :-)
*/
attach: function(ta) {
// Quit if the textarea has the noresize attribute.
if (!ta.getAttribute || ta.getAttribute('noresize')) return;
// Get a pointer to the current container of the textarea.
var parent = ta.parentNode;
// Dynamically create a new wrapper for this textarea.
var wp = document.createElement('div');
// Dynamically create a new resize bar for this textarea.
var rz = document.createElement('div');
// Quit if previous DOM operations failed.
if (!parent||!wp||!rz) return;
// Make the width of the wrapper equal to the width of the textarea.
wp.style.width = ta.offsetWidth + 'px';
// Attach the CSS class to the resize bar.
rz.className = 'dyntar-resizer';
// Compute the size of the resize bar.
rz.style.width = (ta.offsetWidth-2) + 'px';
// Allow us to get into related elements later.
rz._wp = wp;
rz._ta = ta;
// Insert the wrapper into the DOM tree, just before the textarea.
parent.insertBefore(wp,ta);
// Relocate the textarea, so it now becomes a child of the wrapper.
wp.appendChild(ta);
// Insert the resize bar into the DOM tree, just after the textarea.
wp.appendChild(rz);
// Install the event that should help us initialize the drag operation.
rz.onmousedown = function(e) {DYNTAR.onmousedown(e,this);}
},
/**
* Start drag operation.
*/
onmousedown: function(e,rz) {
// This is important to prevent from starting the drag operation
// more than once.
// The mouse could be released outside the browser window!
if (this.is||!rz._wp) return;
// Cross-browser access to the event.
if (!e) e = window.event;
// Save current state.
this.is = {
rz:rz, // Pointer to the current resize bar.
wp:rz._wp, // Pointer to the current wrapper.
ta:rz._ta, // Pointer to the current textarea.
h:rz._ta.offsetHeight, // Current height of the textarea.
y:e.clientY // Current mouse position.
};
// Change the look of the textarea and show the wrapper.
with(this.is) {
ta.className += ' dyntar-active';
wp.className = 'dyntar-wrapper';
}
// Save previous onmouse event handlers.
this.oldmousemove = document.onmousemove;
this.oldmouseup = document.onmouseup;
// Install our own onmouse event handlers.
document.onmousemove = function(e){DYNTAR.onmousemove(e);}
document.onmouseup = function(e){DYNTAR.onmouseup(e);}
},
/**
* Finish drag operation.
*/
onmouseup: function(e) {
// Quit if our flag is not set, or false (safety)
if (!this.is) return;
// Restore the state of the textarea and hide the wrapper.
with(this.is) {
ta.className = ta.className.replace(/ *dyntar-active/, '');
wp.className = '';
}
this.is = false;
// Restore previous onmouse event handlers.
document.onmousemove = this.oldmousemove;
document.onmouseup = this.oldmouseup;
},
/**
* Compute the new size of the textarea.
*/
onmousemove: function(e) {
// Quit if our flag is not set, or false (safety)
if (!this.is) return;
// Cross-browser access to the event.
if (!e) e = window.event;
// Compute the new size of the textarea.
this.is.ta.style.height = Math.max(this.min,this.is.h+e.clientY-this.is.y) + 'px';
// Cancel the event.
this.cancel_event(e);
return false;
},
/**
* Cover all (known) methods to cancel an event.
*/
cancel_event: function(e) {
if (e.preventDefault) e.preventDefault();
if (e.stopPropagation) e.stopPropagation();
e.cancelBubble = true;
e.returnValue = false;
}
};
DYNTAR.init();









Recent comments
1 year 33 weeks ago
1 year 36 weeks ago
1 year 36 weeks ago
1 year 37 weeks ago
1 year 38 weeks ago
1 year 38 weeks ago
1 year 41 weeks ago
1 year 41 weeks ago
1 year 43 weeks ago
1 year 44 weeks ago