Skip to content

Instantly share code, notes, and snippets.

@Joopmicroop
Last active November 13, 2019 10:36
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save Joopmicroop/10471650 to your computer and use it in GitHub Desktop.
Save Joopmicroop/10471650 to your computer and use it in GitHub Desktop.
dom helper functions
function ParseUrl(url){
this.href = this.protocol = this.hostname = this.port = this.pathname = this.search = this.hash = '';
this.query = {};
return this._makeUrlObj(url);
}
ParseUrl.prototype._makeUrlObj = function(url){
var a = document.createElement('a');
a.href = url;
var qs = {};
a.search.replace(new RegExp("([^?=&]+)(=([^&]*))?", "g"), function($0, $1, $2, $3) { qs[$1] = $3; });
this.href = a.href;
this.protocol = a.protocol+'//';
this.hostname = a.hostname;
this.port = a.port;
this.pathname = a.pathname;
this.search = a.search;
this.query = qs;
this.hash = a.hash;
a.href = '';
a = null;
return this;
}
ParseUrl.prototype.set = function(key, val){
switch(key){
case 'href': this.href = val; break;
case 'protocol': this.href = val+this.hostname+(this.port?':'+this.port:'')+this.pathname+this.search+this.hash; break;
case 'hostname': this.href = this.protocol+val+(this.port?':'+this.port:'')+this.pathname+this.search+this.hash; break;
case 'port': this.href = this.protocol+this.hostname+(val?':'+val:'')+this.pathname+this.search+this.hash; break;
case 'pathname': this.href = this.protocol+this.hostname+(this.port?':'+this.port:'')+val+this.search+this.hash; break;
case 'search': this.href = this.protocol+this.hostname+(this.port?':'+this.port:'')+this.pathname+val+this.hash; break;
case 'query':
var search = '';
for(var i in val) if(val.hasOwnProperty(i)) search += (search==''?'?':'&')+i+'='+val[i];
this.href = this.protocol+this.hostname+(this.port?':'+this.port:'')+this.pathname+search+this.hash;
break;
case 'hash': this.href = this.protocol+this.hostname+(this.port?':'+this.port:'')+this.pathname+this.search+val; break;
}
return this._makeUrlObj(this.href);
}
function getComputedStyleValue(node, jsStyleProp){
if(typeof jsStyleProp != 'string') new Error('getComputedStyleValue -> jsStyleProp must be type string');
if(!node.tagName) new Error('getComputedStyleValue -> node must be a node element');
return window.getComputedStyle(node).getPropertyValue(styleprop);
}
// createPrefilledArray(4, 1) ==> [1,1,1,1]
// createPrefilledArray(2, 'test') ==> ['test','test']
// ...
function createPrefilledArray(ofLength, withValue){
if(typeof ofLength === 'string') ofLength = Number(ofLength);
if(ofLength == undefined || typeof ofLength !== 'number'){ console.error('createPrefilledArray > invallid length type'); return; }
if(withValue == undefined){ console.error('createPrefilledArray > invallid value'); return; }
var type = null;
switch(typeof withValue){
case 'number': type = Number; break;
case 'string': type = String; break;
case 'boolean': type = Boolean; break;
case 'object': type = (withValue.hasOwnProperty('length'))? Array : Object; break;
}
if(!type){ console.error('createPrefilledArray > invallid value type'); return; }
return Array.apply(null, Array(ofLength)).map(type.prototype.valueOf, withValue);
}
// get the dom element out of the document with the xpath string aka get element by xpath
function getElementByXPath(xPath, doc){
if(!doc) doc = document;
if(doc.evaluate) return doc.evaluate(xPath, document, null, 9, null).singleNodeValue;
// for IE
while(xPath.charAt(0) == '/') xPath = xPath.substr(1);
var prevElem = doc;
var arr = xPath.split('/');
for(var i=0; i<arr.length; i++){
var step = arr[i].split(/(\w*)\[(\d*)\]/gi).filter(function(v){ return !(v==''||v.match(/\s/gi)) },this);
var elem = step[0];
var elemNum = step[1]?step[1]-1:0; // -1 since xpath is 1 based
if(i<arr.length-1) prevElem = prevElem.getElementsByTagName(elem)[elemNum];
else return prevElem.getElementsByTagName(elem)[elemNum];
}
}
// get the xpath string from a dom element out of the document aka get an element it's xpath
function getElementXPath(node, doc) {
if(doc == undefined) doc = document;
var xpath = '';
var pos, tempitem2;
while(node !== doc.documentElement) {
pos = 0; tempitem2 = node;
while(tempitem2) {
if (tempitem2.nodeType === 1 && tempitem2.nodeName === node.nodeName) { pos += 1; }
tempitem2 = tempitem2.previousSibling;
}
xpath = node.nodeName+'['+pos+']'+'/'+xpath;
node = node.parentNode;
}
xpath = '/'+doc.documentElement.nodeName+'/'+xpath;
xpath = xpath.replace(/\/$/, '');
return xpath;
}
// will give the top and left dimention in pixels from the browsers top left 0,0 point
function getPosition(who){
var T= 0,L= 0;
while(who){
L+= who.offsetLeft;
T+= who.offsetTop;
who= who.offsetParent;
}
return [L,T];
}
// alert(getPosition(document.getElementById('demo')))
function CssHelper(){
// checkers
this.isPx = function isPx(v){ return /px/gi.test(v); };
this.isPc = function isPc(v){ return /%|pc/gi.test(v); };
this.isVal = function isVal(v){ return !isNaN(v); };
// converters
this.toVal = function toVal(v){ return parseFloat(v); };
this.toUnit = function toUnit(unit, v){ return this.toVal(v)+unit; };
this.toPx = this.toUnit.bind(this, 'px');
this.toPc = this.toUnit.bind(this, '%');
}
/*
val[number/array]: the value that needs to be mapped
r1s[number]: range 1 start
r1e[number]: range 1 end
r2s[number]: range 2 start
r2e[number]: range 2 end
*/
function mapRange(val,r1s,r1e,r2s,r2e){
if(Array.isArray(val)) return val.map(function(v){ return mapRange(v,r1s,r1e,r2s,r2e); })
return (val-r1s)*((r2e-r2s)/(r1e-r1s))+r2s;
}
console.log(mapRange(0.25,0,1,-1,1)); // -0.5
console.log(mapRange([0.5, 0.75],0,1,-100,100)); // [0, 50]
// merge attributes and styles on a DOM element
function merge(item, attr, styles){
if(!item) return false;
if(attr)
for(var a in attr){
if(a=='className') attr[a].split(' ').forEach(function(v){ item.classList.add(v); });
else item.setAttribute(a,attr[a]);
}
if(styles) for(var s in styles) item.style[s] = styles[s].toString();
return true;
}
/**
* Random
* [min=0], [max=1], [float=false] ==> to receive random a number
* array|object, [min], [max] ==> to receive random value
*/
function Random(a, b, c){
function getLength(arr, min){
b = min||0;
if( b >= arr.length ){ console.error('min bigger or equqal length'); return; }
return arr.length-1;
}
// a = object, b = min, c = max
if( (typeof a === "object") && (a !== null) && !Array.isArray(a)){
var k = Object.keys( a );
var l = getLength( k, b );
c = Math.min( c||l, l );
return a[ Random( k , b, c ) ];
}
// a = array, b = min, c = max
if( Array.isArray(a) ) {
var l = getLength( a, b );
c = Math.min( c||l, l );
return a[ Random( b, c, true) ];
}
// a = min, b = max, c = floor
var min = a||0; var max = b||1;
max = c ? max+1 : max;
var r = min + Math.random()*(max - min);
return c ? Math.floor(r) : r;
}
//---------------------------------------------------------------------
console.clear();
// RANDOM INTEGERS AND FLOATS
console.log( Random() ); // random float between 0 and 1.
console.log( Random( 0, 1 ) ); // random float between 0 and 1.
console.log( Random( 0.2, 0.7) ); // random float between 0.2 and 0.7.
console.log( Random( 5, 7, true) ); // random integer between 5 and 7.
// RANDOM ARRAY ITEMS
var arr = ['one','two', 'three'];
console.log( Random( arr ) ); // random array item.
console.log( Random( arr, 1,2 ) ); // random array item, between INDEX 1 and 2.
// RANDOM OBJECT VALUES
var obj = { 'one':1, 'two':2, 'three':3 };
console.log( Random( obj ) ); // random object value.
console.log( Random( obj, 1, 2) ); // random object value, between INDEX 1 and 2.
function toHTMLEntity(str){
if(str === '') return str;
if(!str){ console.warn('toHTMLEntity has invalid str'); return ''; }
return str.replace(/[\u00A0-\u9999<>\&]/gim, function(v){ return '&#'+v.charCodeAt(0)+';' });
}
@RobertAlblas
Copy link

I'm trying to use your getElementByXPath for getting the element from an xpath. This works perfectly for me in Firefox, but in IE, I get the following error:

Unable to get property 'getElementsByTagName' of undefined or null reference.

I don't have a lot of experience with Javascript. Do you have the same problem or am I doing something wrong?

@Joopmicroop
Copy link
Author

Humm I think i never tested it in IE.. I'll take a look at it later. Tkx for letting me know.

@travishaagen
Copy link

Yeah, getElementByXPath would only work in IE when I brought in the shim from,

https://code.google.com/p/wicked-good-xpath/

@Joopmicroop
Copy link
Author

now moved to https://github.com/google/wicked-good-xpath since google code is closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment