Skip to content

Instantly share code, notes, and snippets.

@vitalyrotari
Last active December 19, 2015 04:58
Show Gist options
  • Save vitalyrotari/5900653 to your computer and use it in GitHub Desktop.
Save vitalyrotari/5900653 to your computer and use it in GitHub Desktop.
JavaScript Notify Plugin
/**
* Reset
*/
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
html, body {
height: 100%;
}
body {
padding: 0;
margin: 0;
}
/**
* Notify
*/
.notify-message {
border-radius: 3px;
color: white;
padding: 10px;
position: absolute;
bottom: 0;
left: 50%;
margin-left: -160px;
width: 320px;
-webkit-transition: all .35s;
-moz-transition: all .35s;
-o-transition: all .35s;
transition: all .35s;
-webkit-transform: translateY(100px);
-moz-transform: translateY(100px);
-o-transform: translateY(100px);
transform: translateY(100px);
}
.notify-show {
-webkit-transform: translateY(-10px);
-moz-transform: translateY(-10px);
-o-transform: translateY(-10px);
transform: translateY(-10px);
}
.notify-message[data-title]:before {
display: block;
content: attr(data-title);
font-weight: bold;
font-size: 16px;
margin-bottom: 5px;
}
.notify-message[data-type="info"] {
background-color: blue;
}
.notify-message[data-type="success"] {
background-color: green;
}
.notify-message[data-type="error"] {
background-color: red;
}
(function (exports) {
var Notify
, NotifyUI
, transitionEnd;
/**
* CSS Transition End
*/
(function () {
var names = {
'transition' : 'transitionend',
'OTransition' : 'oTransitionEnd',
'WebkitTransition': 'webkitTransitionEnd',
'MozTransition' : 'transitionend'
},
method;
for (var prop in names) {
if (typeof document.body.style[prop] !== "undefined") {
method = names[prop];
break;
}
}
transitionEnd = function (element, cb, once) {
if (method) {
var func = function () {
cb.call(element, event);
if (once) {
element.removeEventListener(method, func);
}
} ;
element.addEventListener(method, func, false);
} else {
cb.call(element);
}
};
})();
/**
* Notify Message
* @interface
*/
function NotifyMessage (body, title, type) {
this.title = title || null;
this.body = body;
this.type = type || Notify.Type.INFO;
}
NotifyUI = {
/**
* @type {Element}
* @private
*/
element: null,
/**
* @type {number}
* @private
*/
timer: 0,
/**
* @this {NotifyMessage}
*/
create: function () {
if (!this.element) {
var fragment = document.createDocumentFragment();
this.element = document.createElement("div");
this.element.classList.add("notify-message");
this.element.addEventListener("click", function () {
NotifyUI.destroy();
}, false);
fragment.appendChild(this.element);
document.body.appendChild(fragment);
}
},
/**
* @param {NotifyMessage} message
* @this {NotifyMessage}
*/
show: function (message) {
this.create();
var classes = this.element.classList;
function apply () {
var dataset = NotifyUI.element.dataset;
dataset.type = message.type;
if (message.title) {
dataset.title = message.title;
} else {
delete dataset.title;
}
NotifyUI.element.textContent = message.body;
transitionEnd(NotifyUI.element, function () {
NotifyUI.timer = setTimeout(function () {
Notify.show();
}, Notify.delay);
}, true);
setTimeout(function () {
classes.add("notify-show");
}, 0);
}
if (classes.contains("notify-show")) {
transitionEnd(this.element, function () {
apply();
}, true);
setTimeout(function () {
classes.remove("notify-show");
}, 0);
} else {
apply();
}
},
/**
* @this {NotifyMessage}
*/
destroy: function () {
if (this.element) {
transitionEnd(this.element, function () {
clearTimeout(NotifyUI.timer);
NotifyUI.element.parentNode.removeChild(NotifyUI.element);
NotifyUI.element = null;
NotifyUI.timer = 0;
}, true);
setTimeout(function () {
NotifyUI.element.classList.remove("notify-show");
}, 0);
}
}
};
Notify = {
/**
* @type {Array.<NotifyMessage>}
* @private
*/
collection: [],
/**
* @type {number}
* @public
*/
delay: 3000,
/**
* @type {boolean}
* @private
*/
process: false,
/**
* @param {string} message
* @param {string=} title
* @param {string=} type
* @this {Notify}
*/
send: function (message, title, type) {
if (message) {
this.collection.push(new NotifyMessage(message, title, type));
if (!this.process) {
this.show();
this.process = true;
}
}
},
/**
* @this {Notify}
*/
show: function () {
if (this.collection.length) {
NotifyUI.show(this.collection.splice(0, 1)[0]);
} else {
this.flush();
}
},
/**
* @this {Notify}
*/
flush: function () {
NotifyUI.destroy();
clearInterval(this.process);
this.process = false;
this.collection.length = 0;
}
};
/**
* @enum {string}
*/
Notify.Type = {
SUCCESS: "success",
ERROR : "error",
INFO : "info"
};
exports.Notify = Notify;
})(window);
Notify.flush();
for (var _i=0; _i<10; _i++) {
Notify.send("Test message #" + (_i+1), "Mail");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment