zhiqim_floater.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. /*
  2. * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。
  3. *
  4. * 指定登记&发行网站: https://www.zhiqim.com/ 欢迎加盟知启蒙,[编程有你,知启蒙一路随行]。
  5. *
  6. * 本文采用《知启蒙登记发行许可证》,除非符合许可证,否则不可使用该文件!
  7. * 1、您可以免费使用、修改、合并、出版发行和分发,再授权软件、软件副本及衍生软件;
  8. * 2、您用于商业用途时,必须在原作者指定的登记网站,按原作者要求进行登记;
  9. * 3、您在使用、修改、合并、出版发行和分发时,必须包含版权声明、许可声明,及保留原作者的著作权、商标和专利等知识产权;
  10. * 4、您在互联网、移动互联网等大众网络下发行和分发再授权软件、软件副本及衍生软件时,必须在原作者指定的发行网站进行发行和分发;
  11. * 5、您可以在以下链接获取一个完整的许可证副本。
  12. *
  13. * 许可证链接:http://zhiqim.org/licenses/zhiqim_register_publish_license.htm
  14. *
  15. * 除非法律需要或书面同意,软件由原始码方式提供,无任何明示或暗示的保证和条件。详见完整许可证的权限和限制。
  16. */
  17. +(function(Z)
  18. {//BEGIN
  19. // @version v1.1.0 @author zouzhigang 2015-11-12 新建与整理
  20. // 定义浮动层
  21. // 1.触发者,支持条件为hover表示移入移出,click表示点击,点击其他地方则关闭
  22. // 2.方位,支持方位上下左右,对齐上下左右居中,偏移向左向上,和指定宽度和高度
  23. // 3.内容,支持是否有箭头和HTML文本
  24. // 4.颜色,支持边框和背景颜色
  25. // 用于如提示信息(ToolTip)和下拉列表等(DropdownList)使用
  26. Z.Floater = Z.Class.newInstance();
  27. Z.Floater.v = "1.4.0";
  28. Z.Floater.prototype =
  29. {
  30. defaults :
  31. {
  32. elem:null,
  33. event: "hover",
  34. //方位
  35. placement: "bottom",
  36. align: "center",
  37. top: 0,
  38. left: 0,
  39. width: 130,
  40. height: 25,
  41. //内容
  42. hasArrow: true,
  43. id: null,
  44. text: null,
  45. //颜色
  46. color: "#333",
  47. borderColor: "#c3c3c3",
  48. backgroundColor: "#fff"
  49. },
  50. execute: function()
  51. {
  52. this.$elem = Z.$elem(this.elem, "Z.Floater");
  53. this.id = this.id || "z-floater-"+Z.random(4);
  54. var floater = '<div class="z-floater" id="'+this.id+'">' +
  55. ' <div class="z-arrow z-px8"><span></span></div>' +
  56. ' <div class="z-content"></div>' +
  57. '</div>';
  58. this.$floater = Z(floater).appendToPos(this.$elem.parent());
  59. this.$arrow = this.$floater.find(".z-arrow");
  60. if (!this.hasArrow)
  61. {//删除箭头
  62. this.$arrow.remove();
  63. }
  64. this.$content = this.$floater.find(".z-content");
  65. this.$content.css({"width": this.width, "minHeight": this.height});
  66. this.$content.css({"color": this.color, "borderColor": this.borderColor,"backgroundColor": this.backgroundColor});
  67. this.$content.html(this.text);
  68. if (this.height < 25){
  69. this.$content.css("line-height", this.height);
  70. }
  71. this.elemLeft = this.$elem.offsetLeft();
  72. this.elemTop = this.$elem.offsetTop();
  73. this.elemWidth = this.$elem.offsetWidth();
  74. this.elemHeight = this.$elem.offsetHeight();
  75. this.elemHalfWidth = this.elemWidth / 2;
  76. this.elemHalfHeight = this.elemHeight / 2;
  77. this.contentWidth = this.$content.offsetWidth();
  78. this.contentHeight = this.$content.offsetHeight();
  79. this.contentHalfWidth = this.contentWidth / 2;
  80. this.contentHalfHeight = this.contentHeight / 2;
  81. //默认可见,计算完宽高之后隐藏
  82. this.$floater.hide();
  83. if (this.event == "hover")
  84. {//为移入移出事件,鼠标在元素和提示上显示
  85. this.$elem.mouseover(this.show, this);
  86. this.$elem.mouseout(this.hide, this);
  87. this.$floater.mouseover(this.show, this);
  88. this.$floater.mouseout(this.hide, this);
  89. }
  90. else if (this.event == "click")
  91. {//为点击事件,点击触发者和浮动层时停止冒泡,其他地方隐藏
  92. Z(document).click(this.hide, this);
  93. this.$elem.click(function(e){this.show();Z.E.stop(e);}, this);
  94. this.$floater.click(function(e){Z.E.stop(e);}, this);
  95. }
  96. else
  97. {//为要求主动关闭
  98. this.show();
  99. }
  100. },
  101. arrowBorderColor: function()
  102. {
  103. switch(this.placement)
  104. {
  105. case "top": return this.borderColor + " transparent transparent";
  106. case "left": return "transparent transparent transparent "+this.borderColor;
  107. case "right": return "transparent "+this.borderColor+" transparent transparent";
  108. default: return "transparent transparent "+this.borderColor;
  109. }
  110. },
  111. arrowBackgroundColor: function()
  112. {
  113. switch(this.placement)
  114. {
  115. case "top": return this.backgroundColor + " transparent transparent";
  116. case "left": return "transparent transparent transparent "+this.backgroundColor;
  117. case "right": return "transparent "+this.backgroundColor+" transparent transparent";
  118. default: return "transparent transparent "+this.backgroundColor;
  119. }
  120. },
  121. placeTop: function()
  122. {//放置上面
  123. var top = this.elemTop - this.contentHeight - (this.hasArrow?8:0) - this.top;
  124. var arrowTop = this.contentHeight - 1;
  125. var left, arrowLeft;
  126. switch (this.align)
  127. {
  128. case "left": left = this.elemLeft;arrowLeft = 10;break;
  129. case "right": left = this.elemLeft - this.contentWidth + this.elemWidth;arrowLeft = this.contentWidth - 16 - 10;break;
  130. default: left = this.elemLeft + this.elemHalfWidth - this.contentHalfWidth;arrowLeft = this.contentHalfWidth - 8 - 1;break;
  131. }
  132. this.$floater.show().css({left: left, top: top});
  133. if (this.hasArrow)
  134. {
  135. this.$arrow.css({left: arrowLeft, top: arrowTop});
  136. }
  137. },
  138. placeLeft: function()
  139. {//放置左边
  140. var left = this.elemLeft - this.contentWidth - (this.hasArrow?8:0) - this.left;
  141. var arrowLeft = this.contentWidth - 4 + 1;
  142. var top, arrowTop;
  143. switch (this.align)
  144. {
  145. case "top": top = this.elemTop;arrowTop = 10;break;
  146. case "bottom": top = this.elemTop + this.elemHeight - this.contentHeight;arrowTop = this.contentHeight - 16 - 10;break;
  147. default: top = this.elemTop + this.elemHalfHeight - this.contentHalfHeight;arrowTop = this.contentHalfHeight - 8;break;
  148. }
  149. this.$floater.show().css({top: top, left: left});
  150. if (this.hasArrow)
  151. {
  152. this.$arrow.addClass("z-right").css({left: arrowLeft, top: arrowTop});
  153. }
  154. },
  155. placeRight: function()
  156. {//放置右边
  157. var left = this.elemLeft + this.elemWidth + this.left;
  158. var top, arrowTop;
  159. switch (this.align)
  160. {
  161. case "top": top = this.elemTop;arrowTop = 10;break;
  162. case "bottom": top = this.elemTop + this.elemHeight - this.contentHeight;arrowTop = this.contentHeight - 16 - 10;break;
  163. default: top = this.elemTop + this.elemHalfHeight - this.contentHalfHeight;arrowTop = this.contentHalfHeight - 8;break;
  164. }
  165. this.$floater.show().css({left: left, top: top});
  166. if (this.hasArrow)
  167. {
  168. this.$arrow.addClass("z-left").css("top", arrowTop);
  169. this.$content.css("left", "9px");
  170. }
  171. },
  172. placeBottom: function()
  173. {//放置下面
  174. var top = this.elemTop + this.$elem.offsetHeight() + this.top;
  175. var left, arrowLeft;
  176. switch (this.align)
  177. {
  178. case "left": left = this.elemLeft;arrowLeft = 10;break;
  179. case "right": left = this.elemLeft - this.contentWidth + this.elemWidth;arrowLeft = this.contentWidth - 16 - 10;break;
  180. default: left = this.elemLeft + this.elemHalfWidth - this.contentHalfWidth;arrowLeft = this.contentHalfWidth - 8;break;
  181. }
  182. this.$floater.show().css({left: left, top: top});
  183. if (this.hasArrow)
  184. {
  185. this.$arrow.addClass("z-up").css("left", arrowLeft);
  186. this.$content.css("top", "7px");
  187. }
  188. },
  189. show: function()
  190. {//定义到元素的下方
  191. //1.设置箭头边框和背景
  192. if (this.hasArrow)
  193. {
  194. this.$arrow.css("border-color", this.arrowBorderColor());
  195. this.$arrow.find("span").css("border-color", this.arrowBackgroundColor());
  196. }
  197. //2.根据指定方位放置
  198. switch(this.placement)
  199. {
  200. case "top":return this.placeTop();
  201. case "left":return this.placeLeft();
  202. case "right":return this.placeRight();
  203. default:return this.placeBottom();
  204. }
  205. },
  206. hide:function(e)
  207. {//鼠标在元素和提示中间不关闭
  208. var x = Z.E.clientX(e);
  209. var y = Z.E.clientY(e);
  210. var tx = this.$elem.clientX();
  211. var ty = this.$elem.clientY();
  212. var tw = this.$elem.offsetWidth();
  213. var th = this.$elem.offsetHeight();
  214. switch(this.placement)
  215. {
  216. case "top":
  217. {
  218. if (x > tx && x < (tx+tw) && y < ty && y > (ty-this.top))
  219. return;
  220. break;
  221. }
  222. case "left":
  223. {
  224. if (x > (tx-this.left) && x < (tx+tw) && y > ty && y < (ty+th))
  225. return;
  226. break;
  227. }
  228. case "right":
  229. {
  230. if (x > (tx+tw) && x < (tx+tw+this.left) && y > ty && y < (ty+th))
  231. return;
  232. break;
  233. }
  234. default:
  235. {//bottom
  236. if (x > tx && x < (tx+tw) && y > (ty+th) && y < (ty+th+this.top))
  237. return;
  238. }
  239. }
  240. this.$floater.hide();
  241. },
  242. remove: function()
  243. {
  244. this.$floater.remove();
  245. }
  246. };
  247. /************************************************************************/
  248. //以下为Z.Tooltip,提供两种方式创建:
  249. // 1、使用Z.Tooltip/Z.Tooltip.close进行手动设置和关闭
  250. // 2、通过配置属性data-role="tooltip"来配置数据,并有data-text属性和可选属性可选的属性data-options值为样式格式handle:click;placement:bottom;align:center;top:5px;left:5px;width:200px;height:25px;color:#000;
  251. // <span data-role="tooltip" data-text="测试弹出提示框是否正常显示">需要提示的内容</span>
  252. // <span data-role="tooltip" data-options="top:1px;width:200px;height:25px;" data-text="测试弹出提示框是否正常显示">需要提示的内容</span>
  253. /************************************************************************/
  254. Z.Tooltip = function(elem, param)
  255. {
  256. Z.Tooltip.close(elem);
  257. var tooltip = new Z.Floater({elem: elem});
  258. for (var key in param){
  259. tooltip[key] = param[key];
  260. }
  261. tooltip.execute();
  262. Z.Tooltip.cache.push(tooltip);
  263. return tooltip;
  264. };
  265. //缓存和关闭函数
  266. Z.Tooltip.cache = [];
  267. Z.Tooltip.close = function(elem)
  268. {
  269. if (!elem)
  270. {//删除所有
  271. Z.each(Z.Tooltip.cache, function(tooltip){
  272. tooltip.remove();
  273. });
  274. Z.Tooltip.cache = [];
  275. }
  276. else
  277. {//删除一个
  278. Z.each(Z.Tooltip.cache, function(tooltip, i)
  279. {
  280. if (tooltip.elem == elem)
  281. {
  282. Z.Tooltip.cache.splice(i, 1);
  283. tooltip.remove();
  284. return true;
  285. }
  286. });
  287. }
  288. };
  289. //初始化和窗口缩放时重新加载
  290. Z.Tooltip.load = function()
  291. {
  292. //先关闭原来的
  293. Z.Tooltip.close();
  294. //再重新新增
  295. Z("[data-role=z-tooltip]").each(function(elem)
  296. {
  297. if (!Z.EL.has(elem, "data-text"))
  298. return;
  299. //获取配置的内容参数
  300. var $elem = Z(elem);
  301. var id = $elem.attr("data-id");
  302. var text = $elem.attr("data-text");
  303. var expression = $elem.attr("data-options");
  304. var options = Z.AR.toObject(expression, ";");
  305. var event = options && options.event || "hover";
  306. var placement = options && options.placement || "bottom";
  307. var align = options && options.align || "center";
  308. var top = Z.S.prefixNum(options && options.top || 0);
  309. var left = Z.S.prefixNum(options && options.left || 0);
  310. var width = Z.S.prefixNum(options && options.width || 130);
  311. var height = Z.S.prefixNum(options && options.height || 25);
  312. var arrow = options && options.arrow || "true";
  313. var hasArrow = "true" == arrow;
  314. var color = options && options.color || "#333";
  315. var borderColor = options && options.borderColor || "#c6c6c6";
  316. var backgroundColor = options && options.backgroundColor || "#fff";
  317. var tooltip = new Z.Floater({elem: elem, event: event, placement: placement, align: align,
  318. top: top, left: left, width: width, height: height,
  319. hasArrow: hasArrow, id: id, text: text,
  320. color: color, borderColor: borderColor, backgroundColor: backgroundColor});
  321. tooltip.execute();
  322. Z.Tooltip.cache.push(tooltip);
  323. });
  324. };
  325. Z.onload(Z.Tooltip.load);
  326. Z(window).resize(Z.Tooltip.load);
  327. //END
  328. })(zhiqim);