原生JS实现可配置弹窗插件完整代码与解析

作者:木棉

时间:2026-10-27

浏览:420

本文分享一个基于原生JavaScript实现的轻量级弹窗插件。该组件支持IE6+及主流浏览器,提供标题、内容(文本、图片、ID节点、iframe)、尺寸、拖拽、自动关闭、遮罩层及回调函数等丰富配置。代码包含完整的HTML结构、CSS样式及JS逻辑,旨在帮助开发者快速集成自定义弹窗功能。

文章目录

弹窗插件功能概述与兼容性

经测试,该组件兼容IE6及以上版本,以及Firefox、Chrome等主流浏览器。

核心配置参数详解

首先介绍该组件的核心配置参数,具体列表如下。

核心配置代码如下:

this.config = {
targetCls : '.clickElem', // 触发点击的元素类名
 title: '我是龙恩', // 弹窗标题
 content : 'text:<p style="width:100px;height:100px">我是龙</p>',
 //content : 'img:http://www.baidu.com/a.jpg',
// 窗口内容格式 {text:文本内容 | id:节点ID | img:图片地址 | 
 // iframe:iframe地址} {string} 
 width: 400, // 内容区域宽度
 height : 300, // 内容区域高度
 theight : 30,// 标题栏高度,默认值30
 drag : true, // 是否允许拖拽,默认true
 time : 3000, // 自动关闭时间(毫秒),若为空或'undefined'则不自动关闭
 showBg : true, // 是否显示遮罩层,默认true
 closable : '#window-close', // 关闭按钮的选择器
 bgColor : '#000', // 遮罩层背景色
 opacity : 0.5,// 遮罩层透明度
 position : {
 x: 0,
 y: 0 // 默认值为0,表示居中显示
 },
 zIndex : 10000,
 isScroll : true, // 默认情况下,弹窗随页面滚动而滚动
 isResize : true, // 默认情况下,弹窗随窗口缩放而调整位置
 callback : null// 弹窗显示后的回调函数
    };

JS编写简单的弹窗插件(含有demo和源码) 2013-12-11 22:30 by 龙恩0707, 409 阅读, 1 评论, 收藏, 编辑 最近项目做完了 事情不是很多,今天正好也在调休,所以趁着这个时间研究了一下简易的JS弹窗功能,当然网上这块插件非常多,本人也没有仔细看网上的插件源码 只是凭着日常使用过的弹窗插件有这么多功能 来实现自己的弹窗思路,当然我这个可能实现了基本功能,那么如果想做的更好 更完善需要以后继续优化!如果有不足之处!请大家多多谅解!

由于弹窗的基本形态大家已很熟悉,此处省略演示效果图。经测试,该组件兼容IE6及以上版本,以及Firefox、Chrome等主流浏览器。

首先介绍该组件的核心配置参数,具体列表如下。

按 Ctrl+C 复制代码

按 Ctrl+C 复制代码 1. 支持配置标题、内容、标题高度、内容宽高、是否允许拖拽、弹窗后是否自动关闭、是否显示遮罩背景、背景颜色及透明度,以及窗口展示位置。默认x轴0、y轴0为居中对齐,也可自行配置x轴和y轴位置,但需注意这是相对于父元素的坐标;若未指定父元素相对定位,则默认相对于document。建议窗口内容宽高不要超过浏览器一屏的尺寸,尽量小于第一屏宽高,因为曾遇到使用其他插件时,内容过大导致关闭按钮因滚动条事件无法点击的问题。若内容宽高很大,窗口会自动出现滚动条。

2. 窗口内容配置支持四种类型:1.text(文本),配置示例如下:text:<p style="width:100px;height:100px">我是龙恩</p>

2. img(图片),配置示例如下:img:http://www.baidu.com/a.jpg

3. id(节点ID),配置示例如下:'id:XX'

4. iframe,配置示例如下:'iframe:http://www.baidu.com(iframe地址)'

3. 提供弹窗显示后的回调函数,以便在弹窗展示后执行自定义操作。

该弹窗组件功能基础,若需应用于项目,CSS样式可自行重写。JS部分仅实现基本弹窗业务逻辑,未写死样式。

HTML与CSS结构实现

HTML结构代码如下:

HTML代码如下:

<div class="clickElem" style="margin-top:10px;">我是龙恩 请点击我</div>
<div class="clickElem" style="margin-top:10px;">我是龙恩 请点击我</div>

CSS样式代码如下

CSS代码如下:

<style type="text/css">
*{margin:0;padding:0;list-style-type:none;}
a,img{border:0;}
body{font:12px/180% Arial, Helvetica, sans-serif;}
label{cursor:pointer;}
#window-box{border:5px solid #E9F3FD;background:#FFF;}
.windown-title{position:relative;height:30px;border:1px solid #A6C9E1;overflow:hidden;background:url(images/tipbg.png) 0 0 repeat-x;}
.window-title h2{padding-left:5px;font-size:14px;color:#666;}
#window-close{position:absolute;right:10px;top:8px;width:10px;height:16px;text-indent:-10em;overflow:hidden;background:url(images/tipbg.png) 100% -49px no-repeat;cursor:pointer;}
#window-content-border{padding:5px 0 5px 5px;}
</style>

JavaScript核心逻辑与源码解析

JS核心逻辑代码如下

JS代码如下:

/**
* 编写JS弹窗组件
* @date 2013-12-10
* @author tugenhua
* @email 879083421@qq.com
 */
function Overlay(options){
 this.config = {
targetCls : '.clickElem', // 触发点击的元素类名
 title: '我是龙恩', // 弹窗标题
 content : 'text:<p style="width:100px;height:100px">我是龙恩</p>',
 //content : 'img:http://gtms01.alicdn.com/tps/i1/T1USkqFc0dXXb5rXb6-1060-300.jpg',
 // 窗口内容格式 {text:文本内容 | id:节点ID | img:图片地址 | 
 // iframe:iframe地址} {string} 
 width: 400, // 内容区域宽度
 height : 300, // 内容区域高度
 theight : 30,// 标题栏高度,默认值30
 drag : true, // 是否允许拖拽,默认true
 time : 3000, // 自动关闭时间(毫秒),若为空或'undefined'则不自动关闭
 showBg : true, // 是否显示遮罩层,默认true
 closable : '#window-close', // 关闭按钮的选择器
 bgColor : '#000', // 遮罩层背景色
 opacity : 0.5,// 遮罩层透明度
 position : {
 x: 0,
 y: 0 // 默认值为0,表示居中显示
 },
 zIndex : 10000,
 isScroll : true, // 默认情况下,弹窗随页面滚动而滚动
 isResize : true, // 默认情况下,弹窗随窗口缩放而调整位置
 callback : null// 弹窗显示后的回调函数
    };
this.cache = {
 isrender : true, // 弹窗HTML结构只渲染一次
 isshow: false, // 窗口是否已经显示出来
 moveable : false
 };
this.init(options);
 }
Overlay.prototype = {
 constructor: Overlay,
 init: function(options){
 this.config = $.extend(this.config,options || {});
 var self = this,
 _config = self.config,
 _cache = self.cache;
 $(_config.targetCls).each(function(index,item){
 $(item).unbind('click');
 $(item).bind('click',function(){
// 渲染弹窗HTML结构
 self._renderHTML();
 // 窗口移动功能
 self._windowMove();
 });
 });
 // 窗口缩放处理
 self._windowResize('#window-box');
// 窗口随滚动条滚动处理
 self._windowIsScroll('#window-box');
},
 /*
 * 渲染弹窗HTML结构
 */
 _renderHTML: function(){
 var self = this,
 _config = self.config,
 _cache = self.cache;
 var html ='';
 if(_cache.isrender) {
html+= '<div id="windowbg" style="display:none;position:absolute;top:0;left:0;"></div>' + 
 '<div id="window-box" style="display:none;overflow:hidden;">' +
 '<div class="window-title"><h2></h2><span id="window-close">关闭</span></div>'+
 '<div id="window-content-border"><div id="window-content"></div></div>' + 
 '</div>';
 $('body').append(html);
 $("#windowbg").css('z-index',_config.zIndex);
 $('#window-content-border').css({'width':_config.width + 'px','height':_config.height + 'px','overflow':'auto'});
 $('.window-title h2').html(_config.title);
 $('.window-title').css({'height':_config.theight + 'px','width':_config.width,'overflow':'hidden'});
 _cache.isrender = false;
 // 判断传递进来的内容格式
 self._contentType();
 if(_config.showBg) {
 // 渲染背景宽度和高度
 self._renderDocHeight();
 $("#windowbg").show();
 self.show();
 }else {
 $("#windowbg").hide();
 self.show();
 }
 self._showDialogPosition("#window-box");
 }else {
 // 如果弹窗已经创建出来的话, 只是隐藏掉了, 那么我们显示出来
 self.show();
 $("#windowbg").animate({"opacity":_config.opacity},'normal');
 if(_config.showBg) {
 $("#windowbg").show();
 }
 self._showDialogPosition("#window-box");
 }
 $(_config.closable).unbind('click');
 $(_config.closable).bind('click',function(){
 // 点击关闭按钮
 self._closed();
 });
// 渲染后 回调函数
 _config.callback && $.isFunction(_config.callback) && _config.callback();
 },
 /**
 * 显示弹窗
 */
 show: function(){
 var self = this,
 _config = self.config,
 _cache = self.cache;
 $("#window-box") && $("#window-box").show();
 _cache.isshow = true;
 if(_config.time == '' || typeof _config.time == 'undefined') {
 return;
 }else {
 t && clearTimeout(t);
 var t = setTimeout(function(){
 self._closed();
 },_config.time);
 }
 },
 /**
 * 隐藏弹窗
 */
 hide: function(){
 var self = this,
 _cache = self.cache;
 $("#window-box") && $("#window-box").hide();
 _cache.isshow = false;
 },
 /**
 * 判断传进来的内容类型
 */
 _contentType: function(){
 var self = this,
 _config = self.config,
 _cache = self.cache;
var contentType = _config.content.substring(0,_config.content.indexOf(":")),
 content = _config.content.substring(_config.content.indexOf(":")+1,_config.content.length);
 switch(contentType) {
 case 'text': 
 $('#window-content').html(content);
 break;
case 'id':
 $('#window-content').html($('#'+content).html());
 break;
case 'img':
 $('#window-content').html("<img src='"+content+"' class='window-img'/>");
 break;
case 'iframe':
 $('#window-content').html('<iframe src="'+content+'" width="100%" height="100%" scrolling="yes" frameborder="0"></iframe>');
 $("#window-content-border").css({'overflow':'visible'});
 break;
 }
 },
 /**
 * 点击关闭按钮
 */
 _closed: function(){
 var self = this,
 _config = self.config,
 _cache = self.cache;
 if(_cache.isshow) {
 self.hide();
 }
 if(_config.showBg) {
 $("#windowbg").hide();
 }
 $("#windowbg").animate({"opacity":0},'normal');
 },
 /**
 * 显示弹窗的位置 默认情况下居中
 */
 _showDialogPosition: function(container) {
 var self = this,
 _config = self.config,
 _cache = self.cache;
 $(container).css({'position':'absolute','z-index':_config.zIndex + 1});
 var offsetTop = Math.floor(($(window).height() - $(container).height())/2) + $(document).scrollTop(),
 offsetLeft = Math.floor(($(window).width() - $(container).width())/2) + $(document).scrollLeft();
// 判断x,y位置默认是不是等于0 如是的话 居中 否则 根据传进来的位置重新定位
 if(0 === _config.position.x && 0 === _config.position.y){
$(container).offset({'top':offsetTop, 'left':offsetLeft});
 }else{
 $(container).offset({'top':_config.position.y,'left':_config.position.x});
 }
 },
 /**
 * 渲染底部背景的高度
 */
 _renderDocHeight: function(){
 var self = this,
 _config = self.config;
 $("#windowbg").animate({"opacity":_config.opacity},'normal');
 if(self._isIE6()){
 $("#windowbg").css({'background':'#fff','height':$(document).height()+'px','width':$(document).width()+"px"});
 }else {
 $("#windowbg").css({'background':_config.bgColor,'height':$(document).height()+'px','width':$(document).width()+"px"});
 }
 },
 /*
* 窗口缩放
*/
 _windowResize: function(elem){
 var self = this,
 _config = self.config;
 $(window).unbind('resize');
 $(window).bind('resize',function(){
 t && clearTimeout(t);
 var t = setTimeout(function(){
 if(_config.isResize){
self._showDialogPosition(elem);
self._renderDocHeight();
 }
 },200);
 });
 },
 /**
 * 窗口是否随着滚动条一起滚动
 */
 _windowIsScroll: function(elem){
 var self = this,
 _config = self.config;
 $(window).unbind('scroll');
 $(window).bind('scroll',function(){
 t && clearTimeout(t);
 var t = setTimeout(function(){
 if(_config.isScroll){
self._showDialogPosition(elem);
self._renderDocHeight();
 }
 },200);
 });
 },
 /**
 * 窗口移动
 */
 _windowMove: function(){
 var self = this,
 _config = self.config,
 _cache = self.cache;
 var mouseX = 0,
 mouseY = 0;
 $('.window-title').mouseenter(function(){
 $(this).css({'cursor':'move'});
 });
 $('.window-title').mouseleave(function(){
 $(this).css({'cursor':'default'});
 });
 $('.window-title').mousedown(function(e){
 _cache.moveable = true;
 mouseX = e.clientX - $(this).offset().left;
 mouseY = e.clientY - $(this).offset().top;
 $('.window-title').css({'cursor':'move'});
 });
 $(document).mouseup(function(){
 if(!_cache.moveable) {
 return;
 }
 $('.window-title').css({'cursor':'default'});
 _cache.moveable = false;
 });
 $('#window-box').mousemove(function(e){
 if(_cache.moveable) {
 $(this).css({'left':e.clientX - mouseX + 'px','top':e.clientY - mouseY + 'px'});
 }
 });
},
 /*
 * 判断是否是IE6游览器
 * @return {Boolean}
 */
 _isIE6: function(){
 return navigator.userAgent.match(/MSIE 6.0/)!= null;
 }
 };

 

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章