├── .gitignore ├── .DS_Store ├── images ├── 1.gif ├── 2.png └── .DS_Store ├── dist ├── .DS_Store ├── notice.css └── notice.js ├── LICENSE ├── README.md └── example └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | dist/new_notice.js 2 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myttyy/layuinotice/HEAD/.DS_Store -------------------------------------------------------------------------------- /images/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myttyy/layuinotice/HEAD/images/1.gif -------------------------------------------------------------------------------- /images/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myttyy/layuinotice/HEAD/images/2.png -------------------------------------------------------------------------------- /dist/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myttyy/layuinotice/HEAD/dist/.DS_Store -------------------------------------------------------------------------------- /images/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myttyy/layuinotice/HEAD/images/.DS_Store -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 myttyy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 基于layui的notice通知控件 2 | 3 | #### 项目介绍 4 | 5 | ##### 更新日志 6 | - 2019-04-10 7 | - V2增加桌面通知方法 8 | 9 | - 2019-03-26 10 | - 重构V2版本,如需使用V1版请查看v1分支 11 | - 新增多种位置选择 12 | - 优化同时显示多条通知 13 | - **css代码初始化js载入,不独立文件css文件。** 14 | 15 | ##### 更新日志 16 | - 2018年9月18日 17 | - **感谢layui社区成员@Thans修改了本插件** 18 | - 优化显示位置,改到右侧。(@Thans) 19 | - 可以同时显示多条通知(@Thans) 20 | - css代码初始化载入,不独立文件。(@Thans) 21 | - 在Thans修改版本上增加桌面提醒 22 | 23 | 基于layui的notice通知控件,算是对layer的一个小扩展 24 | 25 | 列示: 26 | ![](./images/2.png) 27 | 28 | #### 使用说明 29 | 30 | 1. 配置layui扩展 31 | 32 | ```javascript 33 | layui.config({ 34 | base: './../dist/' 35 | }); 36 | ``` 37 | 38 | 3. 调用API 39 | 40 | ```javascript 41 | layui.use(['notice'], function () { 42 | var notice = layui.notice; // 允许别名 toastr 43 | 44 | // 初始化配置,同一样式只需要配置一次,非必须初始化,有默认配置 45 | notice.options = { 46 | closeButton:true,//显示关闭按钮 47 | debug:false,//启用debug 48 | positionClass:"toast-top-right",//弹出的位置, 49 | showDuration:"300",//显示的时间 50 | hideDuration:"1000",//消失的时间 51 | timeOut:"2000",//停留的时间 52 | extendedTimeOut:"1000",//控制时间 53 | showEasing:"swing",//显示时的动画缓冲方式 54 | hideEasing:"linear",//消失时的动画缓冲方式 55 | iconClass: 'toast-info', // 自定义图标,有内置,如不需要则传空 支持layui内置图标/自定义iconfont类名 56 | onclick: null, // 点击关闭回调 57 | }; 58 | 59 | 60 | notice.warning("成功"); 61 | notice.info("提示信息:毛都没有..."); 62 | notice.error("大佬,我咋知道怎么肥四!"); 63 | let notice01 = notice.success("大佬,我咋知道怎么肥四!"); 64 | /// 增加桌面提示 65 | notice.desktopInfo("大佬,我咋知道怎么肥四!"); 66 | 67 | // 手动移除notice 或者使用 remove 68 | notice01.clear(notice01); 69 | 70 | 71 | }); 72 | ``` 73 | 4. positionClass属性可选值: 74 | - toast-top-center 75 | - toast-bottom-center 76 | - toast-top-full-width 77 | - toast-bottom-full-width 78 | - toast-top-left 79 | - toast-top-right 80 | - toast-bottom-right 81 | - toast-bottom-left 82 | 83 | 5. 其他配置项 84 | 85 | ```javascript 86 | // 默认配置 87 | { 88 | tapToDismiss: true, 89 | toastClass: 'toast', 90 | containerId: 'toast-container', 91 | debug: false, 92 | 93 | showMethod: 'fadeIn', //fadeIn, slideDown, and show are built into jQuery 94 | showDuration: 300, 95 | showEasing: 'swing', //swing and linear are built into jQuery 96 | onShown: undefined, 97 | hideMethod: 'fadeOut', 98 | hideDuration: 1000, 99 | hideEasing: 'swing', 100 | onHidden: undefined, 101 | closeMethod: false, 102 | closeDuration: false, 103 | closeEasing: false, 104 | closeOnHover: true, 105 | 106 | extendedTimeOut: 1000, 107 | iconClasses: { 108 | error: 'toast-error', 109 | info: 'toast-info', 110 | success: 'toast-success', 111 | warning: 'toast-warning' 112 | }, 113 | iconClass: 'toast-info', 114 | positionClass: 'toast-top-right', 115 | timeOut: 5000, // Set timeOut and extendedTimeOut to 0 to make it sticky 116 | titleClass: 'toast-title', 117 | messageClass: 'toast-message', 118 | escapeHtml: false, 119 | target: 'body', 120 | closeHtml: '', 121 | closeClass: 'toast-close-button', 122 | newestOnTop: true, 123 | preventDuplicates: false, 124 | progressBar: false, 125 | progressClass: 'toast-progress', 126 | rtl: false 127 | }; 128 | ``` 129 | 130 | 5. 支持方法 131 | 132 | ```javascript 133 | layui.use(['notice'], function () { 134 | // 警告提示 135 | notice.warning("提示内容"); 136 | // 正常提示 137 | notice.info("提示内容"); 138 | // 异常提示 139 | notice.error("提示内容"); 140 | // 141 | notice.success("提示内容"); 142 | }); 143 | ``` 144 | 145 | 146 | 147 | #### 参与贡献 148 | 149 | 1. Fork 本项目 150 | 2. 新建 Feat_xxx 分支 151 | 3. 提交代码 152 | 4. 新建 Pull Request 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 基于layui的notice通知控件 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 |
19 |
20 | 21 | 1.此控件是基于layui的notice通知控件,可用于美化消息通知 22 | 2.控件支持响应式 23 |
24 |
25 | 26 |
27 |
API
28 | 29 | 30 |
 31 |                 //使用说明
 32 |                 layui.use(['notice'], function () {
 33 |                     var notice = layui.notice; // 允许别名 toastr
 34 |                         
 35 |                         // 初始化配置,同一样式只需要配置一次,非必须初始化,有默认配置
 36 |                         notice.options = {
 37 |                             closeButton:true,//显示关闭按钮
 38 |                             debug:false,//启用debug
 39 |                             positionClass:"toast-top-right",//弹出的位置,
 40 |                             showDuration:"300",//显示的时间
 41 |                             hideDuration:"1000",//消失的时间
 42 |                             timeOut:"2000",//停留的时间
 43 |                             extendedTimeOut:"1000",//控制时间
 44 |                             showEasing:"swing",//显示时的动画缓冲方式
 45 |                             hideEasing:"linear",//消失时的动画缓冲方式
 46 |                             iconClass: 'toast-info', // 自定义图标,有内置,如不需要则传空 支持layui内置图标/自定义iconfont类名
 47 |                             onclick: null, // 点击关闭回调
 48 |                         };
 49 | 
 50 | 
 51 |                         notice.warning("成功");
 52 |                         notice.info("提示信息:毛都没有...");
 53 |                         notice.error("大佬,我咋知道怎么肥四!");
 54 |                         notice.success("大佬,我咋知道怎么肥四!");
 55 |                 });
 56 |                 
57 |
58 |
59 | 60 | 61 |
62 |
63 |
64 |
65 | 66 | 67 | 137 | 138 | -------------------------------------------------------------------------------- /dist/notice.css: -------------------------------------------------------------------------------- 1 | .toast-title { 2 | font-weight: bold; 3 | } 4 | .toast-message { 5 | -ms-word-wrap: break-word; 6 | word-wrap: break-word; 7 | } 8 | .toast-message a, 9 | .toast-message label { 10 | color: #FFFFFF; 11 | } 12 | .toast-message a:hover { 13 | color: #CCCCCC; 14 | text-decoration: none; 15 | } 16 | .toast-close-button { 17 | position: relative; 18 | right: -0.3em; 19 | top: -0.3em; 20 | float: right; 21 | font-size: 20px; 22 | font-weight: bold; 23 | color: #FFFFFF; 24 | -webkit-text-shadow: 0 1px 0 #ffffff; 25 | text-shadow: 0 1px 0 #ffffff; 26 | opacity: 0.8; 27 | -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80); 28 | filter: alpha(opacity=80); 29 | line-height: 1; 30 | } 31 | .toast-close-button:hover, 32 | .toast-close-button:focus { 33 | color: #000000; 34 | text-decoration: none; 35 | cursor: pointer; 36 | opacity: 0.4; 37 | -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40); 38 | filter: alpha(opacity=40); 39 | } 40 | .rtl .toast-close-button { 41 | left: -0.3em; 42 | float: left; 43 | right: 0.3em; 44 | } 45 | /*Additional properties for button version 46 | iOS requires the button element instead of an anchor tag. 47 | If you want the anchor version, it requires `href="#"`.*/ 48 | button.toast-close-button { 49 | padding: 0; 50 | cursor: pointer; 51 | background: transparent; 52 | border: 0; 53 | -webkit-appearance: none; 54 | } 55 | .toast-top-center { 56 | top: 0; 57 | right: 0; 58 | width: 100%; 59 | } 60 | .toast-bottom-center { 61 | bottom: 0; 62 | right: 0; 63 | width: 100%; 64 | } 65 | .toast-top-full-width { 66 | top: 0; 67 | right: 0; 68 | width: 100%; 69 | } 70 | .toast-bottom-full-width { 71 | bottom: 0; 72 | right: 0; 73 | width: 100%; 74 | } 75 | .toast-top-left { 76 | top: 12px; 77 | left: 12px; 78 | } 79 | .toast-top-right { 80 | top: 12px; 81 | right: 12px; 82 | } 83 | .toast-bottom-right { 84 | right: 12px; 85 | bottom: 12px; 86 | } 87 | .toast-bottom-left { 88 | bottom: 12px; 89 | left: 12px; 90 | } 91 | #toast-container { 92 | position: fixed; 93 | z-index: 999999; 94 | pointer-events: none; 95 | /*overrides*/ 96 | } 97 | #toast-container * { 98 | -moz-box-sizing: border-box; 99 | -webkit-box-sizing: border-box; 100 | box-sizing: border-box; 101 | } 102 | #toast-container > div { 103 | position: relative; 104 | pointer-events: auto; 105 | overflow: hidden; 106 | margin: 0 0 6px; 107 | padding: 15px 15px 15px 50px; 108 | width: 300px; 109 | -moz-border-radius: 3px 3px 3px 3px; 110 | -webkit-border-radius: 3px 3px 3px 3px; 111 | border-radius: 3px 3px 3px 3px; 112 | background-position: 15px center; 113 | background-repeat: no-repeat; 114 | -moz-box-shadow: 0 0 12px #999999; 115 | -webkit-box-shadow: 0 0 12px #999999; 116 | box-shadow: 0 0 12px #999999; 117 | color: #FFFFFF; 118 | opacity: 0.8; 119 | -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80); 120 | filter: alpha(opacity=80); 121 | } 122 | #toast-container > div.rtl { 123 | direction: rtl; 124 | padding: 15px 50px 15px 15px; 125 | background-position: right 15px center; 126 | } 127 | #toast-container > div:hover { 128 | -moz-box-shadow: 0 0 12px #000000; 129 | -webkit-box-shadow: 0 0 12px #000000; 130 | box-shadow: 0 0 12px #000000; 131 | opacity: 1; 132 | -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100); 133 | filter: alpha(opacity=100); 134 | cursor: pointer; 135 | } 136 | #toast-container > .toast-info { 137 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=") !important; 138 | } 139 | #toast-container > .toast-error { 140 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=") !important; 141 | } 142 | #toast-container > .toast-success { 143 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==") !important; 144 | } 145 | #toast-container > .toast-warning { 146 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=") !important; 147 | } 148 | #toast-container.toast-top-center > div, 149 | #toast-container.toast-bottom-center > div { 150 | width: 300px; 151 | margin-left: auto; 152 | margin-right: auto; 153 | } 154 | #toast-container.toast-top-full-width > div, 155 | #toast-container.toast-bottom-full-width > div { 156 | width: 96%; 157 | margin-left: auto; 158 | margin-right: auto; 159 | } 160 | .toast { 161 | background-color: #030303; 162 | } 163 | .toast-success { 164 | background-color: #51A351; 165 | } 166 | .toast-error { 167 | background-color: #BD362F; 168 | } 169 | .toast-info { 170 | background-color: #2F96B4; 171 | } 172 | .toast-warning { 173 | background-color: #F89406; 174 | } 175 | .toast-progress { 176 | position: absolute; 177 | left: 0; 178 | bottom: 0; 179 | height: 4px; 180 | background-color: #000000; 181 | opacity: 0.4; 182 | -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40); 183 | filter: alpha(opacity=40); 184 | } 185 | /*Responsive Design*/ 186 | @media all and (max-width: 240px) { 187 | #toast-container > div { 188 | padding: 8px 8px 8px 50px; 189 | width: 11em; 190 | } 191 | #toast-container > div.rtl { 192 | padding: 8px 50px 8px 8px; 193 | } 194 | #toast-container .toast-close-button { 195 | right: -0.2em; 196 | top: -0.2em; 197 | } 198 | #toast-container .rtl .toast-close-button { 199 | left: -0.2em; 200 | right: 0.2em; 201 | } 202 | } 203 | @media all and (min-width: 241px) and (max-width: 480px) { 204 | #toast-container > div { 205 | padding: 8px 8px 8px 50px; 206 | width: 18em; 207 | } 208 | #toast-container > div.rtl { 209 | padding: 8px 50px 8px 8px; 210 | } 211 | #toast-container .toast-close-button { 212 | right: -0.2em; 213 | top: -0.2em; 214 | } 215 | #toast-container .rtl .toast-close-button { 216 | left: -0.2em; 217 | right: 0.2em; 218 | } 219 | } 220 | @media all and (min-width: 481px) and (max-width: 768px) { 221 | #toast-container > div { 222 | padding: 15px 15px 15px 50px; 223 | width: 25em; 224 | } 225 | #toast-container > div.rtl { 226 | padding: 15px 50px 15px 15px; 227 | } 228 | } -------------------------------------------------------------------------------- /dist/notice.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Toastr 3 | * Copyright 2012-2015 4 | * Authors: John Papa, Hans Fjällemark, and Tim Ferrell. 5 | * All Rights Reserved. 6 | * Use, reproduction, distribution, and modification of this code is subject to the terms and 7 | * conditions of the MIT license, available at http://www.opensource.org/licenses/mit-license.php 8 | * 9 | * ARIA Support: Greta Krafsig 10 | * 11 | * Project: https://github.com/CodeSeven/toastr 12 | */ 13 | /* global define */ 14 | (function (define) { 15 | define(['jquery'], function ($) { 16 | return (function () { 17 | var $container; 18 | var listener; 19 | var toastId = 0; 20 | var toastType = { 21 | error: 'error', 22 | info: 'info', 23 | success: 'success', 24 | warning: 'warning', 25 | desktopInfo: 'desktopInfo' 26 | }; 27 | 28 | var cssStyle = $(''); 29 | $("body").append(cssStyle); 30 | 31 | var toastr = { 32 | version: '2.1.5', 33 | getContainer: getContainer, 34 | options: {}, 35 | subscribe: subscribe, 36 | info: info, 37 | error: error, 38 | warning: warning, 39 | success: success, 40 | clear: clear, 41 | remove: remove, 42 | desktopInfo: desktopInfo 43 | }; 44 | 45 | var previousToast; 46 | 47 | return toastr; 48 | 49 | //////////////// 50 | 51 | function info(message, title, optionsOverride) { 52 | return notify({ 53 | type: toastType.info, 54 | iconClass: getOptions().iconClasses.info, 55 | message: message, 56 | optionsOverride: optionsOverride, 57 | title: title 58 | }); 59 | } 60 | 61 | function success(message, title, optionsOverride) { 62 | return notify({ 63 | type: toastType.success, 64 | iconClass: getOptions().iconClasses.success, 65 | message: message, 66 | optionsOverride: optionsOverride, 67 | title: title 68 | }); 69 | } 70 | 71 | function error(message, title, optionsOverride) { 72 | return notify({ 73 | type: toastType.error, 74 | iconClass: getOptions().iconClasses.error, 75 | message: message, 76 | optionsOverride: optionsOverride, 77 | title: title 78 | }); 79 | } 80 | 81 | function desktopInfo(message, title) { 82 | // 先检查浏览器是否支持 83 | if (!("Notification" in window)) { 84 | console.log("This browser does not support desktop notification"); 85 | return; 86 | } 87 | 88 | // 检查用户是否同意接受通知 89 | else if (Notification.permission == "granted" || Notification.permission == "default") { 90 | let title_ = title ? title : '您有新的消息'; 91 | let notice_ = new Notification(title_, { 92 | body: message, 93 | icon: getOptions().iconClasses.info, 94 | }); 95 | notice_.onclick = function () {//单击消息提示框,进入浏览器页面 96 | window.focus(); 97 | }; 98 | } 99 | // 否则我们需要向用户获取权限 100 | else if (Notification.permission !== 'denied') { 101 | Notification.requestPermission(function (permission) { 102 | // 如果用户同意,就可以向他们发送通知 103 | if (permission === "granted") { 104 | let title_ = title ? title : '您有新的消息'; 105 | let notice_ = new Notification(title_, { 106 | body: message, 107 | icon: getOptions().iconClasses.info, 108 | }); 109 | notice_.onclick = function () {//单击消息提示框,进入浏览器页面 110 | window.focus(); 111 | }; 112 | } 113 | }); 114 | } 115 | return; 116 | } 117 | 118 | function warning(message, title, optionsOverride) { 119 | return notify({ 120 | type: toastType.warning, 121 | iconClass: getOptions().iconClasses.warning, 122 | message: message, 123 | optionsOverride: optionsOverride, 124 | title: title 125 | }); 126 | } 127 | 128 | function clear($toastElement, clearOptions) { 129 | var options = getOptions(); 130 | if (!$container) { getContainer(options); } 131 | if (!clearToast($toastElement, options, clearOptions)) { 132 | clearContainer(options); 133 | } 134 | } 135 | 136 | function remove($toastElement) { 137 | var options = getOptions(); 138 | if (!$container) { getContainer(options); } 139 | if ($toastElement && $(':focus', $toastElement).length === 0) { 140 | removeToast($toastElement); 141 | return; 142 | } 143 | if ($container.children().length) { 144 | $container.remove(); 145 | } 146 | } 147 | 148 | // internal functions 149 | function getContainer(options, create) { 150 | if (!options) { options = getOptions(); } 151 | $container = $('#' + options.containerId); 152 | if ($container.length) { 153 | return $container; 154 | } 155 | if (create) { 156 | $container = createContainer(options); 157 | } 158 | return $container; 159 | } 160 | 161 | function subscribe(callback) { 162 | listener = callback; 163 | } 164 | 165 | function clearContainer(options) { 166 | var toastsToClear = $container.children(); 167 | for (var i = toastsToClear.length - 1; i >= 0; i--) { 168 | clearToast($(toastsToClear[i]), options); 169 | } 170 | } 171 | 172 | function clearToast($toastElement, options, clearOptions) { 173 | var force = clearOptions && clearOptions.force ? clearOptions.force : false; 174 | if ($toastElement && (force || $(':focus', $toastElement).length === 0)) { 175 | $toastElement[options.hideMethod]({ 176 | duration: options.hideDuration, 177 | easing: options.hideEasing, 178 | complete: function () { removeToast($toastElement); } 179 | }); 180 | return true; 181 | } 182 | return false; 183 | } 184 | 185 | function createContainer(options) { 186 | $container = $('
') 187 | .attr('id', options.containerId) 188 | .addClass(options.positionClass); 189 | 190 | $container.appendTo($(options.target)); 191 | return $container; 192 | } 193 | 194 | function getDefaults() { 195 | return { 196 | tapToDismiss: true, 197 | toastClass: 'toast', 198 | containerId: 'toast-container', 199 | debug: false, 200 | 201 | showMethod: 'fadeIn', //fadeIn, slideDown, and show are built into jQuery 202 | showDuration: 300, 203 | showEasing: 'swing', //swing and linear are built into jQuery 204 | onShown: undefined, 205 | hideMethod: 'fadeOut', 206 | hideDuration: 1000, 207 | hideEasing: 'swing', 208 | onHidden: undefined, 209 | closeMethod: false, 210 | closeDuration: false, 211 | closeEasing: false, 212 | closeOnHover: true, 213 | 214 | extendedTimeOut: 1000, 215 | iconClasses: { 216 | error: 'toast-error', 217 | info: 'toast-info', 218 | success: 'toast-success', 219 | warning: 'toast-warning' 220 | }, 221 | iconClass: 'toast-info', 222 | positionClass: 'toast-top-right', 223 | timeOut: 5000, // Set timeOut and extendedTimeOut to 0 to make it sticky 224 | titleClass: 'toast-title', 225 | messageClass: 'toast-message', 226 | escapeHtml: false, 227 | target: 'body', 228 | closeHtml: '', 229 | closeClass: 'toast-close-button', 230 | newestOnTop: true, 231 | preventDuplicates: false, 232 | progressBar: false, 233 | progressClass: 'toast-progress', 234 | rtl: false 235 | }; 236 | } 237 | 238 | function publish(args) { 239 | if (!listener) { return; } 240 | listener(args); 241 | } 242 | 243 | function notify(map) { 244 | var options = getOptions(); 245 | var iconClass = map.iconClass || options.iconClass; 246 | 247 | if (typeof (map.optionsOverride) !== 'undefined') { 248 | options = $.extend(options, map.optionsOverride); 249 | iconClass = map.optionsOverride.iconClass || iconClass; 250 | } 251 | 252 | if (shouldExit(options, map)) { return; } 253 | 254 | toastId++; 255 | 256 | $container = getContainer(options, true); 257 | 258 | var intervalId = null; 259 | var $toastElement = $('
'); 260 | var $titleElement = $('
'); 261 | var $messageElement = $('
'); 262 | var $progressElement = $('
'); 263 | var $closeElement = $(options.closeHtml); 264 | var progressBar = { 265 | intervalId: null, 266 | hideEta: null, 267 | maxHideTime: null 268 | }; 269 | var response = { 270 | toastId: toastId, 271 | state: 'visible', 272 | startTime: new Date(), 273 | options: options, 274 | map: map 275 | }; 276 | 277 | personalizeToast(); 278 | 279 | displayToast(); 280 | 281 | handleEvents(); 282 | 283 | publish(response); 284 | 285 | if (options.debug && console) { 286 | console.log(response); 287 | } 288 | 289 | return $toastElement; 290 | 291 | function escapeHtml(source) { 292 | if (source == null) { 293 | source = ''; 294 | } 295 | 296 | return source 297 | .replace(/&/g, '&') 298 | .replace(/"/g, '"') 299 | .replace(/'/g, ''') 300 | .replace(//g, '>'); 302 | } 303 | 304 | function personalizeToast() { 305 | setIcon(); 306 | setTitle(); 307 | setMessage(); 308 | setCloseButton(); 309 | setProgressBar(); 310 | setRTL(); 311 | setSequence(); 312 | setAria(); 313 | } 314 | 315 | function setAria() { 316 | var ariaValue = ''; 317 | switch (map.iconClass) { 318 | case 'toast-success': 319 | case 'toast-info': 320 | ariaValue = 'polite'; 321 | break; 322 | default: 323 | ariaValue = 'assertive'; 324 | } 325 | $toastElement.attr('aria-live', ariaValue); 326 | } 327 | 328 | function handleEvents() { 329 | if (options.closeOnHover) { 330 | $toastElement.hover(stickAround, delayedHideToast); 331 | } 332 | 333 | if (!options.onclick && options.tapToDismiss) { 334 | $toastElement.click(hideToast); 335 | } 336 | 337 | if (options.closeButton && $closeElement) { 338 | $closeElement.click(function (event) { 339 | if (event.stopPropagation) { 340 | event.stopPropagation(); 341 | } else if (event.cancelBubble !== undefined && event.cancelBubble !== true) { 342 | event.cancelBubble = true; 343 | } 344 | 345 | if (options.onCloseClick) { 346 | options.onCloseClick(event); 347 | } 348 | 349 | hideToast(true); 350 | }); 351 | } 352 | 353 | if (options.onclick) { 354 | $toastElement.click(function (event) { 355 | options.onclick(event); 356 | hideToast(); 357 | }); 358 | } 359 | } 360 | 361 | function displayToast() { 362 | $toastElement.hide(); 363 | 364 | $toastElement[options.showMethod]( 365 | { duration: options.showDuration, easing: options.showEasing, complete: options.onShown } 366 | ); 367 | 368 | if (options.timeOut > 0) { 369 | intervalId = setTimeout(hideToast, options.timeOut); 370 | progressBar.maxHideTime = parseFloat(options.timeOut); 371 | progressBar.hideEta = new Date().getTime() + progressBar.maxHideTime; 372 | if (options.progressBar) { 373 | progressBar.intervalId = setInterval(updateProgress, 10); 374 | } 375 | } 376 | } 377 | 378 | function setIcon() { 379 | if (map.iconClass) { 380 | $toastElement.addClass(options.toastClass).addClass(iconClass); 381 | } 382 | } 383 | 384 | function setSequence() { 385 | if (options.newestOnTop) { 386 | $container.prepend($toastElement); 387 | } else { 388 | $container.append($toastElement); 389 | } 390 | } 391 | 392 | function setTitle() { 393 | if (map.title) { 394 | var suffix = map.title; 395 | if (options.escapeHtml) { 396 | suffix = escapeHtml(map.title); 397 | } 398 | $titleElement.append(suffix).addClass(options.titleClass); 399 | $toastElement.append($titleElement); 400 | } 401 | } 402 | 403 | function setMessage() { 404 | if (map.message) { 405 | var suffix = map.message; 406 | if (options.escapeHtml) { 407 | suffix = escapeHtml(map.message); 408 | } 409 | $messageElement.append(suffix).addClass(options.messageClass); 410 | $toastElement.append($messageElement); 411 | } 412 | } 413 | 414 | function setCloseButton() { 415 | if (options.closeButton) { 416 | $closeElement.addClass(options.closeClass).attr('role', 'button'); 417 | $toastElement.prepend($closeElement); 418 | } 419 | } 420 | 421 | function setProgressBar() { 422 | if (options.progressBar) { 423 | $progressElement.addClass(options.progressClass); 424 | $toastElement.prepend($progressElement); 425 | } 426 | } 427 | 428 | function setRTL() { 429 | if (options.rtl) { 430 | $toastElement.addClass('rtl'); 431 | } 432 | } 433 | 434 | function shouldExit(options, map) { 435 | if (options.preventDuplicates) { 436 | if (map.message === previousToast) { 437 | return true; 438 | } else { 439 | previousToast = map.message; 440 | } 441 | } 442 | return false; 443 | } 444 | 445 | function hideToast(override) { 446 | var method = override && options.closeMethod !== false ? options.closeMethod : options.hideMethod; 447 | var duration = override && options.closeDuration !== false ? 448 | options.closeDuration : options.hideDuration; 449 | var easing = override && options.closeEasing !== false ? options.closeEasing : options.hideEasing; 450 | if ($(':focus', $toastElement).length && !override) { 451 | return; 452 | } 453 | clearTimeout(progressBar.intervalId); 454 | return $toastElement[method]({ 455 | duration: duration, 456 | easing: easing, 457 | complete: function () { 458 | removeToast($toastElement); 459 | clearTimeout(intervalId); 460 | if (options.onHidden && response.state !== 'hidden') { 461 | options.onHidden(); 462 | } 463 | response.state = 'hidden'; 464 | response.endTime = new Date(); 465 | publish(response); 466 | } 467 | }); 468 | } 469 | 470 | function delayedHideToast() { 471 | if (options.timeOut > 0 || options.extendedTimeOut > 0) { 472 | intervalId = setTimeout(hideToast, options.extendedTimeOut); 473 | progressBar.maxHideTime = parseFloat(options.extendedTimeOut); 474 | progressBar.hideEta = new Date().getTime() + progressBar.maxHideTime; 475 | } 476 | } 477 | 478 | function stickAround() { 479 | clearTimeout(intervalId); 480 | progressBar.hideEta = 0; 481 | $toastElement.stop(true, true)[options.showMethod]( 482 | { duration: options.showDuration, easing: options.showEasing } 483 | ); 484 | } 485 | 486 | function updateProgress() { 487 | var percentage = ((progressBar.hideEta - (new Date().getTime())) / progressBar.maxHideTime) * 100; 488 | $progressElement.width(percentage + '%'); 489 | } 490 | } 491 | 492 | function getOptions() { 493 | return $.extend({}, getDefaults(), toastr.options); 494 | } 495 | 496 | function removeToast($toastElement) { 497 | if (!$container) { $container = getContainer(); } 498 | if ($toastElement.is(':visible')) { 499 | return; 500 | } 501 | $toastElement.remove(); 502 | $toastElement = null; 503 | if ($container.children().length === 0) { 504 | $container.remove(); 505 | previousToast = undefined; 506 | } 507 | } 508 | 509 | })(); 510 | }); 511 | }(typeof define === 'function' && define.amd ? define : function (deps, factory) { 512 | if (typeof module !== 'undefined' && module.exports) { //Node 513 | module.exports = factory(require('jquery')); 514 | } 515 | else if (window.layui && layui.define) { 516 | layui.define('jquery', function (exports) { //layui加载 517 | exports('toastr', factory(layui.jquery)); 518 | exports('notice', factory(layui.jquery)); 519 | }); 520 | } 521 | else { 522 | window.toastr = factory(window.jQuery); 523 | } 524 | })); --------------------------------------------------------------------------------