Similar to my Prototype Function Collection thread: Here are 2 prototype-functions I created.
This thread is the place to share your cross-browser and reusable functions. If your function is a prototype-function, post it in the above link instead. If you don't even know what a prototype-function is, chances are your function isn't one and it should be posted here.
Because a layer can be inside another layer, a layer's style.left and style.top can both be 0px but the layer can be 500 pixels away from the margin.
These functions return the true offset:
Code:
function getPositionLeft(This){
var el = This;var pL = 0;
while(el){pL+=el.offsetLeft;el=el.offsetParent;}
return pL
}
Code:
function getPositionTop(This){
var el = This;var pT = 0;
while(el){pT+=el.offsetTop;el=el.offsetParent;}
return pT
}
In JavaScript, if you try to compare two Arrays it will always return false, even this simple comparison: ([3]==[3]). So to see if two arrays are actually identical you can use this function, I could have made it accept more than two arrays but thought it was nice and simple as it was. It can take multi-dimensional arrays.
Code:
function compareArrays(a, b){
if (a.constructor!=Array || b.constructor!=Array || a.length!=b.length) return false;
var L=a.length,i;
while (i<L) {
if (a[i]==b[i] || compareArrays(a[i],b[i])) i++;
else return false;
}
return true;
}
Send it an argument as a URL string or it will presume the windows location.
Builds an object of the query string:
Code:
function queryObject(){
var s=arguments[0] || window.location.href, m=s.indexOf('?')+1, i=0, t;
this.toString=function(){return s}
if (m) {
m=s.substring(m,s.length).split("&");
while (i<m.length)
this[m[i].substring(0,t=m[i].indexOf("="))]=m[i].substring(t+1,m[i++].length);
}
}
Example:
Code:
var query=new queryObject("http://www.google.com.au/search?hl=en&q=lemurs&btnG=Search&meta=");
for (var i in query) alert(i+" = "+query[i]);
addFunctionToOnload is used to add function calls to the onload event.
The defining code is in royalblue:
Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html dir="ltr" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<title></title>
<script type="text/javascript"><!--
var onloadString=""
function addFunctionToOnload(){onloadString+=arguments[0]+"();"}
onload=function(){Function("",onloadString)()}
//--></script>
<script type="text/JavaScript"><!--
function blah1(){
var e=document.getElementById("el1");
if(!e)alert("el1 cound\'t be found, please wait until the onload event")
else alert(e.value)
}
function blah2(){
var e=document.getElementById("el2");
if(!e)alert("el2 cound\'t be found, please wait until the onload event")
else alert(e.value)
}
addFunctionToOnload("blah1")
addFunctionToOnload("blah2")
blah1()
blah2()
//--></script>
</head>
<body>
<p>
<input type="text" value="valueof el1" id="el1">
<input type="text" value="valueof el2" id="el2">
</body>
</html>
note: In the case of multiple external JS files that all will need to append to the onload event and you don't want to define the addFunctionToOnload function twice, use this code in each JS extneral file to define the function:
Code:
if(typeof onloadString=="undefined"){
var onloadString="";
addFunctionToOnload=function(){onloadString+=arguments[0]+"();"}
onload=function(){Function("",onloadString)()}
}
It checks to see if it is already defined, then if it is undefined, then defines it. Then simply proceed in your JS file with the addFunctionToOnload defined as usual. Do make sure to put the defining code at the very top of your JS file so no futher code in it will require it's usage prior to it's defination.
I don't normally revive threads like this, but this time I figured, why not? I've found myself using this a couple of times already - it's a function to get the contents of an XML element and convert it to text. Like innerHTML, only using the DOM and without the entities. Found myself needing this for AJAX type applications, when it's neccessary to send back the contents of an element (all of them) to the server without always knowing just what would be there.
It takes as an argument the node you want Text-isized
Code:
function getXML(aNode)
{
var out = '';
if(aNode.nodeType == Node.ELEMENT_NODE)
{
out = '<'+aNode.nodeName;
if(aNode.hasAttributes())
{
var atts = aNode.attributes;
for(var x=0;x<atts.length;x++)
{
out +=' '+atts[x].nodeName+'="'+atts[x].nodeValue+'"';
}
}
if(aNode.hasChildNodes())
{
out += '>';
var kids = aNode.childNodes;
for(var x=0;x<kids.length;x++)
{
switch(kids[x].nodeType)
{
case Node.ELEMENT_NODE:
out += getXML(kids[x]);
break;
case Node.TEXT_NODE:
out += kids[x].nodeValue;
break;
case Node.COMMENT_NODE:
out += '<!--'+kids[x].nodeValue+'-->';
break;
case Node.CDATA_SECTION_NODE:
out += '<'+'![CDATA['+kids[x].nodeValue+']'+']>';
break;
}
}
out += '</'+aNode.nodeName+'>';
} else {
out += '/>';
}
}
return out;
}
It's been a while since I've done much Javascript (well, until lately at least) but it's been working out fine for me.
Someone wanted to change the order of dynamically assigned event handlers and as seen as there is no guarantee of which fires first I set about writing a program that would handle it, however I got no response so I thought I'd see if anybody else has a use for it.
It's still a little off of a finished product but I can see it has its' uses. There is no support for arguments in the functions that are called as of yet and no support for capturing and bubbling but what the hell:
Check the bottom of the program for usage... I might add support for event capturing and bubbling if anybody is interested.
Code:
<div id="text">
Some text
<br />
Goes here
</div>
<script>
var cache = document.getElementById;
var isIE = 0;
if(navigator.appName == "Microsoft Internet Explorer"){
isIE=1;
}
document.getElementById = function(id){ // Override the document.getElementById function to add the addEventListener function
this.getId = cache; // Copy the native document.getElementById into this objects getId variable
this.domObject = this.getId(id); // Assign this.domObject to the object that you are getting by id
this.domObject.addListenerObject = function(){ // Add the addListenerObject method to the document.getElementById method
return new listenerObject(id);
}
return this.domObject;
}
function listenerObject(id){
this.id = id;
this.listeners = new Array(); // Array of event listeners
this.eventHandler = myEventHandler;
this.add = addListener; // Method to add an event listener
this.remove = removeListener; // Method to remove an event listener
this.push = pushListener; // Method to increase the listeners precedence
this.shift = shiftListener; // Method to decrease listeners precedence
this.move = moveListener; // Method to move a listener to a specific index
this.swap = switchListeners; // Method to switch the position of two listeners
this.list = list; // Method to retrieve the event handlers i array format
this.eventHandler = myEventHandler // Event Handling method
return this;
}
function addListener(type, func, bool, index){ // Method for adding event listeners
with(this);
if(isIE){
type = "on" + type; // Append on to the event type, IE handles events differently to mozilla
}
if(!this.listeners[type]){ // If there hasn't been an array defined for the event type
this.listeners[type] = new Array(); // Create one
if(!index){ // If the index argument has been ommited
index = this.listeners[type].length; // add the listener object to the end
}
this.listeners[type][index] = func; // Add an event listener to the events list
var thisEventListener = this; // Reference this so the anonymous function can access it
var eventHandler = function(ev){ // Capture the events
thisEventListener.eventHandler(ev.type.toString(), thisEventListener.listeners); // Pass events to the event handler
}
if(isIE){
document.getElementById(this.id).attachEvent(type, eventHandler); // Add the event listener to the element
}else{
document.getElementById(this.id).addEventListener(type, eventHandler, bool); // Add the event listener to the element
}
}else{
if(!index){ // If the index argument has been ommited
index = this.listeners[type].length; // add the listener object to the end
}
this.listeners[type][index] = func; // Add an event listener to the events list
}
return this;
}
function removeListener(ev, func){ // Method for removing an event listener
with(this);
if(isIE){
ev = "on" + ev;
}
var tempArray = new Array(); // Create a temporary array to store the listeners
for(var i=0; i<this.listeners[ev].length; i++){ // Iterate through the listeners
if(this.listeners[ev][i] != func){
tempArray[tempArray.length] = this.listeners[ev][i]; // Store the data from the listener array in a temporary array (I had to do it this way as I was getting unexpected results with splice)
}
}
this.listeners[ev] = tempArray; // Update the listeners array
return this;
}
function pushListener(ev, func){ // Function still in progress
with(this);
if(isIE){
ev = "on" + ev;
}
var index;
var tempValue;
if(this.listeners[ev][0] != func){ // Make sure we aren't trying to push the listener off of the end of the array
for(var i=this.listeners[ev].length-1; i>0; i--){ // Iterate through the array
if(this.listeners[ev][i] == func){ // If we have found the function
index = i; // Make a note of it's index
}
}
tempValue = this.listeners[ev][index-1]; // Store the listener to be shifted
this.listeners[ev][index-1] = this.listeners[ev][index]; // Switch
this.listeners[ev][index] = tempValue; // the values at the index
return this;
}
}
function shiftListener(ev, func){ // Function to decrease the listeners index
with(this);
if(isIE){
ev = "on" + ev;
}
var tempArray = new Array(); // Define a temporary array to store the new listeners array
if(this.listeners[ev][this.listeners[ev].length-1] != func){ // Make sure we aren't trying to shift the listener off of the end of the array
for(var i=0; i<this.listeners[ev].length; i++){ // Iterate through the array
if(this.listeners[ev][i] == func){ // If we have found the function
tempArray[i] = this.listeners[ev][i+1]; // Switch
tempArray[i+1] = this.listeners[ev][i]; // the listeners
i++;
}else{
tempArray[i] = this.listeners[ev][i];
}
}
this.listeners[ev] = tempArray; // Overwrite the listeners array
return this;
}
}
function moveListener(ev, func, index){ // Method to move a listener to a specific location
with(this);
if(isIE){
ev = "on" + ev;
}
if(index > -1 && index < this.listeners[ev].length){ // Don't allow listeners to be moved from the extremeties of the array
var functionIndex;
var found = false;
var tempArray = new Array();
for(var i=0; i<this.listeners[ev].length; i++){ // Iterate through the array
if(!found){ // If we have not yet found the listener index in the listeners array
if(this.listeners[ev][i] == func){ // Check to see if we are at the index of the listener
found = true; // Set the flag telling the loop that we have found the funtion's index
// Notice how we ignore the listener, it does not get copied
}else{
tempArray[i] = this.listeners[ev][i]; // Copy the function into the temporary array
}
}else{
tempArray[i-1] = this.listeners[ev][i]; // Shift the rest of the listeners up in the array
}
}
var finalArray = new Array(); // Define an array to store our final listeners list
var isIndex = false; // Flag that determines if we are at the desired index
for(var k=0; k<this.listeners[ev].length-1; k++){ // Iterate through the array
if(!isIndex){ // If we have not yet passed the listener index
if(k == index){ // Check to see if we are at the index of the listener
isIndex = true; // Set the flag telling the loop that we have passed the index
finalArray[k] = func; // Add the function to the array at the index point
finalArray[k+1] = tempArray[k]; // Shift the next listener up
}else{
finalArray[k] = tempArray[k]; // Copy the listener into the new array
}
}else{
finalArray[k+1] = tempArray[k]; // Shift the rest of the listeners up
}
}
this.listeners[ev] = finalArray; // Overwrite the listeners array
return this;
}
}
function myEventHandler(ev, listeners){
if(isIE){
ev = "on" + ev;
}
for(var i=0; i<listeners[ev].length; i++){
eval(listeners[ev][i] + "()");
}
}
function switchListeners(ev, func1, func2){
with(this);
if(isIE){
ev = "on" + ev;
}
var index1;
var index2;
for(var i=0; i<this.listeners[ev].length; i++){
if(this.listeners[ev][i] == func1){
index1 = i;
}
if(this.listeners[ev][i] == func2){
index2 = i;
}
}
this.listeners[ev][index2] = func1;
this.listeners[ev][index1] = func2;
return this;
}
function list(type){
with(this);
if(isIE){
type = "on" + type; // Append on to the event type, IE handles events differently to mozilla
}
return this.listeners[type]; // return the listeners array
}
function click1(){
alert("I'm click 1");
}
function click2(){
alert("I'm click 2");
}
function click3(){
alert("I'm click 3");
}
function click4(){
alert("I'm click 4");
}
function click5(){
alert("I'm click 5");
}
var myListener = document.getElementById("text").addListenerObject();
myListener.add("click","click1",true);
myListener.add("click","click2", true);
myListener.add("click","click3", true);
myListener.add("click","click4", true);
myListener.add("click","click5", true);
alert(myListener.list("click"));
myListener.swap("click","click2","click5");
alert(myListener.list("click"));
myListener.remove("click","click1");
alert(myListener.list("click"));
myListener.push("click","click4");
alert(myListener.list("click"));
myListener.shift("click","click3");
alert(myListener.list("click"));
myListener.move("click","click2", 1);
alert(myListener.list("click"));
</script>
function mul() {
// multiplies two numbers given in string form (in base ten)
// decimals OK, negative numbers and scientific notation not OK
// returns answer as a string
if (arguments.length!=2) return false;
var figsi=new Array(); var figsw=new Array();
var fdp=false; var places=0; var point='.';
// if your country writes decimals with a comma
// then uncomment the following line:
// point=',';
var wa=0; var ts=''; var posn=0; var tc='';
for (wa=0; wa<2; wa++) {
fdp=false; ts=arguments[wa]; figsi[wa]=new Array();
if (typeof(ts)!='string') return false;
if (ts=='' || ts==point) return false;
for (posn=0; posn<ts.length; posn++) {
tc=ts.charAt(posn);
if (tc>='0' && tc<='9') {
figsi[wa][figsi[wa].length]=tc-0; if (fdp) places++; }
else if (tc==point && fdp==false) fdp=true;
else return false; }
figsw[wa]=figsi[wa].reverse();}
var i=0; var j=0; var ansa=new Array();
for (i=0; i<=figsw[0].length+figsw[1].length; i++) ansa[i]=0;
for (i=0; i<figsw[0].length; i++)
for (j=0; j<figsw[1].length; j++)
ansa[i+j]+=(figsw[0][i]*figsw[1][j]);
// now meld
for (i=0; i<ansa.length-1; i++) {
ansa[i+1]+=Math.round((ansa[i]-(ansa[i]%10))/10); ansa[i]%=10; }
ansa[places]+=point;
var ans=ansa.reverse().join('');
// clean up
while (ans.charAt(0)=='0' && ans.length>1 && ans.charAt(1)!='.')
ans=ans.substring(1,ans.length);
fdp=false;
while (fdp==false && (ans.charAt(ans.length-1)=='0' ||
ans.charAt(ans.length-1)==point)) {
if (ans.charAt(ans.length-1)==point) fdp=true;
ans=ans.substring(0,ans.length-1); }
return ans; }
function easter(year) {
// function to calculate the date of Easter Sunday
// as given by the Gregorian calendar reform of 1582
// Note: this function returns a Date object
// with its time set to NOON local time
// function by Juuitchan
if (typeof(year)!='number') return false;
if (year%1!=0) return false;
if (year<1582) return false;
var ccpass=Math.floor(year/100)-15;
// Century changes since the calendar reform
var gsnum=year%19;
// Used in a table lookup
// Calculate the seed for the table
var seed=22; // it was initialized to this in 1582
seed+=(ccpass-Math.ceil(ccpass/4)); // Solar Equation
seed-=(8*Math.floor(ccpass/25)+Math.floor((ccpass%25)/3));
// the line above is the Lunar Equation
seed%=30; // seed is restricted to range 0-29
var moontable=new Array();
var wheel=seed; var finger=0; var p29=-1; var p28=-1;
for (finger=0; finger<19; finger++) {
moontable[finger]=wheel;
if (wheel==29) p29=finger; // gets special treatment
if (wheel==28) p28=finger; // might get special treatment
wheel-=11; if (wheel<0) wheel+=30; }
if (p29>=0 && p28>=0) moontable[p28]=27;
if (p29>=0) moontable[p29]=28;
var pfmoffset=moontable[gsnum];
// Paschal Full Moon is this many days past March 21
var work=new Date(year,3-1,21+pfmoffset,12,0,0);
// work is set to date of Paschal Full Moon
// (time is set to noon to avoid a problem
// with JS Date objects near midnight)
work.setDate(work.getDate()+(7-work.getDay()));
// this sets the date to the following Sunday
return work;
// More comments:
// Ash Wednesday = Easter Sunday - 46 days
// (Sundays are not counted in the 40 days of Lent)
// Palm Sunday = Easter Sunday - 7 days
// Good Friday = Easter Sunday - 2 days
// Pentecost = Easter Sunday + 49 days
}
Ever want to add a StyleSheet to your document using the full CSS without having to use a load of addRules and insertRules?
Although this is non-standard it is a pretty niffy approach that I'm sure can be expanded upon.
The addNewStyleSheetByFullCSS function accepts one argument, the full CSS to be used within the styleSheet, and the new StyleSheet is appended to the DOM Tree automatically.
I was looking to post this function over at JavaScript Source and was wondering why you didn't just add the two scripts together? Are you just trying to show the actual function separate?
Correct, just keeping the function separate and the example usage in another SCRIPT tag. -- Just my way of organizing. Feel free to concentrate the two as you fancy.
Bookmarks