toast.js 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225
  1. (function (root, factory) {
  2. if(typeof define === 'function' && define.amd) {
  3. define([], factory(root));
  4. } else if(typeof exports === 'object') {
  5. module.exports = factory(root);
  6. } else if (window.layui && layui.define) {
  7. layui.define(function(exports){
  8. exports('toast',factory(root))
  9. })
  10. }else {
  11. root.iziToast = factory(root);
  12. }
  13. })(typeof global !== 'undefined' ? global : window || this.window || this.global, function (root) {
  14. 'use strict';
  15. var $iziToast = {},
  16. PLUGIN_NAME = 'iziToast',
  17. BODY = document.querySelector('body'),
  18. ISMOBILE = (/Mobi/.test(navigator.userAgent)) ? true : false,
  19. ISCHROME = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor),
  20. ISFIREFOX = typeof InstallTrigger !== 'undefined',
  21. ACCEPTSTOUCH = 'ontouchstart' in document.documentElement,
  22. POSITIONS = ['bottomRight','bottomLeft','bottomCenter','topRight','topLeft','topCenter','center'],
  23. THEMES = {
  24. info: {
  25. color: 'blue',
  26. icon: 'ico-info'
  27. },
  28. success: {
  29. color: 'green',
  30. icon: 'ico-success'
  31. },
  32. warning: {
  33. color: 'orange',
  34. icon: 'ico-warning'
  35. },
  36. error: {
  37. color: 'red',
  38. icon: 'ico-error'
  39. },
  40. question: {
  41. color: 'yellow',
  42. icon: 'ico-question'
  43. }
  44. },
  45. MOBILEWIDTH = 568,
  46. CONFIG = {};
  47. $iziToast.children = {};
  48. // Default settings
  49. var defaults = {
  50. id: null,
  51. class: '',
  52. title: '',
  53. titleColor: '',
  54. titleSize: '',
  55. titleLineHeight: '',
  56. message: '',
  57. messageColor: '',
  58. messageSize: '',
  59. messageLineHeight: '',
  60. backgroundColor: '',
  61. theme: 'light', // dark
  62. color: '', // blue, red, green, yellow
  63. icon: '',
  64. iconText: '',
  65. iconColor: '',
  66. iconUrl: null,
  67. image: '',
  68. imageWidth: 50,
  69. maxWidth: null,
  70. zindex: null,
  71. layout: 2,
  72. balloon: false,
  73. close: true,
  74. closeOnEscape: false,
  75. closeOnClick: false,
  76. displayMode: 0,
  77. position: 'topCenter', // bottomRight, bottomLeft, topRight, topLeft, topCenter, bottomCenter, center
  78. target: '',
  79. targetFirst: true,
  80. timeout: 3000, // 默认3秒
  81. rtl: false,
  82. animateInside: false, // 动画效果
  83. drag: true,
  84. pauseOnHover: true,
  85. resetOnHover: false,
  86. progressBar: false,
  87. progressBarColor: '',
  88. progressBarEasing: 'linear',
  89. overlay: false,
  90. overlayClose: false,
  91. overlayColor: 'rgba(0, 0, 0, 0.6)',
  92. transitionIn: 'fadeInDown', // bounceInLeft, bounceInRight, bounceInUp, bounceInDown, fadeIn, fadeInDown, fadeInUp, fadeInLeft, fadeInRight, flipInX
  93. transitionOut: 'fadeOut', // fadeOut, fadeOutUp, fadeOutDown, fadeOutLeft, fadeOutRight, flipOutX
  94. transitionInMobile: 'bounceInDown',
  95. transitionOutMobile: 'fadeOutUp',
  96. buttons: {},
  97. inputs: {},
  98. onOpening: function () {},
  99. onOpened: function () {},
  100. onClosing: function () {},
  101. onClosed: function () {}
  102. };
  103. if(!('remove' in Element.prototype)) {
  104. Element.prototype.remove = function() {
  105. if(this.parentNode) {
  106. this.parentNode.removeChild(this);
  107. }
  108. };
  109. }
  110. if(typeof window.CustomEvent !== 'function') {
  111. var CustomEventPolyfill = function (event, params) {
  112. params = params || { bubbles: false, cancelable: false, detail: undefined };
  113. var evt = document.createEvent('CustomEvent');
  114. evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
  115. return evt;
  116. };
  117. CustomEventPolyfill.prototype = window.Event.prototype;
  118. window.CustomEvent = CustomEventPolyfill;
  119. }
  120. var forEach = function (collection, callback, scope) {
  121. if(Object.prototype.toString.call(collection) === '[object Object]') {
  122. for (var prop in collection) {
  123. if(Object.prototype.hasOwnProperty.call(collection, prop)) {
  124. callback.call(scope, collection[prop], prop, collection);
  125. }
  126. }
  127. } else {
  128. if(collection){
  129. for (var i = 0, len = collection.length; i < len; i++) {
  130. callback.call(scope, collection[i], i, collection);
  131. }
  132. }
  133. }
  134. };
  135. var extend = function (defaults, options) {
  136. var extended = {};
  137. forEach(defaults, function (value, prop) {
  138. extended[prop] = defaults[prop];
  139. });
  140. forEach(options, function (value, prop) {
  141. extended[prop] = options[prop];
  142. });
  143. return extended;
  144. };
  145. var createFragElem = function(htmlStr) {
  146. var frag = document.createDocumentFragment(),
  147. temp = document.createElement('div');
  148. temp.innerHTML = htmlStr;
  149. while (temp.firstChild) {
  150. frag.appendChild(temp.firstChild);
  151. }
  152. return frag;
  153. };
  154. var generateId = function(params) {
  155. var newId = btoa(encodeURIComponent(params));
  156. return newId.replace(/=/g, "");
  157. };
  158. var isColor = function(color){
  159. if( color.substring(0,1) == '#' || color.substring(0,3) == 'rgb' || color.substring(0,3) == 'hsl' ){
  160. return true;
  161. } else {
  162. return false;
  163. }
  164. };
  165. var isBase64 = function(str) {
  166. try {
  167. return btoa(atob(str)) == str;
  168. } catch (err) {
  169. return false;
  170. }
  171. };
  172. var drag = function() {
  173. return {
  174. move: function(toast, instance, settings, xpos) {
  175. var opacity,
  176. opacityRange = 0.3,
  177. distance = 180;
  178. if(xpos !== 0){
  179. toast.classList.add(PLUGIN_NAME+'-dragged');
  180. toast.style.transform = 'translateX('+xpos + 'px)';
  181. if(xpos > 0){
  182. opacity = (distance-xpos) / distance;
  183. if(opacity < opacityRange){
  184. instance.hide(extend(settings, { transitionOut: 'fadeOutRight', transitionOutMobile: 'fadeOutRight' }), toast, 'drag');
  185. }
  186. } else {
  187. opacity = (distance+xpos) / distance;
  188. if(opacity < opacityRange){
  189. instance.hide(extend(settings, { transitionOut: 'fadeOutLeft', transitionOutMobile: 'fadeOutLeft' }), toast, 'drag');
  190. }
  191. }
  192. toast.style.opacity = opacity;
  193. if(opacity < opacityRange){
  194. if(ISCHROME || ISFIREFOX)
  195. toast.style.left = xpos+'px';
  196. toast.parentNode.style.opacity = opacityRange;
  197. this.stopMoving(toast, null);
  198. }
  199. }
  200. },
  201. startMoving: function(toast, instance, settings, e) {
  202. e = e || window.event;
  203. var posX = ((ACCEPTSTOUCH) ? e.touches[0].clientX : e.clientX),
  204. toastLeft = toast.style.transform.replace('px)', '');
  205. toastLeft = toastLeft.replace('translateX(', '');
  206. var offsetX = posX - toastLeft;
  207. if(settings.transitionIn){
  208. toast.classList.remove(settings.transitionIn);
  209. }
  210. if(settings.transitionInMobile){
  211. toast.classList.remove(settings.transitionInMobile);
  212. }
  213. toast.style.transition = '';
  214. if(ACCEPTSTOUCH) {
  215. document.ontouchmove = function(e) {
  216. e.preventDefault();
  217. e = e || window.event;
  218. var posX = e.touches[0].clientX,
  219. finalX = posX - offsetX;
  220. drag.move(toast, instance, settings, finalX);
  221. };
  222. } else {
  223. document.onmousemove = function(e) {
  224. e.preventDefault();
  225. e = e || window.event;
  226. var posX = e.clientX,
  227. finalX = posX - offsetX;
  228. drag.move(toast, instance, settings, finalX);
  229. };
  230. }
  231. },
  232. stopMoving: function(toast, e) {
  233. if(ACCEPTSTOUCH) {
  234. document.ontouchmove = function() {};
  235. } else {
  236. document.onmousemove = function() {};
  237. }
  238. toast.style.opacity = '';
  239. toast.style.transform = '';
  240. if(toast.classList.contains(PLUGIN_NAME+'-dragged')){
  241. toast.classList.remove(PLUGIN_NAME+'-dragged');
  242. toast.style.transition = 'transform 0.4s ease, opacity 0.4s ease';
  243. setTimeout(function() {
  244. toast.style.transition = '';
  245. }, 400);
  246. }
  247. }
  248. };
  249. }();
  250. $iziToast.setSetting = function (ref, option, value) {
  251. $iziToast.children[ref][option] = value;
  252. };
  253. $iziToast.getSetting = function (ref, option) {
  254. return $iziToast.children[ref][option];
  255. };
  256. $iziToast.destroy = function () {
  257. forEach(document.querySelectorAll('.'+PLUGIN_NAME+'-overlay'), function(element, index) {
  258. element.remove();
  259. });
  260. forEach(document.querySelectorAll('.'+PLUGIN_NAME+'-wrapper'), function(element, index) {
  261. element.remove();
  262. });
  263. forEach(document.querySelectorAll('.'+PLUGIN_NAME), function(element, index) {
  264. element.remove();
  265. });
  266. this.children = {};
  267. // Remove event listeners
  268. document.removeEventListener(PLUGIN_NAME+'-opened', {}, false);
  269. document.removeEventListener(PLUGIN_NAME+'-opening', {}, false);
  270. document.removeEventListener(PLUGIN_NAME+'-closing', {}, false);
  271. document.removeEventListener(PLUGIN_NAME+'-closed', {}, false);
  272. document.removeEventListener('keyup', {}, false);
  273. // Reset variables
  274. CONFIG = {};
  275. };
  276. /**
  277. * Initialize Plugin
  278. * @public
  279. * @param {Object} options User settings
  280. */
  281. $iziToast.settings = function (options) {
  282. // Destroy any existing initializations
  283. $iziToast.destroy();
  284. CONFIG = options;
  285. defaults = extend(defaults, options || {});
  286. };
  287. /**
  288. * Building themes functions.
  289. * @public
  290. * @param {Object} options User settings
  291. */
  292. forEach(THEMES, function (theme, name) {
  293. $iziToast[name] = function (options) {
  294. var settings = extend(CONFIG, options || {});
  295. settings = extend(theme, settings || {});
  296. this.show(settings);
  297. };
  298. });
  299. /**
  300. * Do the calculation to move the progress bar
  301. * @private
  302. */
  303. $iziToast.progress = function (options, $toast, callback) {
  304. var that = this,
  305. ref = $toast.getAttribute('data-iziToast-ref'),
  306. settings = extend(this.children[ref], options || {}),
  307. $elem = $toast.querySelector('.'+PLUGIN_NAME+'-progressbar div');
  308. return {
  309. start: function() {
  310. if(typeof settings.time.REMAINING == 'undefined'){
  311. $toast.classList.remove(PLUGIN_NAME+'-reseted');
  312. if($elem !== null){
  313. $elem.style.transition = 'width '+ settings.timeout +'ms '+settings.progressBarEasing;
  314. $elem.style.width = '0%';
  315. }
  316. settings.time.START = new Date().getTime();
  317. settings.time.END = settings.time.START + settings.timeout;
  318. settings.time.TIMER = setTimeout(function() {
  319. clearTimeout(settings.time.TIMER);
  320. if(!$toast.classList.contains(PLUGIN_NAME+'-closing')){
  321. that.hide(settings, $toast, 'timeout');
  322. if(typeof callback === 'function'){
  323. callback.apply(that);
  324. }
  325. }
  326. }, settings.timeout);
  327. that.setSetting(ref, 'time', settings.time);
  328. }
  329. },
  330. pause: function() {
  331. if(typeof settings.time.START !== 'undefined' && !$toast.classList.contains(PLUGIN_NAME+'-paused') && !$toast.classList.contains(PLUGIN_NAME+'-reseted')){
  332. $toast.classList.add(PLUGIN_NAME+'-paused');
  333. settings.time.REMAINING = settings.time.END - new Date().getTime();
  334. clearTimeout(settings.time.TIMER);
  335. that.setSetting(ref, 'time', settings.time);
  336. if($elem !== null){
  337. var computedStyle = window.getComputedStyle($elem),
  338. propertyWidth = computedStyle.getPropertyValue('width');
  339. $elem.style.transition = 'none';
  340. $elem.style.width = propertyWidth;
  341. }
  342. if(typeof callback === 'function'){
  343. setTimeout(function() {
  344. callback.apply(that);
  345. }, 10);
  346. }
  347. }
  348. },
  349. resume: function() {
  350. if(typeof settings.time.REMAINING !== 'undefined'){
  351. $toast.classList.remove(PLUGIN_NAME+'-paused');
  352. if($elem !== null){
  353. $elem.style.transition = 'width '+ settings.time.REMAINING +'ms '+settings.progressBarEasing;
  354. $elem.style.width = '0%';
  355. }
  356. settings.time.END = new Date().getTime() + settings.time.REMAINING;
  357. settings.time.TIMER = setTimeout(function() {
  358. clearTimeout(settings.time.TIMER);
  359. if(!$toast.classList.contains(PLUGIN_NAME+'-closing')){
  360. that.hide(settings, $toast, 'timeout');
  361. if(typeof callback === 'function'){
  362. callback.apply(that);
  363. }
  364. }
  365. }, settings.time.REMAINING);
  366. that.setSetting(ref, 'time', settings.time);
  367. } else {
  368. this.start();
  369. }
  370. },
  371. reset: function(){
  372. clearTimeout(settings.time.TIMER);
  373. delete settings.time.REMAINING;
  374. that.setSetting(ref, 'time', settings.time);
  375. $toast.classList.add(PLUGIN_NAME+'-reseted');
  376. $toast.classList.remove(PLUGIN_NAME+'-paused');
  377. if($elem !== null){
  378. $elem.style.transition = 'none';
  379. $elem.style.width = '100%';
  380. }
  381. if(typeof callback === 'function'){
  382. setTimeout(function() {
  383. callback.apply(that);
  384. }, 10);
  385. }
  386. }
  387. };
  388. };
  389. /**
  390. * Close the specific Toast
  391. * @public
  392. * @param {Object} options User settings
  393. */
  394. $iziToast.hide = function (options, $toast, closedBy) {
  395. if(typeof $toast != 'object'){
  396. $toast = document.querySelector($toast);
  397. }
  398. var that = this,
  399. settings = extend(this.children[$toast.getAttribute('data-iziToast-ref')], options || {});
  400. settings.closedBy = closedBy || null;
  401. delete settings.time.REMAINING;
  402. $toast.classList.add(PLUGIN_NAME+'-closing');
  403. // Overlay
  404. (function(){
  405. var $overlay = document.querySelector('.'+PLUGIN_NAME+'-overlay');
  406. if($overlay !== null){
  407. var refs = $overlay.getAttribute('data-iziToast-ref');
  408. refs = refs.split(',');
  409. var index = refs.indexOf(String(settings.ref));
  410. if(index !== -1){
  411. refs.splice(index, 1);
  412. }
  413. $overlay.setAttribute('data-iziToast-ref', refs.join());
  414. if(refs.length === 0){
  415. $overlay.classList.remove('fadeIn');
  416. $overlay.classList.add('fadeOut');
  417. setTimeout(function() {
  418. $overlay.remove();
  419. }, 700);
  420. }
  421. }
  422. })();
  423. if(settings.transitionIn){
  424. $toast.classList.remove(settings.transitionIn);
  425. }
  426. if(settings.transitionInMobile){
  427. $toast.classList.remove(settings.transitionInMobile);
  428. }
  429. if(ISMOBILE || window.innerWidth <= MOBILEWIDTH){
  430. if(settings.transitionOutMobile)
  431. $toast.classList.add(settings.transitionOutMobile);
  432. } else {
  433. if(settings.transitionOut)
  434. $toast.classList.add(settings.transitionOut);
  435. }
  436. var H = $toast.parentNode.offsetHeight;
  437. $toast.parentNode.style.height = H+'px';
  438. $toast.style.pointerEvents = 'none';
  439. if(!ISMOBILE || window.innerWidth > MOBILEWIDTH){
  440. $toast.parentNode.style.transitionDelay = '0.2s';
  441. }
  442. try {
  443. var event = new CustomEvent(PLUGIN_NAME+'-closing', {detail: settings, bubbles: true, cancelable: true});
  444. document.dispatchEvent(event);
  445. } catch(ex){
  446. console.warn(ex);
  447. }
  448. setTimeout(function() {
  449. $toast.parentNode.style.height = '0px';
  450. $toast.parentNode.style.overflow = '';
  451. setTimeout(function(){
  452. delete that.children[settings.ref];
  453. $toast.parentNode.remove();
  454. try {
  455. var event = new CustomEvent(PLUGIN_NAME+'-closed', {detail: settings, bubbles: true, cancelable: true});
  456. document.dispatchEvent(event);
  457. } catch(ex){
  458. console.warn(ex);
  459. }
  460. if(typeof settings.onClosed !== 'undefined'){
  461. settings.onClosed.apply(null, [settings, $toast, closedBy]);
  462. }
  463. }, 1000);
  464. }, 200);
  465. if(typeof settings.onClosing !== 'undefined'){
  466. settings.onClosing.apply(null, [settings, $toast, closedBy]);
  467. }
  468. };
  469. /**
  470. * Create and show the Toast
  471. * @public
  472. * @param {Object} options User settings
  473. */
  474. $iziToast.show = function (options) {
  475. var that = this;
  476. // Merge user options with defaults
  477. var settings = extend(CONFIG, options || {});
  478. settings = extend(defaults, settings);
  479. settings.time = {};
  480. if(settings.id === null){
  481. settings.id = generateId(settings.title+settings.message+settings.color);
  482. }
  483. if(settings.displayMode === 1 || settings.displayMode == 'once'){
  484. try {
  485. if(document.querySelectorAll('.'+PLUGIN_NAME+'#'+settings.id).length > 0){
  486. return false;
  487. }
  488. } catch (exc) {
  489. console.warn('['+PLUGIN_NAME+'] Could not find an element with this selector: '+'#'+settings.id+'. Try to set an valid id.');
  490. }
  491. }
  492. if(settings.displayMode === 2 || settings.displayMode == 'replace'){
  493. try {
  494. forEach(document.querySelectorAll('.'+PLUGIN_NAME+'#'+settings.id), function(element, index) {
  495. that.hide(settings, element, 'replaced');
  496. });
  497. } catch (exc) {
  498. console.warn('['+PLUGIN_NAME+'] Could not find an element with this selector: '+'#'+settings.id+'. Try to set an valid id.');
  499. }
  500. }
  501. settings.ref = new Date().getTime() + Math.floor((Math.random() * 10000000) + 1);
  502. $iziToast.children[settings.ref] = settings;
  503. var $DOM = {
  504. body: document.querySelector('body'),
  505. overlay: document.createElement('div'),
  506. toast: document.createElement('div'),
  507. toastBody: document.createElement('div'),
  508. toastTexts: document.createElement('div'),
  509. toastCapsule: document.createElement('div'),
  510. cover: document.createElement('div'),
  511. buttons: document.createElement('div'),
  512. inputs: document.createElement('div'),
  513. icon: !settings.iconUrl ? document.createElement('i') : document.createElement('img'),
  514. wrapper: null
  515. };
  516. $DOM.toast.setAttribute('data-iziToast-ref', settings.ref);
  517. $DOM.toast.appendChild($DOM.toastBody);
  518. $DOM.toastCapsule.appendChild($DOM.toast);
  519. // CSS Settings
  520. (function(){
  521. $DOM.toast.classList.add(PLUGIN_NAME);
  522. $DOM.toast.classList.add(PLUGIN_NAME+'-opening');
  523. $DOM.toastCapsule.classList.add(PLUGIN_NAME+'-capsule');
  524. $DOM.toastBody.classList.add(PLUGIN_NAME + '-body');
  525. $DOM.toastTexts.classList.add(PLUGIN_NAME + '-texts');
  526. if(ISMOBILE || window.innerWidth <= MOBILEWIDTH){
  527. if(settings.transitionInMobile)
  528. $DOM.toast.classList.add(settings.transitionInMobile);
  529. } else {
  530. if(settings.transitionIn)
  531. $DOM.toast.classList.add(settings.transitionIn);
  532. }
  533. if(settings.class){
  534. var classes = settings.class.split(' ');
  535. forEach(classes, function (value, index) {
  536. $DOM.toast.classList.add(value);
  537. });
  538. }
  539. if(settings.id){ $DOM.toast.id = settings.id; }
  540. if(settings.rtl){
  541. $DOM.toast.classList.add(PLUGIN_NAME + '-rtl');
  542. $DOM.toast.setAttribute('dir', 'rtl');
  543. }
  544. if(settings.layout > 1){ $DOM.toast.classList.add(PLUGIN_NAME+'-layout'+settings.layout); }
  545. if(settings.balloon){ $DOM.toast.classList.add(PLUGIN_NAME+'-balloon'); }
  546. if(settings.maxWidth){
  547. if( !isNaN(settings.maxWidth) ){
  548. $DOM.toast.style.maxWidth = settings.maxWidth+'px';
  549. } else {
  550. $DOM.toast.style.maxWidth = settings.maxWidth;
  551. }
  552. }
  553. if(settings.theme !== '' || settings.theme !== 'light') {
  554. $DOM.toast.classList.add(PLUGIN_NAME+'-theme-'+settings.theme);
  555. }
  556. if(settings.color) { //#, rgb, rgba, hsl
  557. if( isColor(settings.color) ){
  558. $DOM.toast.style.background = settings.color;
  559. } else {
  560. $DOM.toast.classList.add(PLUGIN_NAME+'-color-'+settings.color);
  561. }
  562. }
  563. if(settings.backgroundColor) {
  564. $DOM.toast.style.background = settings.backgroundColor;
  565. if(settings.balloon){
  566. $DOM.toast.style.borderColor = settings.backgroundColor;
  567. }
  568. }
  569. })();
  570. // Cover image
  571. (function(){
  572. if(settings.image) {
  573. $DOM.cover.classList.add(PLUGIN_NAME + '-cover');
  574. $DOM.cover.style.width = settings.imageWidth + 'px';
  575. if(isBase64(settings.image.replace(/ /g,''))){
  576. $DOM.cover.style.backgroundImage = 'url(data:image/png;base64,' + settings.image.replace(/ /g,'') + ')';
  577. } else {
  578. $DOM.cover.style.backgroundImage = 'url(' + settings.image + ')';
  579. }
  580. if(settings.rtl){
  581. $DOM.toastBody.style.marginRight = (settings.imageWidth + 10) + 'px';
  582. } else {
  583. $DOM.toastBody.style.marginLeft = (settings.imageWidth + 10) + 'px';
  584. }
  585. $DOM.toast.appendChild($DOM.cover);
  586. }
  587. })();
  588. // Button close
  589. (function(){
  590. if(settings.close){
  591. $DOM.buttonClose = document.createElement('button');
  592. $DOM.buttonClose.type = 'button';
  593. $DOM.buttonClose.classList.add(PLUGIN_NAME + '-close');
  594. $DOM.buttonClose.addEventListener('click', function (e) {
  595. var button = e.target;
  596. that.hide(settings, $DOM.toast, 'button');
  597. });
  598. $DOM.toast.appendChild($DOM.buttonClose);
  599. } else {
  600. if(settings.rtl){
  601. $DOM.toast.style.paddingLeft = '18px';
  602. } else {
  603. $DOM.toast.style.paddingRight = '18px';
  604. }
  605. }
  606. })();
  607. // Progress Bar & Timeout
  608. (function(){
  609. if(settings.progressBar){
  610. $DOM.progressBar = document.createElement('div');
  611. $DOM.progressBarDiv = document.createElement('div');
  612. $DOM.progressBar.classList.add(PLUGIN_NAME + '-progressbar');
  613. $DOM.progressBarDiv.style.background = settings.progressBarColor;
  614. $DOM.progressBar.appendChild($DOM.progressBarDiv);
  615. $DOM.toast.appendChild($DOM.progressBar);
  616. }
  617. if(settings.timeout) {
  618. if(settings.pauseOnHover && !settings.resetOnHover){
  619. $DOM.toast.addEventListener('mouseenter', function (e) {
  620. that.progress(settings, $DOM.toast).pause();
  621. });
  622. $DOM.toast.addEventListener('mouseleave', function (e) {
  623. that.progress(settings, $DOM.toast).resume();
  624. });
  625. }
  626. if(settings.resetOnHover){
  627. $DOM.toast.addEventListener('mouseenter', function (e) {
  628. that.progress(settings, $DOM.toast).reset();
  629. });
  630. $DOM.toast.addEventListener('mouseleave', function (e) {
  631. that.progress(settings, $DOM.toast).start();
  632. });
  633. }
  634. }
  635. })();
  636. // Icon
  637. (function(){
  638. if(settings.iconUrl) {
  639. $DOM.icon.setAttribute('class', PLUGIN_NAME + '-icon');
  640. $DOM.icon.setAttribute('src', settings.iconUrl);
  641. } else if(settings.icon) {
  642. $DOM.icon.setAttribute('class', PLUGIN_NAME + '-icon ' + settings.icon);
  643. if(settings.iconText){
  644. $DOM.icon.appendChild(document.createTextNode(settings.iconText));
  645. }
  646. if(settings.iconColor){
  647. $DOM.icon.style.color = settings.iconColor;
  648. }
  649. }
  650. if(settings.icon || settings.iconUrl) {
  651. if(settings.rtl){
  652. $DOM.toastBody.style.paddingRight = '33px';
  653. } else {
  654. $DOM.toastBody.style.paddingLeft = '33px';
  655. }
  656. $DOM.toastBody.appendChild($DOM.icon);
  657. }
  658. })();
  659. // Title & Message
  660. (function(){
  661. if(settings.title.length > 0) {
  662. $DOM.strong = document.createElement('strong');
  663. $DOM.strong.classList.add(PLUGIN_NAME + '-title');
  664. $DOM.strong.appendChild(createFragElem(settings.title));
  665. $DOM.toastTexts.appendChild($DOM.strong);
  666. if(settings.titleColor) {
  667. $DOM.strong.style.color = settings.titleColor;
  668. }
  669. if(settings.titleSize) {
  670. if( !isNaN(settings.titleSize) ){
  671. $DOM.strong.style.fontSize = settings.titleSize+'px';
  672. } else {
  673. $DOM.strong.style.fontSize = settings.titleSize;
  674. }
  675. }
  676. if(settings.titleLineHeight) {
  677. if( !isNaN(settings.titleSize) ){
  678. $DOM.strong.style.lineHeight = settings.titleLineHeight+'px';
  679. } else {
  680. $DOM.strong.style.lineHeight = settings.titleLineHeight;
  681. }
  682. }
  683. }
  684. if(settings.message.length > 0) {
  685. $DOM.p = document.createElement('p');
  686. $DOM.p.classList.add(PLUGIN_NAME + '-message');
  687. $DOM.p.appendChild(createFragElem(settings.message));
  688. $DOM.toastTexts.appendChild($DOM.p);
  689. if(settings.messageColor) {
  690. $DOM.p.style.color = settings.messageColor;
  691. }
  692. if(settings.messageSize) {
  693. if( !isNaN(settings.titleSize) ){
  694. $DOM.p.style.fontSize = settings.messageSize+'px';
  695. } else {
  696. $DOM.p.style.fontSize = settings.messageSize;
  697. }
  698. }
  699. if(settings.messageLineHeight) {
  700. if( !isNaN(settings.titleSize) ){
  701. $DOM.p.style.lineHeight = settings.messageLineHeight+'px';
  702. } else {
  703. $DOM.p.style.lineHeight = settings.messageLineHeight;
  704. }
  705. }
  706. }
  707. if(settings.title.length > 0 && settings.message.length > 0) {
  708. if(settings.rtl){
  709. $DOM.strong.style.marginLeft = '10px';
  710. } else if(settings.layout !== 2 && !settings.rtl) {
  711. $DOM.strong.style.marginRight = '10px';
  712. }
  713. }
  714. })();
  715. $DOM.toastBody.appendChild($DOM.toastTexts);
  716. // Inputs
  717. var $inputs;
  718. (function(){
  719. if(settings.inputs.length > 0) {
  720. $DOM.inputs.classList.add(PLUGIN_NAME + '-inputs');
  721. forEach(settings.inputs, function (value, index) {
  722. $DOM.inputs.appendChild(createFragElem(value[0]));
  723. $inputs = $DOM.inputs.childNodes;
  724. $inputs[index].classList.add(PLUGIN_NAME + '-inputs-child');
  725. if(value[3]){
  726. setTimeout(function() {
  727. $inputs[index].focus();
  728. }, 300);
  729. }
  730. $inputs[index].addEventListener(value[1], function (e) {
  731. var ts = value[2];
  732. return ts(that, $DOM.toast, this, e);
  733. });
  734. });
  735. $DOM.toastBody.appendChild($DOM.inputs);
  736. }
  737. })();
  738. // Buttons
  739. (function(){
  740. if(settings.buttons.length > 0) {
  741. $DOM.buttons.classList.add(PLUGIN_NAME + '-buttons');
  742. forEach(settings.buttons, function (value, index) {
  743. $DOM.buttons.appendChild(createFragElem(value[0]));
  744. var $btns = $DOM.buttons.childNodes;
  745. $btns[index].classList.add(PLUGIN_NAME + '-buttons-child');
  746. if(value[2]){
  747. setTimeout(function() {
  748. $btns[index].focus();
  749. }, 300);
  750. }
  751. $btns[index].addEventListener('click', function (e) {
  752. e.preventDefault();
  753. var ts = value[1];
  754. return ts(that, $DOM.toast, this, e, $inputs);
  755. });
  756. });
  757. }
  758. $DOM.toastBody.appendChild($DOM.buttons);
  759. })();
  760. if(settings.message.length > 0 && (settings.inputs.length > 0 || settings.buttons.length > 0)) {
  761. $DOM.p.style.marginBottom = '0';
  762. }
  763. if(settings.inputs.length > 0 || settings.buttons.length > 0){
  764. if(settings.rtl){
  765. $DOM.toastTexts.style.marginLeft = '10px';
  766. } else {
  767. $DOM.toastTexts.style.marginRight = '10px';
  768. }
  769. if(settings.inputs.length > 0 && settings.buttons.length > 0){
  770. if(settings.rtl){
  771. $DOM.inputs.style.marginLeft = '8px';
  772. } else {
  773. $DOM.inputs.style.marginRight = '8px';
  774. }
  775. }
  776. }
  777. // Wrap
  778. (function(){
  779. $DOM.toastCapsule.style.visibility = 'hidden';
  780. setTimeout(function() {
  781. var H = $DOM.toast.offsetHeight;
  782. var style = $DOM.toast.currentStyle || window.getComputedStyle($DOM.toast);
  783. var marginTop = style.marginTop;
  784. marginTop = marginTop.split('px');
  785. marginTop = parseInt(marginTop[0]);
  786. var marginBottom = style.marginBottom;
  787. marginBottom = marginBottom.split('px');
  788. marginBottom = parseInt(marginBottom[0]);
  789. $DOM.toastCapsule.style.visibility = '';
  790. $DOM.toastCapsule.style.height = (H+marginBottom+marginTop)+'px';
  791. setTimeout(function() {
  792. $DOM.toastCapsule.style.height = 'auto';
  793. if(settings.target){
  794. $DOM.toastCapsule.style.overflow = 'visible';
  795. }
  796. }, 500);
  797. if(settings.timeout) {
  798. that.progress(settings, $DOM.toast).start();
  799. }
  800. }, 100);
  801. })();
  802. // Target
  803. (function(){
  804. var position = settings.position;
  805. if(settings.target){
  806. $DOM.wrapper = document.querySelector(settings.target);
  807. $DOM.wrapper.classList.add(PLUGIN_NAME + '-target');
  808. if(settings.targetFirst) {
  809. $DOM.wrapper.insertBefore($DOM.toastCapsule, $DOM.wrapper.firstChild);
  810. } else {
  811. $DOM.wrapper.appendChild($DOM.toastCapsule);
  812. }
  813. } else {
  814. if( POSITIONS.indexOf(settings.position) == -1 ){
  815. console.warn('['+PLUGIN_NAME+'] Incorrect position.\nIt can be › ' + POSITIONS);
  816. return;
  817. }
  818. if(ISMOBILE || window.innerWidth <= MOBILEWIDTH){
  819. if(settings.position == 'bottomLeft' || settings.position == 'bottomRight' || settings.position == 'bottomCenter'){
  820. position = PLUGIN_NAME+'-wrapper-bottomCenter';
  821. }
  822. else if(settings.position == 'topLeft' || settings.position == 'topRight' || settings.position == 'topCenter'){
  823. position = PLUGIN_NAME+'-wrapper-topCenter';
  824. }
  825. else {
  826. position = PLUGIN_NAME+'-wrapper-center';
  827. }
  828. } else {
  829. position = PLUGIN_NAME+'-wrapper-'+position;
  830. }
  831. $DOM.wrapper = document.querySelector('.' + PLUGIN_NAME + '-wrapper.'+position);
  832. if(!$DOM.wrapper) {
  833. $DOM.wrapper = document.createElement('div');
  834. $DOM.wrapper.classList.add(PLUGIN_NAME + '-wrapper');
  835. $DOM.wrapper.classList.add(position);
  836. document.body.appendChild($DOM.wrapper);
  837. }
  838. if(settings.position == 'topLeft' || settings.position == 'topCenter' || settings.position == 'topRight'){
  839. $DOM.wrapper.insertBefore($DOM.toastCapsule, $DOM.wrapper.firstChild);
  840. } else {
  841. $DOM.wrapper.appendChild($DOM.toastCapsule);
  842. }
  843. }
  844. if(!isNaN(settings.zindex)) {
  845. $DOM.wrapper.style.zIndex = settings.zindex;
  846. } else {
  847. console.warn('['+PLUGIN_NAME+'] Invalid zIndex.');
  848. }
  849. })();
  850. // Overlay
  851. (function(){
  852. if(settings.overlay) {
  853. if( document.querySelector('.'+PLUGIN_NAME+'-overlay.fadeIn') !== null ){
  854. $DOM.overlay = document.querySelector('.'+PLUGIN_NAME+'-overlay');
  855. $DOM.overlay.setAttribute('data-iziToast-ref', $DOM.overlay.getAttribute('data-iziToast-ref') + ',' + settings.ref);
  856. if(!isNaN(settings.zindex) && settings.zindex !== null) {
  857. $DOM.overlay.style.zIndex = settings.zindex-1;
  858. }
  859. } else {
  860. $DOM.overlay.classList.add(PLUGIN_NAME+'-overlay');
  861. $DOM.overlay.classList.add('fadeIn');
  862. $DOM.overlay.style.background = settings.overlayColor;
  863. $DOM.overlay.setAttribute('data-iziToast-ref', settings.ref);
  864. if(!isNaN(settings.zindex) && settings.zindex !== null) {
  865. $DOM.overlay.style.zIndex = settings.zindex-1;
  866. }
  867. document.querySelector('body').appendChild($DOM.overlay);
  868. }
  869. if(settings.overlayClose) {
  870. $DOM.overlay.removeEventListener('click', {});
  871. $DOM.overlay.addEventListener('click', function (e) {
  872. that.hide(settings, $DOM.toast, 'overlay');
  873. });
  874. } else {
  875. $DOM.overlay.removeEventListener('click', {});
  876. }
  877. }
  878. })();
  879. // Inside animations
  880. (function(){
  881. if(settings.animateInside){
  882. $DOM.toast.classList.add(PLUGIN_NAME+'-animateInside');
  883. var animationTimes = [200, 100, 300];
  884. if(settings.transitionIn == 'bounceInLeft' || settings.transitionIn == 'bounceInRight'){
  885. animationTimes = [400, 200, 400];
  886. }
  887. if(settings.title.length > 0) {
  888. setTimeout(function(){
  889. $DOM.strong.classList.add('slideIn');
  890. }, animationTimes[0]);
  891. }
  892. if(settings.message.length > 0) {
  893. setTimeout(function(){
  894. $DOM.p.classList.add('slideIn');
  895. }, animationTimes[1]);
  896. }
  897. if(settings.icon || settings.iconUrl) {
  898. setTimeout(function(){
  899. $DOM.icon.classList.add('revealIn');
  900. }, animationTimes[2]);
  901. }
  902. var counter = 150;
  903. if(settings.buttons.length > 0 && $DOM.buttons) {
  904. setTimeout(function(){
  905. forEach($DOM.buttons.childNodes, function(element, index) {
  906. setTimeout(function(){
  907. element.classList.add('revealIn');
  908. }, counter);
  909. counter = counter + 150;
  910. });
  911. }, settings.inputs.length > 0 ? 150 : 0);
  912. }
  913. if(settings.inputs.length > 0 && $DOM.inputs) {
  914. counter = 150;
  915. forEach($DOM.inputs.childNodes, function(element, index) {
  916. setTimeout(function(){
  917. element.classList.add('revealIn');
  918. }, counter);
  919. counter = counter + 150;
  920. });
  921. }
  922. }
  923. })();
  924. settings.onOpening.apply(null, [settings, $DOM.toast]);
  925. try {
  926. var event = new CustomEvent(PLUGIN_NAME + '-opening', {detail: settings, bubbles: true, cancelable: true});
  927. document.dispatchEvent(event);
  928. } catch(ex){
  929. console.warn(ex);
  930. }
  931. setTimeout(function() {
  932. $DOM.toast.classList.remove(PLUGIN_NAME+'-opening');
  933. $DOM.toast.classList.add(PLUGIN_NAME+'-opened');
  934. try {
  935. var event = new CustomEvent(PLUGIN_NAME + '-opened', {detail: settings, bubbles: true, cancelable: true});
  936. document.dispatchEvent(event);
  937. } catch(ex){
  938. console.warn(ex);
  939. }
  940. settings.onOpened.apply(null, [settings, $DOM.toast]);
  941. }, 1000);
  942. if(settings.drag){
  943. if(ACCEPTSTOUCH) {
  944. $DOM.toast.addEventListener('touchstart', function(e) {
  945. drag.startMoving(this, that, settings, e);
  946. }, false);
  947. $DOM.toast.addEventListener('touchend', function(e) {
  948. drag.stopMoving(this, e);
  949. }, false);
  950. } else {
  951. $DOM.toast.addEventListener('mousedown', function(e) {
  952. e.preventDefault();
  953. drag.startMoving(this, that, settings, e);
  954. }, false);
  955. $DOM.toast.addEventListener('mouseup', function(e) {
  956. e.preventDefault();
  957. drag.stopMoving(this, e);
  958. }, false);
  959. }
  960. }
  961. if(settings.closeOnEscape) {
  962. document.addEventListener('keyup', function (evt) {
  963. evt = evt || window.event;
  964. if(evt.keyCode == 27) {
  965. that.hide(settings, $DOM.toast, 'esc');
  966. }
  967. });
  968. }
  969. if(settings.closeOnClick) {
  970. $DOM.toast.addEventListener('click', function (evt) {
  971. that.hide(settings, $DOM.toast, 'toast');
  972. });
  973. }
  974. that.toast = $DOM.toast;
  975. };
  976. return $iziToast;
  977. });