【原生JS】仿新浪微博名片弹框
博客已经搬家地址:http://cm2009.sinaapp.com/
第一次用原生JS写小功能,有很多不足的地方,例如事件绑定没有使用事件委托功能,而是直接用零级DOM进行批量绑定,以及很多我自己不知道的不足。
这个弹框效果跟新浪微博的名片弹框效果差不多,可以随着相应事件的头像位置的不同而改变出现的位置,当发生事件的位置位于屏幕上方,则弹框从下弹出,反之亦;当事件发生时鼠标位于屏幕25%的左方,则弹框从右边弹出,反之亦,但是事件发生在左右的优先级高于发生在上下的优先级(即先判断左右,后判断上下)。
名片框的灰色边框使用的是一个半透明DIV层来模拟的,这个DIV与放置内容的DIV是在同一层的,所以他的半透明CSS效果不会对其他div造成影响,小箭头则是一张PNG-24图片,明显,PNG-24在IE6下肯定会很难看。
效果:
以下是这个名片框的js代码,可以拷贝到任何页面使用:
1 /******************************* 2 * 3 * 通用的NameCardBox小模块 4 * 5 *******************************/ 6 7 function NameCardBox() { 8 this.initialize.apply(this, arguments); 9 } 10 11 NameCardBox.prototype = { 12 /* 13 * targetObj:欲使用此名片功能的node节点的集合 14 * innerNode:在box中装入的节点集合 15 * width : 一个数字,描述提示框的宽度 16 * offsetFix : 小箭头的偏移量修正值 17 * 注意:targetObj与innerNode要按顺序一一对应 18 */ 19 initialize : function(targetObj, innerNode, width, offsetXFix, offsetYFix) { 20 var _this = this; 21 this.id = 'Info-preview-' + (new Date()).getTime(); 22 this.creatElement(); 23 this.wrapper = document.getElementById(this.id); 24 this.wrapper2 = this.wrapper.getElementsByTagName('div')[0]; 25 this.bg = this.wrapper.getElementsByTagName('div')[1]; 26 this.content = this.wrapper.getElementsByTagName('div')[2]; 27 this.arrow = this.wrapper.getElementsByTagName('div')[3]; 28 this.width = width + 'px'; 29 this.borderWidth = 4; 30 this.target = targetObj; 31 this.inner = innerNode; 32 this.directionFlag 33 this.direction = []; 34 this.timer = null; 35 this.option = { 36 'top' : '-1px', 37 'bottom' : '-23px', 38 'left' : '-45px', 39 'right' : '-70px' 40 }; 41 this.offsetXFix = offsetXFix || 0; 42 this.offsetYFix = offsetYFix || 0; 43 this.initCss(); 44 this.addEvent(this.directionFlag); 45 this.wrapper.onmouseover = function() { 46 _this.doKeep(); 47 } 48 this.wrapper.onmouseout = function() { 49 _this.doHide(); 50 } 51 }, 52 //创建box的HTML代码 53 creatElement : function(inner) { 54 var d = document; 55 var wrapper = d.createElement('div'); 56 var wrapper2 = d.createElement('div'); 57 var bg = d.createElement('div'); 58 var content = d.createElement('div'); 59 var arrow = d.createElement('div'); 60 content.innerHTML = "</ br></ br></ br></ br></ br></ br>"; 61 wrapper.setAttribute('id', this.id); 62 wrapper2.appendChild(bg); 63 wrapper2.appendChild(content); 64 wrapper2.appendChild(arrow); 65 wrapper.appendChild(wrapper2); 66 document.body.appendChild(wrapper); 67 }, 68 //计算箭头应该出现的方向以及box放置的方位 69 getDirection : function(event) { 70 var event = window.event || event; 71 var X = event.clientX; 72 var Y = event.clientY; 73 var screenH = screen.availHeight; 74 var screenW = screen.availWidth; 75 if(X / screenW < 0.25 || X / screenW >= 0.75) { 76 this.directionFlag = false; 77 } else { 78 this.directionFlag = true; 79 } 80 if(this.directionFlag === true) { 81 this.direction[0] = 'top'; 82 this.direction[1] = Y / screenH; 83 } else { 84 this.direction[0] = 'left'; 85 this.direction[1] = X / screenW; 86 } 87 }, 88 //为对象绑定box事件 89 addEvent : function() { 90 var _this = this; 91 var obj = this.target; 92 if( typeof obj === 'object' && typeof obj.length === 'number') { 93 for(var i = 0; i < obj.length; i++) { 94 obj[i].setAttribute('NameCard', i); 95 obj[i].onmouseover = function() { 96 _this.getDirection(event); 97 //第一次获取定位 98 _this.getPosition(this, _this);100 _this.content.innerHTML = _this.inner[this.getAttribute('NameCard')].innerHTML;101 //尝试显示102 _this.doShow(this);103 //获取修正后的定位104 _this.getPosition(this, _this);105 //再次显示106 _this.doShow(this);107 _this.doKeep();108 }109 obj[i].onmouseout = function() {110 _this.doHide();111 }112 }113 } else if( typeof obj == 'object' && !( obj instanceof Array)) {114 obj.onmouseover = function() {115 _this.getDirection(event);116 //第一次获取定位117 _this.getPosition(this, _this);118 _this.content.innerHTML = this.getAttribute('data');119 //尝试显示120 _this.doShow(this);121 //获取修正后的定位122 _this.getPosition(this, _this);123 //再次显示124 _this.doShow(this);125 _this.doKeep();126 }127 obj.onmouseout = function() {128 _this.doHide()129 };130 } else131 throw Error('type error!');132 },133 doShow : function(obj) {134 //第一次设置CSS,本次无法预知框的高度135 this.setCss(obj);136 this.wrapper.style.display = 'block';137 //根据实际情况修正一次CSS(根据高度修正)138 this.setCss(obj);139 },140 doHide : function() {141 var _this = this;142 this.timer = setTimeout(function() {143 _this.wrapper.style.display = 'none';144 }, 300);145 },146 doKeep : function() {147 if(this.timer != null) {148 clearTimeout(this.timer);149 }150 },151 //给整个框赋予基本的CSS152 initCss : function() {153 var w = this.wrapper;154 var w2 = this.wrapper2;155 var bg = this.bg;156 var c = this.content;157 var a = this.arrow;158 w.style.cssText = 'position:absolute;display:none';159 w2.style.cssText = 'position:relative';160 c.style.cssText = 'position:absolute;padding:10px;background:#FFF;opacity:1;z-index:2;border: 1px solid #bbb;';161 bg.style.cssText = 'left:-4px;top:-4px;background-color: #000;opacity:0.1;position:absolute;z-index:1;filter:alpha(opacity=10)';162 a.style.cssText = 'height:25px;width:25px;position:absolute;left:30px;top:-17px;z-index:2;background-image: url(/images/InfoPreviewBox_arrow.png);background-repeat: no-repeat;background-position-x: -1px; background-position-y: -1px;';163 c.style.width = this.width || '281px';164 },165 //用来给箭头位置、半透明边框定位166 setCss : function(obj) {167 var w = this.wrapper;168 var bg = this.bg;169 var arrow = this.arrow;170 var aFixX = 30 + this.offsetXFix + 'px';171 var aFixY = 30 + this.offsetYFix + 'px';172 var contentW = this.content.offsetWidth;173 var contentH = this.content.offsetHeight;174 bg.style.width = this.content.offsetWidth + this.borderWidth * 2 + 'px';175 bg.style.height = this.content.offsetHeight + this.borderWidth * 2 + 'px';176 bg.style.left = 0 - this.borderWidth;177 bg.style.top = 0 - this.borderWidth;178 w.style.left = obj.getAttribute('css-left') + 'px';179 w.style.top = obj.getAttribute('css-top') + 'px';180 181 if(this.direction[0] === 'left') {182 if(this.direction[1] < 0.5) {183 arrow.style.backgroundPositionY = this.option.left;184 arrow.style.left = '-20px';185 arrow.style.top = aFixY;186 } else {187 arrow.style.backgroundPositionY = this.option.right;188 arrow.style.left = this.content.offsetWidth - 11 + 'px';189 arrow.style.top = aFixY;190 }191 } else {192 if(this.direction[1] > 0.5) {193 arrow.style.backgroundPositionY = this.option.bottom;194 arrow.style.left = aFixX;195 arrow.style.top = this.content.offsetHeight - 4 + 'px';196 } else {197 arrow.style.backgroundPositionY = this.option.top;198 arrow.style.left = aFixX;199 arrow.style.top = '-17px';200 }201 }202 },203 //设置box的定位信息204 getPosition : function(obj, _this) {205 var offsetLeft = obj.getBoundingClientRect().left;206 var clientOffsetTop = document.documentElement.scrollTop || document.body.scrollTop;207 var offsetTop = obj.getBoundingClientRect().top + clientOffsetTop;208 var leftR = offsetLeft - parseInt(this.width) - 35;209 var leftL = offsetLeft + obj.offsetWidth + 15;210 var leftB = offsetTop;211 var topL = offsetLeft;212 var topB = offsetTop + obj.offsetHeight + 15;213 var topT = offsetTop - _this.content.offsetHeight - 15;214 if(this.direction[0] === 'left') {215 if(this.direction[1] < 0.5) {216 obj.setAttribute('css-left', leftL);217 obj.setAttribute('css-top', leftB);218 } else {219 obj.setAttribute('css-left', leftR);220 obj.setAttribute('css-top', leftB);221 }222 } else {223 if(this.direction[1] > 0.5) {224 obj.setAttribute('css-left', topL);225 obj.setAttribute('css-top', topT);226 } else {227 obj.setAttribute('css-left', topL);228 obj.setAttribute('css-top', topB);229 }230 }231 }232 }
转载于:https://www.cnblogs.com/circle-of-the-moon/archive/2011/12/14/2287924.html
【原生JS】仿新浪微博名片弹框相关推荐
- js仿苹果风格弹出框alert插件
下载地址 js仿苹果风格弹出框alert插件,多种调用方式. dd:
- html 监听input输入框的值,利用原生JS实时监听input框输入值
利用原生JS实时监听input框输入值 原生JS中可以使用oninput,onpropertychange,onchange oninput,onpropertychange,onchange的用法 ...
- 原生js打印阅览复选框不显示问题
原生js打印阅览复选框不显示问题 原生js打印预览,主要是阅览时候回出现一些问题,比如复选框传值,√不显示,那么怎么来解决这个问题呢?首先我们看一下效果图:我的页面是vue环境 这是预览状态,√和元页 ...
- 【每日一练】原生js仿淘宝主图放大镜功能,附学习源码
在我们的项目中,经常会遇到各种功能效果的实现,对于每一项功能的实现方式,都有很多种,这些实现方式没有好坏之分,只有适合与否,但是我个人建议,如果项目急就选择自己擅长的方式实现,比较完成工作更加重要嘛. ...
- html 对勾单选框,利用原生js和jQuery实现单选框的勾选和取消操作的方法
根据以下的Demo,大概就可以看的明白 Demo: window.onload = function(){ var dom_a = document.getElementById('a1'); var ...
- JS:原生JS实现message消息提示框
简介 学习了一下如何使用原生JS(加上class类)实现message消息提示框的封装(繁琐版). 使用到的主要技术点:class类,JS. 功能点 1.四种提示状态(message success ...
- 安卓仿Toasty消息弹框
Toast是安卓非常常用的消息弹框之一,但是原生的弹框过于朴素,无法适应不同场景的样式需求,因此设计一个类似于Toasty的弹框构建工具. 不废话直接上代码 import android.conten ...
- js仿新浪微博消息发布功能
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 原生js实现select下拉框选择
最近在做一个项目需要兼容到ie不同版本,在使用select时遇到了各种问题.后来索性就自己使用原生js实现了这样一个下拉框,话不多说,直接上代码吧. <html lang="en&qu ...
最新文章
- python怎么读取文件-python怎么读写文件操作
- 27对象的向上向下转型
- WeihanLi.Npoi 导出支持自定义列内容啦
- 每日一题(27)—— define定义一个宏表明1年中有多少秒
- LeetCode 1130. 叶值的最小代价生成树(区间DP/单调栈贪心)
- log4net 小记
- mysql generator备注_MyBatis Generator 自定义生成注释
- python爬虫中文乱码_Python爬虫处理抓取数据中文乱码问题
- Java实现Redis的消息订阅和发布
- 2003退休去世领了2年退休金没回本就死了能退吗?
- ubuntu18.04+nvidia显卡安装+cuda9.0+cudnn7+pycharm2018.2专业版激活+anaconda3+tensorflow-gpu1.6.0+keras+opencv3
- 【对比Java学Kotlin】类型别名
- molten php 上传,molten:PHP 应用透明链路追踪工具
- 在手机上图片分辨率怎么调?怎样用手机改300dpi图片?
- Git创建分支和查看分支命令
- 【集创赛】arm杯一等奖作品:智能BLDC驱动系统
- 不用计算机怎么算三角函数,1.不用计算机怎么求根式和三角函数值?
- 情商为什么比智商更重要1
- 7-12 两个数的简单计算器
- Navicat Mysql 破解教程(亲测可用)