Skip to content

Instantly share code, notes, and snippets.

@tzi
Last active March 3, 2016 14:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tzi/fc0545d826628cbb9c38 to your computer and use it in GitHub Desktop.
Save tzi/fc0545d826628cbb9c38 to your computer and use it in GitHub Desktop.
MorningJS - A simple lib to create widget

MorningJS

A simple lib to create widget (HTML, CSS) in pure JavaScript with IE8+ support.

Thanks to bl.ocks.org, you can try this gist online.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>MorningJS</title>
<style>
/* Global styles have no effect on widget */
h1 {
font-weight: normal;
}
</style>
</head>
<body>
<script src="morning.js"></script>
<script>
/* WIDGET HTML & CSS */
var html = '' +
'<div class="coco">' +
'<h1 class="choucroute">This title is dynamic</h1>' +
'<small>Created with MorningJS, in an iframe \\o/</small>' +
'<span class="counter"></span>' +
'</div>';
var styles = {
'.choucroute': 'background-color: yellow; font-style: italic',
'.choucroute:hover': 'background-color: olive',
'.coco small': 'display: block; color: grey'
}
/* WIDGET INITIALIZTION */
var widget = morning.createWidget(html, styles);
/* EVENTS */
var titleElement = widget.document.querySelector('h1');
if (titleElement.addEventListener) {
titleElement.addEventListener('click', titleClickHandler);
} else {
titleElement.attachEvent('onclick', titleClickHandler);
}
/* ROUTINES */
var count = 3;
var counterElement = widget.document.querySelector('.counter');
countDown();
/* WIDGET VISIBILITY */
widget.show();
/* UTILS */
function titleClickHandler() {
titleElement.style.backgroundColor = 'tomato';
}
function countDown() {
var text;
if (count > 0) {
text = count + 's avant décollage';
count--;
setTimeout(countDown, 1000);
} else {
text = 'Go!';
}
counterElement.innerHTML = text;
}
</script>
</body>
</html>
/** Create DOM and append it, from an HTML string, via an iframe
*
* Be aware the following support:
* * IE11+ to handle insertion in table, tr, thead, tbody elements (http://bit.ly/webbugtrack-210)
* * IE10+ to handle insertion in select elements (http://bit.ly/webbugtrack-274)
* * IE9+ to handle insertion in pre elements (http://bit.ly/webbugtrack-165)
* * IE8+ for other cases (http://bit.ly/webbugtrack-124)
*/
var morning = (function() {
function createWidget(html, styles, parentNode) {
var iframe;
var iframeDoc;
var styleSheet;
initIframe(parentNode);
addHtml(html);
addStyles(styles);
function initIframe(parentNode) {
// Add an hidden iframe that will contain our widget
parentNode = parentNode || document.body;
iframe = document.createElement('iframe');
iframe.frameBorder = 'no';
iframe.setAttribute('style', 'border: 0; width: 100%; height: 10px; visibility: hidden');
parentNode.appendChild(iframe);
iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
// Add a head & body to the iframe
iframeDoc.open();
iframeDoc.write("<html><body></body></html>");
iframeDoc.close();
// Add a stylesheet to the iframe
var style = iframeDoc.createElement('style');
iframeDoc.getElementsByTagName('head')[0].appendChild(style);
styleSheet = style.sheet ? style.sheet : style.styleSheet;
}
function addHtml(html) {
var fragment = document.createDocumentFragment();
var div = document.createElement('div');
var node;
div.innerHTML = html;
while (node = div.firstChild) {
fragment.appendChild(node);
}
iframeDoc.body.appendChild(fragment);
}
function addStyleRule(selector, rule) {
if ('insertRule' in styleSheet) {
styleSheet.insertRule(selector + '{' + rule + '}', styleSheet.cssRules.length);
} else if ('addRule' in styleSheet) {
styleSheet.addRule(selector, rule);
}
}
function addStyles(styles) {
styles = styles || {};
for (var selector in styles) {
addStyleRule(selector, styles[selector]);
}
}
function updateIframeHeight() {
var body = iframeDoc.body;
var html = iframeDoc.documentElement;
var height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
// IE opt. for bing/msn needs a bit added or scrollbar appears
iframe.style.height = ( height + 4 ) + "px";
}
function show() {
updateIframeHeight();
iframe.style.visibility = 'visible';
}
return {
element: iframe,
document: iframeDoc.documentElement,
show: show
};
}
return {
createWidget: createWidget
};
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment