• l2Overlay: 原生 JavaScript 实现 Hoverpop 效果插件 p


    最近想给自己做的项目加上类似于 Facebook 的 Namecard 效果,即鼠标移动到制定目标后浮现一个信息卡,在鼠标移开目标或者信息卡后则自动隐藏。

    搜索了一下好像没有现成的插件可用,找到过几个仿 Facebook Style 的代码片段,但是感觉代码质量比我的还要糟糕,而且也不完全符合自己的要求,所以就花了一个下午的时间,用原生 JavaScript 写了一个类 Facebook Style 的 Namecard (hoverpop)插件。

    l2Overlay

    参看演示效果可以到:l2Overlay 演示

    l2Overlay 的 CSS 代码

    l2Overlay 的样式主要是模仿 Facebook 的 Namecard,下面是根据我的 l2Overlay 编写的 CSS 样式:

    1. .l2OverlayWrapper {
    2. font-size:12px;
    3. color:#333333;
    4. line-height:1.8;
    5. background-color:#FFFFFF;
    6. border:1px solid #8C8C8C;
    7. box-shadow:0010px#C8C8C8;
    8. margin:9px0;
    9. position: relative;
    10. max-width:300px;
    11. _width:300px;
    12. }
    13. .l2OverlayArrow {
    14. position: absolute;
    15. width:16px;
    16. height:9px;
    17. background:url("arrow.png") no-repeat -50px0px transparent;
    18. }
    19. .arrow-lt .l2OverlayArrow {
    20. left:15px;
    21. top:-9px;
    22. }
    23. .arrow-rt .l2OverlayArrow {
    24. right:15px;
    25. top:-9px;
    26. }
    27. .arrow-lb .l2OverlayArrow {
    28. background-position:-17px0;
    29. left:15px;
    30. bottom:-9px;
    31. _bottom:-15px;
    32. }
    33. .arrow-rb .l2OverlayArrow {
    34. background-position:-17px0;
    35. right:15px;
    36. bottom:-9px;
    37. _bottom:-15px;
    38. }
    39. .l2OverlayContent {
    40. margin:10px;
    41. }
    42. .l2Action {
    43. padding:010px;
    44. margin:10px-10px-10px;
    45. background-color:#F2F2F2;
    46. border-top:1px solid #CCCCCC;
    47. line-height:34px;
    48. height:34px;
    49. }
    50. .l2Title {
    51. border-bottom:1px dotted #CCCCCC;
    52. font-size:14px;
    53. font-weight: bold;
    54. margin:0010px;
    55. }

    l2Overlay 的 Javascript 代码

    Js 代码不压缩只有 9.88 kb,YUI 压缩后只有 4.15 kb,对于不想只为了一个效果而引用一个库的来说,绝对是很好的选择。

    1. /**
    2. * Plugin Name: l2Overlay
    3. * Plugin Author: LOO2K
    4. * Plugin Address: http://loo2k.com/blog/l2overlay-a-javascript-based-hoverpop-plugin/
    5. * Plugin Edition: 0.1
    6. * Last updated: 2012.05.19
    7. */
    8. function l2Overlay(){
    9. this.initialize.apply(this, arguments);
    10. }
    11.  
    12. l2Overlay.prototype ={
    13. /*
    14. * object 要应用 l2Overlay 的元素 对象或者数组
    15. * content 显示内容 'function|html|string|target'
    16. * option 选项
    17. * option = {
    18. * 'title' = 'string', // defalut undefied
    19. * 'pos' = 'auto|lt|lb|rt|tb', // default auto
    20. * 'cache' = 'true|false' // default false
    21. * }
    22. */
    23. initialize:function(object, content, option){
    24. this.id =(newDate()).getTime();
    25. this.createElement();
    26. var _this =this;
    27. this.object = object;
    28. this.content = content;
    29. this.option ={
    30. 'title': option.title ||undefined,
    31. 'pos': option.pos ||'auto',
    32. 'cache': option.cache ||false
    33. };
    34. this.hidel2Overlay;
    35. this.l2Overlay.onmouseover =function(){
    36. _this.cancleHide();
    37. }
    38. this.l2Overlay.onmouseout =function(){
    39. _this.hideOverlay();
    40. }
    41. if(typeofthis.object ==='object'&&typeofthis.object.length ==='number'){
    42. for(var i =0; i <this.object.length; i++){
    43. this.addEvent(this.object[i]);
    44. }
    45. }elseif(typeofthis.object =='object'&&!(this.object instanceof Array)){
    46. this.addEvent(this.object);
    47. }else{
    48. alert('传入对象错误');
    49. }
    50. },
    51. createElement:function(){
    52. // 生成基本模版
    53. if(!document.getElementById('l2Overlay_'+this.id)){
    54. var overlay = document.createElement('div');
    55. overlay.id ='l2Overlay_'+this.id;
    56. overlay.style.position ='absolute';
    57. overlay.style.zIndex ='9999';
    58. overlay.style.display ='none';
    59. var wrapper = document.createElement('div');
    60. wrapper.className ='l2OverlayWrapper';
    61. var arrow = document.createElement('div');
    62. arrow.className ='l2OverlayArrow';
    63.  
    64. var content = document.createElement('div');
    65. content.className ='l2OverlayContent';
    66. wrapper.appendChild(arrow);
    67. wrapper.appendChild(content);
    68. overlay.appendChild(wrapper);
    69. document.getElementsByTagName('body')[0].appendChild(overlay);
    70. }
    71. this.l2Overlay = document.getElementById('l2Overlay_'+this.id);
    72. var wrapper =this.l2Overlay.getElementsByTagName('div')[0].getElementsByTagName('div');
    73. this.l2Content = wrapper[1];
    74. this.l2Arrow = wrapper[0];
    75. },
    76. getPos:function(el){
    77. var ua = navigator.userAgent.toLowerCase();
    78. var isOpera =(ua.indexOf('opera')!=-1);
    79. var isIE =(ua.indexOf('msie')!=-1&&!isOpera);
    80. if( el.parentNode ===null|| el.style.display =='none'){
    81. returnfalse;
    82. }
    83. var parent =null;
    84. var pos =[];
    85. var box;
    86.  
    87. if( el.getBoundingClientRect ){
    88. // For IE
    89. box = el.getBoundingClientRect();
    90. var scrollTop =Math.max(document.documentElement.scrollTop, document.body.scrollTop);
    91. var scrollLeft =Math.max(document.documentElement.scrollLeft, document.body.scrollLeft);
    92. return{
    93. x: box.left + scrollLeft,
    94. y: box.top + scrollTop
    95. };
    96. }elseif( document.getBoxObjectFor ){
    97. // For FF
    98. box = document.getBoxObjectFor(el);
    99. var borderLeft =(el.style.borderLeftWidth)? parseInt(el.style.borderLeftWidth):0;
    100. var borderTop =(el.style.borderTopWidth)? parseInt(el.style.borderTopWidth):0;
    101. pos =[box.x - borderLeft, box.y - borderTop];
    102. }else{
    103. // For Safari & Opera
    104. pos =[el.offsetLeft, el.offsetTop];
    105. parent = el.offsetParent;
    106. if( parent != el ){
    107. while(parent){
    108. pos[0]+= parent.offsetLeft;
    109. pos[1]+= parent.offsetTop;
    110. parent = parent.offsetParent;
    111. }
    112. }
    113. if( ua.indexOf('opera')!=-1||(ua.indexOf('safari')!=-1&& el.style.position =='absolute')){
    114. pos[0]-= document.body.offsetLeft;
    115. pos[1]-= document.body.offsetTop;
    116. }
    117. }
    118. if( el.parentNode ){
    119. parent = el.parentNode;
    120. }else{
    121. parent =null;
    122. }
    123. // account for any scrolled ancestors
    124. while(parent && parent.tagName !='BODY'&& parent.tagName !='HTML'){
    125. pos[0]-= parent.scrollLeft;
    126. pos[1]-= parent.scrollTop;
    127. if(parent.parentNode){
    128. parent = parent.parentNode;
    129. }else{
    130. parent =null;
    131. }
    132. }
    133. return{
    134. x: pos[0],
    135. y: pos[1]
    136. };
    137. },
    138. getSize:function(element){
    139. if(element.offsetWidth !==0){
    140. /* 元素不是display:none的情况,这个时候是能得到尺寸的 */
    141. return{
    142. 'width': element.offsetWidth,
    143. 'height': element.offsetHeight
    144. };
    145. }
    146. var old ={};
    147. /* 将display:none元素设成visibility:hidden */
    148. var options ={
    149. position:"absolute",
    150. visibility:"hidden",
    151. display:"block"
    152. }
    153. for(var name in options ){
    154. old[ name ]= element.style[ name ];
    155. element.style[ name ]= options[ name ];
    156. }
    157. var temp ={
    158. 'width': element.offsetWidth,
    159. 'height': element.offsetHeight
    160. };
    161. for(var name in options ){
    162. element.style[ name ]= old[ name ];
    163. }
    164. return temp;
    165. },
    166. hideOverlay:function(){
    167. var _this =this;
    168. this.hidel2Overlay = setTimeout(function(){
    169. _this.l2Overlay.style.display ='none';
    170. },100);
    171. },
    172. cancleHide:function(){
    173. if(this.hidel2Overlay ){
    174. clearTimeout(this.hidel2Overlay);
    175. }
    176. },
    177. getBrowser:function(){
    178. var offset ={
    179. 'top': document.documentElement.scrollTop || document.body.scrollTop,
    180. 'left': document.documentElement.scrollLeft || document.body.scrollLeft
    181. }
    182. return offset;
    183. },
    184. addEvent:function(object){
    185. var _this =this;
    186. //var _object = this.object;
    187. var _object = object;
    188. _object.onmouseover =function(){
    189. _this.cancleHide();
    190. // 缓存模块
    191. if( _this.option.cache &&this.l2cache ){
    192. _this.l2Content.innerHTML =this.l2cache;
    193. }elseif(typeof _this.content ==='function'){
    194. _this.l2Content.innerHTML = _this.content.apply(this, arguments);;
    195. //console.log(_this.content());
    196. }else{
    197. _this.l2Content.innerHTML = _this.content;
    198. }
    199. if( _this.option.cache &&!this.l2cache ){
    200. this.l2cache = _this.l2Content.innerHTML;
    201. }
    202. // 定位模块
    203. var position = _this.getPos(this);
    204. var curTop = position.y;
    205. var curLeft = position.x;
    206. var offset = _this.getSize(_this.l2Overlay);
    207. var self = _this.getSize(this);
    208. var browser = _this.getBrowser();
    209. var pos ='';
    210. if( _this.option.pos ==='auto'){
    211. if((curLeft - browser.left - offset.width)>0){
    212. pos +='r';
    213. }else{
    214. pos +='l';
    215. }
    216. if((curTop - browser.top - offset.height)>0){
    217. pos +='b';
    218. }else{
    219. pos +='t';
    220. }
    221. }else{
    222. pos = _this.option.pos;
    223. }
    224. switch(pos){
    225. case'lt':
    226. _this.l2Overlay.className ='arrow-lt';
    227. oTop = curTop + self.height;
    228. oLeft = curLeft;
    229. break;
    230. case'rt':
    231. _this.l2Overlay.className ='arrow-rt';
    232. oTop = curTop + self.height;
    233. oLeft = curLeft - offset.width + self.width;
    234. break;
    235. case'rb':
    236. _this.l2Overlay.className ='arrow-rb';
    237. oTop = curTop - offset.height;
    238. oLeft = curLeft - offset.width + self.width;
    239. break;
    240. case'lb':
    241. default:
    242. _this.l2Overlay.className ='arrow-lb';
    243. oTop = curTop - offset.height;
    244. oLeft = curLeft;
    245. break;
    246. }
    247. _this.l2Overlay.style.top = oTop +'px';
    248. _this.l2Overlay.style.left = oLeft +'px';
    249. _this.l2Overlay.style.display ='';
    250. }
    251. _object.onmouseout =function(){
    252. _this.hideOverlay();
    253. }
    254. }
    255. }

    l2Overlay 的使用方法

    l2Overlay 创建了一个函数对象 l2Overlay,接受三个参数。分别为:

    1. object: 传入的必须是 HTML 元素,或者是 HTML 元素数组;
    2. content: 显示内容,可以是函数,HTML 代码,或者字符串,作用域为 object;
    3. option: option 对象可以设置 l2Overlay 显示的位置以及是否启用缓存;
    1. var applyLinks = document.getElementById('demo').getElementsByTagName('a');
    2. var content =function(){
    3. var html ='<div class="l2Title">这是一个标题</div>';
    4. html +='Function 内的作用域为该链接,如执行 this.href 可以得到该链接的地址:';
    5. html +=this.href;
    6. html +='<div class="l2Action"><a href="#">添加</a> | <a href="#">修改</a> | <a href="#">删除</a></div>';
    7. return html;
    8. }
    9. var options ={'pos':'','cache':true};
    10. new l2Overlay(applyLinks, content, options);

    参看演示效果可以到:l2Overlay 演示

    下载插件可以到:l2Overlay 下载

    小总结

    第一次写 JavaScript 插件,功夫不到家,代码仅供参考 :P

    其实这个用 jQuery 等库实现会简单很多,而且代码行数也会少很多,但是为了熟悉原生的 JavaScript 还是自己动手写了一遍。

  • 相关阅读:
    intellij idea 13
    tomcat加载web.xml
    tomcat-servlet-client
    请求由tomcat转到servlet的临界点
    传说用户发来的请求是在JIoEndpoint的accept函数中接收的,是tomact与外界交互的分界点
    java引用被设置为null的疑惑
    javascript之数组
    javascript学习笔记
    Http响应报文
    HTTP请求报文与响应报文
  • 原文地址:https://www.cnblogs.com/anyuqi/p/2726288.html
Copyright © 2020-2023  润新知