原生js实现自定义alert风格和实现
2018年6月29 最新更新
添加函数节流,解决多次点击问题,添加单例模式,提高代码性能。
<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<title>自定义alert</title>
<style type="text/css">
html,
body {
padding: ;
margin: ;
}
/* //防止鼠标双击选中文字
*/ div { -khtml-user-select: none;
/*早期浏览器*/
user-select: none;
}
/* //来自animated.css的样式 */ .animated {
animation-duration: 1s;
animation-fill-mode: both;
} @keyframes bounceInDown {
from,
%,
%,
%,
to {
animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
} % {
opacity: ;
transform: translate3d(, -3000px, );
} % {
opacity: ;
transform: translate3d(, 25px, );
} % {
transform: translate3d(, -10px, );
} % {
transform: translate3d(, 5px, );
} to {
transform: none;
display: none;
}
} .bounceInDown {
animation-name: bounceInDown;
} </style>
</head> <body>
<button onclick="test" id="btn">点我测试</button>
<script type="text/javascript">
(function(win, doc) {
var firstTime = true,
startTime = ; function alert(txt, autoTime, top) {
//工具函数
function $(dom) {
return document.querySelector(dom);
}
//单利模式核心
var getSingle = function(fn) {
var result;
return function() {
return (result || (result = fn.apply(this, arguments)));
}
} //函数节流
var throttle = function(fn, interval) {
var __self = fn; // 保存需要被延迟执行的函数引用// 是否是第一次调用
return function() {
var args = arguments,
__me = this;
if (firstTime) { // 如果是第一次调用,不需延迟执行
__self.apply(__me, args);
return firstTime = false;
} var endTime = new Date() * ; //时间大于3000秒下次执行
if (endTime - startTime > (autoTime || )) {
__self.apply(__me, args);
}
};
}; //创建div代码
var createDiv = function() { var div = doc.createElement("div");
div.style.backgroundColor = " #22b9ff";
div.style.color = " #fff";
div.style.position = " fixed";
div.style.zIndex = ;
div.style.height = " 60px";
div.style.top = top || "10%";
div.style.left = "50%";
div.style.lineHeight = " 60px";
div.style.borderRadius = " 4px";
div.style.fontSize = " 20px";
div.style.textAlign = "center";
div.style.padding = "0 10px";
div.className = "animated bounceInDown";
div.id = "alert";
div.innerHTML = txt || "不能为空!";
return div;
} var createSingleDiv = getSingle(createDiv); return throttle(function() { var div = createSingleDiv(); //创建div
startTime = new Date() * ; //初始位置
$("body").appendChild(div);
//动态调整位置
var alertWidth = win.getComputedStyle($("#alert"), null).width;
div.style.marginLeft = -parseInt(alertWidth) / + "px";
setTimeout(function() {
$("body").removeChild(div);
}, autoTime || );
}).apply(this, null);
} win.alert = alert; //导出 })(window, document); document.getElementById('btn').onclick = function() {
alert("手机号不能为空!");
} </script>
</body> </html>
上篇文章介绍了自定义confirm的必要性,可以说alert是比confirm更为常用的浏览器自带组件了。但更因为常用,而原生组件无论是样式还是体验都不是很好,所以更加有必要自定义。
此为改造的背景。
本来第一版是自定义的第一版是没有防止提示期间,用户进行其他操作的透明层的;js代码是这样:
<script type="text/javascript">
window.alert = function(text) { //实现alert
var div = document.createElement("div");
div.style.backgroundColor = " #22b9ff";
div.style.color = " #fff";
div.style.position = " fixed";
div.style.zIndex = 9999999;
div.style.height = " 60px";
div.style.top = " 10%";
div.style.left = "50%";
div.style.lineHeight = " 60px";
div.style.borderRadius = " 4px";
div.style.fontSize = " 20px";
div.style.textAlign = "center";
div.style.padding = "0 10px";
div.className = "animated bounceInDown";
div.id = "alert";
div.innerHTML = text;
document.getElementsByTagName("body")[0].appendChild(div);
var selfObj = document.getElementById("alert");
//动态调整位置
var alertWidth = window.getComputedStyle(selfObj, null).width;
div.style.marginLeft = -parseInt(alertWidth) / 2 + "px";
setTimeout(function() {
document.getElementsByTagName("body")[0].removeChild(div);
}, 30000);
}
alert("这是自定义的alert");
</script>
后来想到实际的alert效果,提示期间是无法做其它操作的,于是改造为这样
<script type="text/javascript">
window.alert = function(text) {
//透明遮罩层
var mask = document.createElement("div");
mask.style.position = " fixed";
mask.style.zIndex = 1000000;
mask.style.top = 0;
mask.style.bottom = 0;
mask.style.left = 0;
mask.style.right = 0;
//实现alert
var div = document.createElement("div");
div.style.backgroundColor = " #22b9ff";
div.style.color = " #fff";
div.style.position = " fixed";
div.style.zIndex = 9999999;
div.style.height = " 60px";
div.style.top = " 10%";
div.style.left = "50%";
div.style.lineHeight = " 60px";
div.style.borderRadius = " 4px";
div.style.fontSize = " 20px";
div.style.textAlign = "center";
div.style.padding = "0 10px";
div.className = "animated bounceInDown";
div.id = "alert";
div.innerHTML = text;
document.getElementsByTagName("body")[0].appendChild(div);
document.getElementsByTagName("body")[0].appendChild(mask);
var selfObj = document.getElementById("alert");
//动态调整位置
var alertWidth = window.getComputedStyle(selfObj, null).width;
div.style.marginLeft = -parseInt(alertWidth) / 2 + "px";
setTimeout(function() {
document.getElementsByTagName("body")[0].removeChild(div);
document.getElementsByTagName("body")[0].removeChild(mask);
}, 3000);
}
alert("这是自定义的alert");
</script>
值得一提的是动态位置的调整哪块,通过实时计算alert组件的宽度,保证组件始终处于中间位置,至于alert组件的显示时间,就自己改源代码时间吧。
整体代码如下
<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<title>自定义alert</title>
<style type="text/css">
html,
body {
padding: ;
margin: ;
}
/* //防止鼠标双击选中文字
*/ div { -khtml-user-select: none;
/*早期浏览器*/
user-select: none;
}
/* //来自animated.css的样式 */ .animated {
animation-duration: 1s;
animation-fill-mode: both;
} @keyframes bounceInDown {
from,
%,
%,
%,
to {
animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
} % {
opacity: ;
transform: translate3d(, -3000px, );
} % {
opacity: ;
transform: translate3d(, 25px, );
} % {
transform: translate3d(, -10px, );
} % {
transform: translate3d(, 5px, );
} to {
transform: none;
}
} .bounceInDown {
animation-name: bounceInDown;
} </style>
</head> <body>
<script type="text/javascript">
(function(win,doc) {
var alert = function(text, time, top) {
text = text || "确定删除?",time = time || ,top = top || "10%";//增加默认值,增强健壮性
var body=doc.getElementsByTagName("body")[];//优化dom
//实现alert
var div = doc.createElement("div");
div.style.backgroundColor = " #22b9ff";
div.style.color = " #fff";
div.style.position = " fixed";
div.style.zIndex = ;
div.style.height = " 60px";
div.style.top = top;
div.style.left = "50%";
div.style.lineHeight = " 60px";
div.style.borderRadius = " 4px";
div.style.fontSize = " 20px";
div.style.textAlign = "center";
div.style.padding = "0 10px";
div.className = "animated bounceInDown";
div.id = "alert";
div.innerHTML = text;
body.appendChild(div);
var selfObj = doc.getElementById("alert");
//动态调整位置
var alertWidth = win.getComputedStyle(selfObj, null).width;
div.style.marginLeft = -parseInt(alertWidth) / + "px";
setTimeout(function() {
body.removeChild(div);
}, time);
}
win.alert=alert;//导出
})(window,document);
alert();
</script>
</body> </html>
2018年6月24日更新 增加参数的默认值,该少dom访问慢的问题,使用闭包包裹,alert导出覆盖window
在整体代码中,有一个用来防止双击选中文字的css样式,值得关注一下。
样式中的css动画来自知名的动画库animation.css。因此,可以根据实际业务需要更换动画类。基本就是这样。
仿京东注册web移动端提示。
<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<title>自定义alert</title>
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0,user-scalable=no" name="viewport" />
<style type="text/css">
html,
body {
padding: ;
margin: ;
}
/* //防止鼠标双击选中文字
*/ div { -khtml-user-select: none;
/*早期浏览器*/
user-select: none;
}
/* //来自animated.css的样式 */ @-webkit-keyframes fadeIn {
% {
opacity: .
}
% {
opacity:
}
% {
opacity: .
}
} .toast {
-webkit-animation-name: fadeIn;
-webkit-animation-duration: 3s;
-webkit-animation-iteration-count: ;
-webkit-animation-delay: 0s;
-webkit-transition: all .3s ease;
-moz-transition: all .3s ease;
transition: all .3s ease;
max-width: %;
color:#fff;
background: #2B2B2B;
padding: 8px 15px;
display: inline-table;
border-radius: 3px;
} .toast-ui {
position: fixed;
top:%;
color:#fff;
width: %;
text-align: center;
} .maskfadeout {
display: block;
-webkit-animation: fadeout 3s linear;
animation: fadeout 3s linear;
-webkit-animation-iteration-count: ;
animation-iteration-count:
} @-webkit-keyframes fadeout {
%,
% {
opacity:
}
% {
opacity:
}
} @keyframes fadeout {
%,
% {
opacity:
}
% {
opacity:
}
}
</style>
</head> <body>
<script type="text/javascript">
(function(win, doc) {
var alert = function(text, time, top) {
text = text || "确定删除?", time = time || , top = top || "10%"; //增加默认值,增强健壮性
var body = doc.getElementsByTagName("body")[]; //优化dom
//实现alert
var div = doc.createElement("div");
div.className = "toast-ui maskfadeout";
div.id = "alert";
var span = doc.createElement("span");
span.innerHTML = text;
span.className = "toast";
div.appendChild(span);
body.appendChild(div); setTimeout(function() {
div.style.display="none";
}, );
}
win.alert = alert; //导出
})(window, document);
alert("是否删除这条评论?");
</script>
</body> </html>
本文结束。
原生js实现自定义alert风格和实现的更多相关文章
- 使用原生js创建自定义标签
使用原生js创建自定义标签 效果图 代码 <!DOCTYPE html> <html lang="en"> <head> <meta ch ...
- ios UIWebView自定义Alert风格的弹框
之前开发过一个App,因为公司之前写好了网页版的内容和安卓版本的App,我进去后老板要求我ios直接用网页的内容,而不需要自己再搭建框架.我一听,偷笑了,这不就是一个UIWebView吗?简单! 但是 ...
- Vue结合原生js实现自定义组件自动生成
就目前三大前端主流数据驱动框架(vue,ng,react)而言,均具有创建自定义组件的api,但都是必须先做到事先写好挂载点,这个挂载点可以是原有静态元素标签也可以是自定义模板:对于多种组件通过同一数 ...
- 原生js 自定义confirm
本文参考博客园另一篇文章:https://www.cnblogs.com/hzj680539/p/5374052.html,在此感谢. 在实际开发当中,考虑到原生js组件,包括alert.confir ...
- 使用原生js自定义内置标签
使用原生js自定义内置标签 效果图 代码 <!DOCTYPE html> <html lang="en"> <head> <meta ch ...
- 原生js拖拽、jQuery拖拽、vue自定义指令拖拽
原生js拖拽: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...
- 利用bootstrap的modal组件自定义alert,confirm和modal对话框
由于浏览器提供的alert和confirm框体验不好,而且浏览器没有提供一个标准的以对话框的形式显示自定义HTML的弹框函数,所以很多项目都会自定义对话框组件.本篇文章介绍自己在项目中基于bootst ...
- 原生JS 表单提交验证器
转载:http://www.cnblogs.com/sicd/p/4613628.html 一.前言 最近在开发一个新项目,需要做登陆等一系列的表单提交页面.在经过“缜密”的讨论后,我们决定 不用外部 ...
- 原生js dom记忆的内容
1.DOM基础getElementByIdgetElementByTagNamegetElementByName getElementsByClass querySelector querySelec ...
随机推荐
- Product Helper
using System; using Microsoft.Xrm.Sdk; using Microsoft.Crm.Sdk.Messages; /// <summary> /// 产品 ...
- centos install rabbitmq
安装rabbitmq 需要环境上有erlang,没有安装的可以参照下面的内容进行安装: https://www.erlang-solutions.com/resources/download.html ...
- Shuffling Machine
7-43 Shuffling Machine(20 分) Shuffling is a procedure used to randomize a deck of playing cards. Bec ...
- Nginx的try_files使用详解
try_files 语法: try_files file ... uri 或 try_files file ... = code 默认值: 无 作用域: server location 按顺序检查文件 ...
- 北京Uber优步司机奖励政策(11月16日~11月22日)
用户组:人民优步“关羽组”(适用于11月16日-11月22日)奖励政策: 滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/ ...
- Android Stadio配置了gralde的本地路径,但是windos 命令行还是会下载gradle
如下图: 已经在stadio 里面设置了gradle 的路径,但是在cmd 命令行里面不会去用这个路径. 解决方案:需要在环境变量里面设置一个gradle home GRADLE_USER_HOME ...
- Drupal 判断匿名用户必须先登录的解决方法
要实现如果是匿名用户点击checkout链接,要求先登录 方案一.通过添加Rules规则实现 EVENT:After adding a product to the cart Conditions : ...
- define的误用
#define LIGHT_SPEED 3e8 // m/sec (in a vacuum)
- 对Java对象的认识与理解
今天是我学习编程以来第一次写博客,记下平日学习所得,本来这几日都在学习web框架 但觉得梳理一下之前所学很有必要.毕竟之前学习Java感觉很粗略只是以考试为目的.所以就以<Thinking in ...
- 从零开始的Python学习Episode 6——字符串操作
字符串操作 一.输出重复字符串 print('smile'*6) #输出6个smile 二.通过引索输出部分字符串 print('smile'[1:]) print('smile'[1:3]) #输出 ...