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
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!