How do you place/position/append a js file if you can't find any ref to a parent node? For example, someone wants to use my script on their webpage and wants it positioned in a div or table etc with no id, name or classname. Parent node just returns null.
My only solution is to keep coming back to the trusty old but allegedly evil document.write().I've read about the perils of document.write() but for this sort of script I've never had a problem.
Below is an example, my take on the old BBC analogue clock. I'm trying to keep up with times and the majority of it uses createElement and append but the wrapper/container is created via document.write().
As it stands, you can stick it anywhere you want and, as far as I've tested, without any problem. Any ideas?
(function () {
/* The BBC Analogue Clock - kurt.grigg@yahoo.co.uk */
/* ^^^^^^^^^^^^^^^^^^^ Config below ^^^^^^^^^^^^^^^^^^^ */
var clockSize = 300;
var dialcol = 'rgba(0,0,255,1.0)';
var handcol = 'rgb(230,230,230)';
/* ^^^^^^^^^^^^^^^^^^^ End config ^^^^^^^^^^^^^^^^^^^ */
var d = document;
var mrkrs = [];
var e = (360 / 12);
var degr = 0;
var mls = 100;
var prev = performance.now();
var radi = Math.PI / 180;
var offs = 60 * radi;
var rndId = 'id'+Math.random() * 1;
var sSpan = '.9s';
var mSpan = '1s';
var hSpan = '1s';
var sIncr = 0;
var mIncr = 0;
var hIncr = 0;
var sDeg, mDeg, hDeg, sPre, mPre, hPre;
var idx = d.getElementsByTagName('div').length;
d.write('<div id = "'+rndId+'" style="display:inline-block;line-height:0px;"></div>');
function xy(a) {
return (a * clockSize / 100);
}
var dial = d.createElement('div');
dial.setAttribute('style', 'display: inline-block;'
+'position: relative;'
+'height: '+clockSize+'px;'
+'width: '+clockSize+'px;'
+'margin: 0px;padding: 0px;'
+'border-radius: 5%;z-index: 1;'
+'background-color: '+dialcol+';');
d.getElementById(rndId).appendChild(dial);
for (var i = 0; i < 12; i++) {
var incr = xy(2.0) + (i * xy(0.2));
mrkrs[i] = d.createElement('div');
mrkrs[i].setAttribute('style', 'display: block;'
+'position: absolute;'
+'width: '+xy(14)+'px;'
+'height: '+xy(14)+'px;'
+'margin: auto; top: 0;bottom: 0;left: 0;right: 0;'
+'font-size: 0px;line-height: 0px;padding: 0;'
+'text-align: center !important;'
+'background-color: transparent;');
mrkrs[i].innerHTML = '<div style = "display: inline-block;'
+'position: relative;width: '+incr+'px;height: '+xy(14)+'px;'
+'font-size: 0px;background-color:'+handcol+';'
+'margin-right: '+xy(0.6)+'px;"></div>'
+'<div style = "display:inline-block;position: relative;'
+'width: '+incr+'px;height: '+xy(14)+'px;font-size: 0px;'
+'margin-left: '+xy(0.6)+'px;'
+'background-color:'+handcol+';"></div>';
dial.appendChild(mrkrs[i]);
degr += 30;
mrkrs[i].style.top = xy(0) + xy(77) *
Math.sin(-offs + e * i * radi) + 'px';
mrkrs[i].style.left= xy(0) + xy(77) *
Math.cos(-offs + e * i * radi) + 'px';
mrkrs[i].style.transform = 'rotate(' + (degr) + 'deg)';
mrkrs[i].style.transformOrigin = 'center center';
}
/* Hour CSS */
var hCss = 'display: block;'
+'position: absolute;'
+'height: '+xy(56)+'px;'
+'width: '+xy(6)+'px;'
+'font-size: 0px;line-height: 0px;padding: 0;'
+'margin: auto; top: 0;bottom: 0; left: 0; right: 0;'
+'transform-origin: center center 0;'
+'z-index: 2;';
var hClone = hCss;
var houHand = d.createElement('div');
houHand.setAttribute('style', hClone);
dial.appendChild(houHand);
var hh = d.createElement('div');
hh.setAttribute('style', 'display: block;'
+'position: absolute;'
+'height: '+xy(21)+'px;'
+'width: '+xy(6)+'px;'
+'font-size: 0px;line-height: 0px;padding: 0;'
+'margin: auto; top: 0; left: 0; right: 0;'
+'background-color: '+handcol+';');
houHand.appendChild(hh);
/* Minute CSS */
var mCss = 'display: block;'
+'position: absolute;'
+'height: '+xy(86)+'px;'
+'width: '+xy(4)+'px;'
+'font-size: 0px;line-height: 0px;padding: 0;'
+'margin: auto; top: 0; bottom: 0; left: 0; right: 0;'
+'transform-origin: center center;'
+'z-index: 3;';
var mClone = mCss;
var minHand = d.createElement('div');
minHand.setAttribute('style', mClone);
dial.appendChild(minHand);
var mh = d.createElement('div');
mh.setAttribute('style', 'display: block;'
+'position: absolute;'
+'height: '+xy(36)+'px;'
+'width: '+xy(4)+'px;'
+'font-size: 0px;line-height: 0px;padding: 0;'
+'margin: auto; top: 0; left: 0; right: 0;'
+'background-color: '+handcol+';');
minHand.appendChild(mh);
/* Second CSS */
var sCss = 'display: block;'
+'position: absolute;'
+'height: '+xy(90)+'px;'
+'width: '+xy(2)+'px;'
+'font-size: 0px;line-height: 0px;padding: 0;'
+'margin: auto; top: 0;bottom: 0; left: 0; right: 0;'
+'transform-origin: center center;'
+'z-index: 4;';
var sClone = sCss;
var secHand = d.createElement('div');
secHand.setAttribute('style', sClone);
dial.appendChild(secHand);
var sh = d.createElement('div');
sh.setAttribute('style', 'display: block;'
+'position: absolute;'
+'height: '+xy(39)+'px;'
+'width: '+xy(2)+'px;'
+'font-size: 0px;line-height: 0px;padding: 0;'
+'margin: auto; top: 0; left: 0; right: 0;'
+'background-color: '+handcol+';');
secHand.appendChild(sh);
var sectail = d.createElement('div');
sectail.setAttribute('style', 'display: block;'
+'position: absolute;'
+'height: '+xy(12)+'px;'
+'width: '+xy(2)+'px;'
+'margin: auto; left: 0; right: 0;'
+'font-size: 0px;line-height: 0px;padding: 0;'
+'top: '+xy(52)+'px;'
+'background-color: '+handcol+';');
secHand.appendChild(sectail);
/* Centre nut & optional glass front CSS */
var nut = d.createElement('div');
nut.setAttribute('style', 'display: inline-block;'
+'position: absolute;'
+'height: '+xy(10)+'px;'
+'width: '+xy(10)+'px;'
+'font-size: 0px;line-height: 0px;padding: 0;'
+'border: '+xy(3)+'px solid '+handcol+';'
+'border-radius: 50%;'
+'margin: auto;top: 0;bottom: 0;left: 0;right: 0;'
+'background-color: transparent;'
+'z-index: 5;');
dial.appendChild(nut);
var glass = d.createElement('div');
glass.setAttribute('style', 'display: block;'
+'height:'+clockSize+'px;'
+'width: '+clockSize+'px;'
+'border-radius:'+xy(5)+'px;'
+'margin: auto;top: 0;bottom: 0;left: 0;right: 0;'
+'z-index: 6;box-shadow:'
+'0 '+xy(1)+'px '+xy(1)+'px rgba(0,0,0,0.5),'
+'inset 0 '+xy(1)+'px rgba(255,255,255,0.3),'
+'inset 0 '+xy(10)+'px rgba(255,255,255,0.2),'
+'inset 0 '+xy(10)+'px '+xy(20)+'px rgba(255,255,255,0.25),'
+'inset 0 -'+xy(15)+'px '+xy(30)+'px rgba(0,0,0,0.3);');
dial.appendChild(glass);
var eiatf = 'translateZ(0); animation-timing-function: ease-in';
var eoatf = 'translateZ(0); animation-timing-function: ease-out';
function secKeyFrames() {
var secSheet = (d.getElementById('tmpSecSheet'+idx));
if (secSheet) {
secSheet.outerHTML = '';
}
sClone = sCss;
var p1 = sDeg;
var p2 = sDeg+6;
var p3 = sDeg+4;
var p4 = sDeg+6;
var p5 = sDeg+5;
var p6 = sDeg+6;
var secframes = '@keyframes reGen'+sIncr+' { '
+'0% { transform: rotate('+p1+'deg) '+eiatf+';}'
+'30% { transform: rotate('+p2+'deg) '+eoatf+';}'
+'45% { transform: rotate('+p3+'deg) '+eiatf+';}'
+'60% { transform: rotate('+p4+'deg) '+eoatf+';}'
+'70% { transform: rotate('+p5+'deg) '+eiatf+';}'
+'80%,100% { transform: rotate('+p6+'deg) '+eoatf+';}}';
var ss = document.createElement( 'style' );
ss.setAttribute('id', 'tmpSecSheet'+idx);
ss.innerHTML = secframes;
document.getElementsByTagName('head')[0].appendChild(ss);
var secAni = 'animation: reGen'+sIncr+' '+sSpan+' 1 forwards;';
sClone += secAni;
secHand.setAttribute('style', sClone);
dial.appendChild(secHand);
}
function minKeyFrames() {
var minSheet = (d.getElementById('tmpMinSheet'+idx));
if (minSheet) {
minSheet.outerHTML = '';
}
mClone = mCss;
var p1 = mDeg;
var p2 = mDeg+6;
var p3 = mDeg+4;
var p4 = mDeg+6;
var p5 = mDeg+5;
var p6 = mDeg+6;
var minframes = '@keyframes minGen'+mIncr+' { '
+'0% { transform: rotate('+p1+'deg) '+eiatf+';}'
+'30% { transform: rotate('+p2+'deg) '+eoatf+';}'
+'45% { transform: rotate('+p3+'deg) '+eiatf+';}'
+'60% { transform: rotate('+p4+'deg) '+eoatf+';}'
+'70% { transform: rotate('+p5+'deg) '+eiatf+';}'
+'80%,100% { transform: rotate('+p6+'deg) '+eoatf+';}}';
var ms = document.createElement( 'style' );
ms.setAttribute('id', 'tmpMinSheet'+idx);
ms.innerHTML = minframes;
d.getElementsByTagName('head')[0].appendChild(ms);
var minAni = 'animation: minGen'+mIncr+' '+mSpan+' 1 forwards;';
mClone += minAni;
minHand.setAttribute('style', mClone);
dial.appendChild(minHand);
}
function houKeyFrames() {
var houSheet = (d.getElementById('tmphouSheet'+idx));
if (houSheet) {
houSheet.outerHTML = '';
}
hClone = hCss;
var p1 = hDeg;
var p2 = hDeg+1;
var p3 = hDeg+0.4;
var p4 = hDeg+1;
var p5 = hDeg+0.5;
var p6 = hDeg+1;
var houframes = '@keyframes houGen'+hIncr+' { '
+'0% { transform: rotate('+p1+'deg) '+eiatf+';}'
+'30% { transform: rotate('+p2+'deg) '+eoatf+';}'
+'45% { transform: rotate('+p3+'deg) '+eiatf+';}'
+'60% { transform: rotate('+p4+'deg) '+eoatf+';}'
+'70% { transform: rotate('+p5+'deg) '+eiatf+';}'
+'80%,100% { transform: rotate('+p6+'deg) '+eoatf+';}}';
var hs = document.createElement( 'style' );
hs.setAttribute('id', 'tmphouSheet'+idx);
hs.innerHTML = houframes;
d.getElementsByTagName('head')[0].appendChild(hs);
var houAni = 'animation: houGen'+hIncr+' '+hSpan+' 1 forwards;';
hClone += houAni;
houHand.setAttribute('style', hClone);
dial.appendChild(houHand);
}
function animate() {
var x = new Date();
var seconds = x.getSeconds();
var minutes = x.getMinutes();
var hours = (x.getHours() * 30) + (x.getMinutes() / 2);
if (seconds !== sPre) {
sIncr++;
sDeg = (seconds-1) * 6;
secHand.removeAttribute('style');
secKeyFrames();
if (sIncr > 59) {
sIncr = 0;
}
}
if (minutes !== mPre) {
mIncr++;
mDeg = (minutes-1) * 6;
minHand.removeAttribute('style');
minKeyFrames();
if (mIncr > 59) {
mIncr = 0;
}
}
if (hours !== hPre) {
hIncr++;
hDeg = (hours-1) * 1;
houHand.removeAttribute('style');
houKeyFrames();
if (hIncr > 59) {
hIncr = 0;
}
}
sPre = seconds;
mPre = minutes;
hPre = hours;
}
function cyc() {
var pres = performance.now();
if ((pres - prev) > mls) {
animate();
prev = performance.now();
}
window.requestAnimationFrame(cyc);
}
window.addEventListener('load', cyc, false);
})();