DOM Manipulation additions

So at times I find myself needing to do some simple neighbor selection and summing in the DOM and I don’t have the tools I need so I wind up doing tedious, repetitive logic in loops, so I built a few useful utility functions:

Element.siblingsBefore() and Element.siblingsAfter() return a new Elements instance containing all the neighbors on that side of the element in respect to it’s parent in the DOM.

Element.hasStyle(name, value) tests the element for a particular value and also supports >value and Elements.excludeStyles(styles) and Elements.includeStyles(styles) filter an element set based on their styles(also supports >,< via hasStyle) Elements.mergedStyles(commaDelimitedString or array) combines multiple style values from Elements.getStyle into a single array.

Array.sumStrings() can sum the mixed string/units arrays returned by Elements.getStyle(name)

So to take this out of the abstract say I want to see how much space is taken up above me inside the element selected, but I want to exclude absolute elements and anything that’s 0 height… normally a bunch of code and tedious, but now:

document.id('element_id').siblingsBefore().excludeStyles(
{position:'absolute', height:'0px'}
).mergedStyles(
'height,margin-top,margin-bottom,padding-top,padding-bottom'
).sumStrings()

Now That’s way better.

if(!Element.siblingsBefore){
Element.implement({
siblingsBefore : function(){
var results = [];
var found = false;
this.getParent().getChildren().each(function(child){
if(this == child) found = true;
if(!found) results.push(child);
});
return new Elements(results);
}
});
}
if(!Element.siblingsAfter){
Element.implement({
siblingsAfter : function(){
var results = [];
var found = false;
this.getParent().getChildren().each(function(child){
if(found) results.push(child);
if(this == child) found = true;
});
return new Elements(results);
}
});
}
if(!Array.sumStrings){
Array.implement({
sumStrings : function(){
var result = 0;
this.each(function(child){
var val = parseInt(Number.from(child));
if(val) result += val;
});
return result;
}
});
}
if(!Element.hasStyle){
Element.implement({
hasStyle : function(name, style){
var result = false;
var num = Number.from(this.getStyle(name));
if(num != null){
switch(style.substring(0,1)){
case '>' :
if(num > Number.from(style.substring(1))) result = true;
break;
case '<' :
if(num > Number.from(style.substring(1))) result = true;
break;
default:
if(num == Number.from(style)) result = true;
}
}else{
switch(style.substring(0,1)){
case '>' :
if(this.getStyle(name) > style.substring(1)) result = true;
break;
case '<' :
if(this.getStyle(name) > style.substring(1)) result = true;
break;
default:
if(this.getStyle(name) == style) result = true;
}
}
return result;
}
})
}
if(!Elements.mergedStyles){
Elements.implement({
mergedStyles : function(styles){
results = [];
if(typeOf(styles) == 'string'){
styles = styles.split(',');
}
styles.each(function(style){
results = results.concat(this.getStyle(style));
}.bind(this));
return results;
}
});
}
if(!Elements.excludeStyles){
Elements.implement({
excludeStyles : function(styles){
var results = [];
this.each(function(element){
var found = false;
Object.each(styles, function(style, name){
if(typeOf(style) == 'array'){
style.each(function(thisStyle){
found = found || element.hasStyle(name, thisStyle);
}.bind(this));
}else{
found = found || element.hasStyle(name, style);
}
}.bind(this));
if(!found) results.push(element);
}.bind(this));
return new Elements(results);
}
});
}
if(!Elements.includeStyles){
Elements.implement({
includeStyles : function(styles){
results = [];
this.each(function(element){
var found = false;
Object.each(styles, function(style, name){
if(typeOf(style) == 'array'){
style.each(function(thisStyle){
found = found || element.hasStyle(name, thisStyle);
}.bind(this));
}else{
found = found || element.hasStyle(name, style);
}
}.bind(this));
if(found) results.push(element);
}.bind(this));
return new Elements(results);
}
});
}

Enjoy!

Leave a Reply