MTooltips.js 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060
  1. var MTooltips = new Class({
  2. Extends: MWF.widget.Common,
  3. Implements: [Options, Events],
  4. options : {
  5. style : "", //如果有style,就加载 style/css.wcss
  6. axis: "y", //箭头在x轴还是y轴上展现
  7. position : { //node 固定的位置
  8. x : "auto", //x轴上left center right, auto 系统自动计算
  9. y : "auto" //y 轴上top middle bottom, auto 系统自动计算
  10. },
  11. priorityOfAuto :{
  12. x : [ "center", "right", "left" ], //当position x 为 auto 时候的优先级
  13. y : [ "middle", "bottom", "top" ] //当position y 为 auto 时候的优先级
  14. },
  15. offset : {
  16. x : 0,
  17. y : 0
  18. },
  19. isFitToContainer : true, //当position x 不为 auto, y 不为 auto 的时候,自动设置偏移量,使tooltip不超过容器的可见范围
  20. isParentOffset: false, //如果容器position不是absoulte 或 relative,计算到祖先absoulte 或 relative的偏移量
  21. event : "mouseenter", //事件类型,有target 时有效, mouseenter对应mouseleave,click 对应 container 的 click
  22. hiddenDelay : 200, //ms , 有target 且 事件类型为 mouseenter 时有效
  23. displayDelay : 0, //ms , 有target 且事件类型为 mouseenter 时有效
  24. hasArrow : true,
  25. isAutoShow : true,
  26. isAutoHide : true,
  27. hasMask : true,
  28. hasCloseAction : false,
  29. hideByClickBody : false,
  30. overflow : "hidden", //弹出框高宽超过container的时候怎么处理,hidden 表示超过的隐藏,scroll 表示超过的时候显示滚动条
  31. zoom: 1 //target有缩放的情况下,IOS的getCoordinates有问题
  32. },
  33. initialize : function( container, target, app, data, options, targetCoordinates ){
  34. //可以传入target 或者 targetCoordinates,两种选一
  35. //传入target,表示触发tooltip的节点,本类根据 this.options.event 自动绑定target的事件
  36. //传入targetCoordinates,表示 出发tooltip的位置,本类不绑定触发事件
  37. if( options ){
  38. this.setOptions(options);
  39. }
  40. this.container = container;
  41. this.target = target;
  42. this.targetCoordinates = targetCoordinates;
  43. this.body = $(document.body);
  44. this.app = app;
  45. if(app)this.lp = app.lp;
  46. this.data = data;
  47. this.path = "../x_component_Template/$MTooltips/";
  48. if( this.target ){
  49. this.setTargetEvents();
  50. }
  51. this.fireEvent("postInitialize",[this]);
  52. },
  53. setTargetEvents : function(){
  54. if( this.options.event === "click" ){
  55. if( this.options.isAutoShow ){
  56. this.targetClickFun = function( ev ){
  57. this.status === "display" ? this.hide() : this.load();
  58. ev.stopPropagation();
  59. }.bind(this);
  60. this.target.addEvents({
  61. "mousedown" : function(ev){ ev.stopPropagation(); },
  62. // "touchstart": function(ev){ ev.stopPropagation(); },
  63. "click": this.targetClickFun
  64. });
  65. }
  66. }else{
  67. if( this.options.isAutoHide || this.options.isAutoShow ){
  68. this.targetMouseenterFun = function(){
  69. if( this.timer_hide ){
  70. clearTimeout(this.timer_hide);
  71. this.timer_hide = null;
  72. }
  73. }.bind(this);
  74. this.target.addEvents({
  75. "mouseenter": this.targetMouseenterFun
  76. });
  77. }
  78. if( this.options.isAutoShow ){
  79. this.targetMouseenterFun2 = function(){
  80. if( this.status !== "display" ){
  81. this.timer_show = setTimeout( this.load.bind(this),this.options.displayDelay );
  82. }
  83. }.bind(this);
  84. this.target.addEvents({
  85. "mouseenter": this.targetMouseenterFun2
  86. });
  87. }
  88. if( this.options.isAutoHide || this.options.isAutoShow ){
  89. this.targetMouseleaveFun = function(){
  90. if( this.timer_show ){
  91. clearTimeout(this.timer_show);
  92. this.timer_show = null;
  93. }
  94. }.bind(this);
  95. this.target.addEvents({
  96. "mouseleave" : this.targetMouseleaveFun
  97. });
  98. }
  99. if( this.options.isAutoHide ){
  100. this.targetMouseleaveFun2 = function(){
  101. if( this.status === "display" ){
  102. this.timer_hide = setTimeout( this.hide.bind(this),this.options.hiddenDelay );
  103. }
  104. }.bind(this);
  105. this.target.addEvents({
  106. "mouseleave" : this.targetMouseleaveFun2
  107. });
  108. }
  109. }
  110. },
  111. load: function(){
  112. this.fireEvent("queryLoad",[this]);
  113. if( this.isEnable() ){
  114. if( this.node ){
  115. this.show();
  116. }else{
  117. this.create();
  118. }
  119. if( this.options.event === "click" ) {
  120. if( this.options.isAutoHide ){
  121. if( !this.options.hasMask ){
  122. this.containerMousedownFun = function(e){
  123. if( this.status === "display" ){
  124. this.hide();
  125. }
  126. e.stopPropagation();
  127. }.bind(this);
  128. this.container.addEvent("mousedown", this.containerMousedownFun );
  129. this.container.addEvent("touchstart", this.containerMousedownFun );
  130. this.nodeMousedownFun = function (e) {
  131. e.stopPropagation();
  132. };
  133. this.node.addEvent("mousedown", this.nodeMousedownFun);
  134. this.node.addEvent("touchstart", this.nodeMousedownFun);
  135. }
  136. }
  137. if( this.options.hideByClickBody ){
  138. if(!this.body)this.body = $(document.body);
  139. this.bodyMousedownFun = function(e){
  140. if( this.status === "display" ){
  141. this.hide();
  142. }
  143. e.stopPropagation();
  144. }.bind(this);
  145. this.body.addEvent("mousedown", this.bodyMousedownFun );
  146. this.body.addEvent("touchstart", this.bodyMousedownFun );
  147. if( !this.nodeMousedownFun ){
  148. this.nodeMousedownFun = function (e) {
  149. e.stopPropagation();
  150. };
  151. this.node.addEvent("mousedown", this.nodeMousedownFun);
  152. this.node.addEvent("touchstart", this.nodeMousedownFun);
  153. }
  154. }
  155. }
  156. }
  157. this.fireEvent("postLoad",[this]);
  158. },
  159. hide: function(){
  160. if( this.node ){
  161. this.node.setStyle("display","none");
  162. this.status = "hidden";
  163. if( this.maskNode ){
  164. this.maskNode.setStyle("display","none");
  165. }
  166. if( this.containerMousedownFun ){
  167. this.container.removeEvent("mousedown", this.containerMousedownFun );
  168. this.container.removeEvent("touchstart", this.containerMousedownFun );
  169. this.containerMousedownFun = null;
  170. }
  171. if( this.bodyMousedownFun && this.body){
  172. this.body.removeEvent("mousedown", this.bodyMousedownFun );
  173. this.body.removeEvent("touchstart", this.bodyMousedownFun );
  174. this.bodyMousedownFun = null;
  175. }
  176. if( this.nodeMousedownFun ){
  177. this.node.removeEvent("mousedown", this.nodeMousedownFun );
  178. this.node.removeEvent("touchstart", this.nodeMousedownFun );
  179. this.nodeMousedownFun = null;
  180. }
  181. if( this.timer_hide ){
  182. clearTimeout(this.timer_hide);
  183. this.timer_hide = null;
  184. }
  185. if( this.timer_show ){
  186. clearTimeout(this.timer_show);
  187. this.timer_show = null;
  188. }
  189. this.fireEvent("hide",[this]);
  190. }
  191. },
  192. show: function(){
  193. this.status = "display";
  194. if( this.maskNode ){
  195. this.maskNode.setStyle("display","");
  196. }
  197. this.node.setStyle("display","");
  198. this.setCoondinates();
  199. this.fireEvent("show",[this]);
  200. },
  201. create: function(){
  202. this.status = "display";
  203. this.fireEvent("queryCreate",[this]);
  204. this.loadStyle();
  205. this.fireEvent("loadStyle",[this]);
  206. this.node = new Element("div.tooltipNode", {
  207. styles : this.nodeStyles
  208. }).inject( this.container );
  209. if( this.contentNode ){
  210. this.contentNode.inject( this.node );
  211. }else{
  212. this.contentNode = new Element("div",{
  213. styles : this.contentStyles
  214. }).inject( this.node );
  215. this.contentNode.set("html", this._getHtml() );
  216. }
  217. this._customNode( this.node, this.contentNode );
  218. if( this.options.hasArrow ){
  219. this.arrowNode = new Element("div.arrowNode", {
  220. "styles": this.arrowStyles
  221. }
  222. ).inject(this.node);
  223. }
  224. if( this.options.hasCloseAction ){
  225. this.closeActionNode = new Element("div", {
  226. styles : this.closeActionStyles,
  227. events : {
  228. click : function(){ this.hide() }.bind(this)
  229. }
  230. }).inject( this.node );
  231. }
  232. this._loadCustom( function(){
  233. this.setCoondinates();
  234. }.bind(this));
  235. if( this.options.event == "click" ) {
  236. if( this.options.isAutoHide ){
  237. if( this.options.hasMask ){
  238. this.maskNode = new Element("div.maskNode", {
  239. "styles": this.maskStyles,
  240. "events": {
  241. "mouseover": function (e) {
  242. e.stopPropagation();
  243. },
  244. "mouseout": function (e) {
  245. e.stopPropagation();
  246. },
  247. "click": function (e) {
  248. this.hide();
  249. e.stopPropagation();
  250. }.bind(this)
  251. }
  252. }).inject( this.node, "before" );
  253. }
  254. if( this.app ){
  255. this.hideFun_resize = this.hide.bind(this);
  256. this.app.addEvent( "resize" , this.hideFun_resize );
  257. }
  258. }else{
  259. if( this.app && this.status === "display" ){
  260. this.setCoondinatesFun_resize = function(){
  261. if( this.timer_setCoondinates )clearTimeout(this.timer_setCoondinates);
  262. this.timer_setCoondinates = setTimeout( this.setCoondinates.bind(this), 300 )
  263. }.bind(this);
  264. this.app.addEvent( "resize" , this.setCoondinatesFun_resize );
  265. }
  266. }
  267. }else{
  268. if( this.options.isAutoHide || this.options.isAutoShow ){
  269. this.node.addEvents({
  270. "mouseenter": function(){
  271. if( this.timer_hide )clearTimeout(this.timer_hide);
  272. }.bind(this)
  273. });
  274. }
  275. if( this.options.isAutoHide ){
  276. this.node.addEvents({
  277. "mouseleave" : function(){
  278. if(this.options.isAutoHide){
  279. this.timer_hide = setTimeout( this.hide.bind(this),this.options.hiddenDelay );
  280. }
  281. }.bind(this)
  282. });
  283. }
  284. }
  285. //this.target.addEvent( "mouseleave", function(){
  286. // this.timer_hide = setTimeout( this.hide.bind(this), this.options.HiddenDelay );
  287. //}.bind(this));
  288. this.fireEvent("postCreate",[this]);
  289. },
  290. loadStyle : function(){
  291. if( this.options.style ){
  292. this.cssPath = this.path+this.options.style+"/css.wcss";
  293. this._loadCss();
  294. }
  295. this.nodeStyles = {
  296. "font-size" : "12px",
  297. "position" : "absolute",
  298. "max-width" : "500px",
  299. "min-width" : "260px",
  300. "z-index" : "11",
  301. "background-color" : "#fff",
  302. "padding" : "10px",
  303. "border-radius" : "8px",
  304. "box-shadow": "0 0 18px 0 #999999",
  305. "-webkit-user-select": "text",
  306. "-moz-user-select": "text"
  307. };
  308. if( this.options.nodeStyles ){ //兼容之前在options里设置nodeStyles
  309. this.nodeStyles = Object.merge( this.nodeStyles, this.options.nodeStyles );
  310. }else if( this.css && this.css.nodeStyles ){
  311. this.nodeStyles = this.css.nodeStyles
  312. }
  313. if( this.css && this.css.contentStyles ){
  314. this.contentStyles = this.css.contentStyles;
  315. }else{
  316. this.contentStyles = {
  317. "width" : "100%",
  318. "height" : "100%"
  319. }
  320. }
  321. if( this.options.hasArrow ){
  322. if( this.css && this.css.arrowStyles ){
  323. this.arrowStyles = this.css.arrowStyles
  324. }else{
  325. this.arrowStyles = {
  326. "width": this.options.axis == "x" ? "9px" : "17px",
  327. "height" : this.options.axis == "x" ? "17px" : "9px",
  328. "position":"absolute",
  329. "background" : "no-repeat url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAAlCAYAAACgc9J8AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAP9JREFUeNq01oENhCAMBdCWuIgTuP8WOoGj9GhSDaeUfjiuCSEm+iKFVllESGNdVzrPk55xHIfewHnItm1MrVDMG/u+i0aeyWZp3R9CJRaBIWRB5YUHItAL80AEqmI1EIFcrAQ1rwjUxEoQgULsAue+2ayc/W83p5+z6RXggOO1WQGhrsFXP/Oip58tAaQTZ4QMbEbyEB2GCKEBdtpmru4NsC4aHg8PLJ/3lim2xDv02jYDz1kNQsGEQgiYeqAQBPuZQF1jFKqBYTn1RLK1D4+v3E3NGfgNkJlfdKi0XrUZgc1OWyt0Dwz/z37tGhA20s+WR4t+1iBbzTJyaD8CDAB7WgNSzh/AnwAAAABJRU5ErkJggg==)"
  330. }
  331. }
  332. }
  333. if( this.options.event == "click" && this.options.isAutoHide ) {
  334. if( this.css && this.css.maskStyles ){
  335. this.maskStyles = this.css.maskStyles;
  336. }else{
  337. this.maskStyles = {
  338. "width": "100%",
  339. "height": "100%",
  340. "opacity": 0,
  341. "position": "absolute",
  342. "background-color": "#fff",
  343. "top": "0px",
  344. "left": "0px"
  345. }
  346. }
  347. }
  348. if( this.options.hasCloseAction ){
  349. if( this.css && this.css.closeActionStyles ){
  350. this.closeActionStyles = this.css.closeActionStyles
  351. }else{
  352. this.closeActionStyles = {
  353. "width": "24px",
  354. "height" : "24px",
  355. "position" : "absolute",
  356. "top": "0px",
  357. "right" : "0px",
  358. "background": "url(../x_component_Template/$MTooltips/default/icon/off_gray.png) no-repeat center center",
  359. "cursor": "pointer"
  360. }
  361. }
  362. }
  363. },
  364. isEnable : function(){
  365. return !this.disable;
  366. },
  367. isIOS: function() {
  368. return [
  369. 'iPad Simulator',
  370. 'iPhone Simulator',
  371. 'iPod Simulator',
  372. 'iPad',
  373. 'iPhone',
  374. 'iPod'
  375. ].includes(navigator.platform)
  376. // iPad on iOS 13 detection
  377. || (navigator.userAgent.includes("Mac") && "ontouchend" in document)
  378. },
  379. // isIOS : function(){
  380. //
  381. // if( typeOf(window.ios) === "boolean" )return window.ios;
  382. //
  383. // var iOS_1to12 = /iPad|iPhone|iPod/.test(navigator.platform);
  384. //
  385. // var iOS13_iPad = (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
  386. // window.ios = !window.MSStream && (iOS_1to12 || iOS13_iPad ); //|| iOS1to12quirk());
  387. //
  388. // return window.ios;
  389. // },
  390. setArrowStyle: function(){
  391. if( this.css && this.css.arrowStyles ){
  392. this.arrowStyles = this.css.arrowStyles
  393. }else{
  394. this.arrowStyles = {
  395. "width": this.options.axis == "x" ? "9px" : "17px",
  396. "height" : this.options.axis == "x" ? "17px" : "9px",
  397. "position":"absolute",
  398. "background" : "no-repeat url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAAlCAYAAACgc9J8AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAP9JREFUeNq01oENhCAMBdCWuIgTuP8WOoGj9GhSDaeUfjiuCSEm+iKFVllESGNdVzrPk55xHIfewHnItm1MrVDMG/u+i0aeyWZp3R9CJRaBIWRB5YUHItAL80AEqmI1EIFcrAQ1rwjUxEoQgULsAue+2ayc/W83p5+z6RXggOO1WQGhrsFXP/Oip58tAaQTZ4QMbEbyEB2GCKEBdtpmru4NsC4aHg8PLJ/3lim2xDv02jYDz1kNQsGEQgiYeqAQBPuZQF1jFKqBYTn1RLK1D4+v3E3NGfgNkJlfdKi0XrUZgc1OWyt0Dwz/z37tGhA20s+WR4t+1iBbzTJyaD8CDAB7WgNSzh/AnwAAAABJRU5ErkJggg==)"
  399. }
  400. }
  401. this.arrowNode.setStyles( this.arrowStyles );
  402. },
  403. setCoondinates : function(){
  404. if( !this.target && !this.targetCoordinates )return;
  405. if( this.options.axis == "x" ){
  406. this.setCoondinates_x();
  407. }else{
  408. this.setCoondinates_y();
  409. }
  410. },
  411. setCoondinates_x : function(){
  412. var targetCoondinates = this.target ? this.target.getCoordinates( this.container ) : this.targetCoordinates ;
  413. // if( o2.typeOf( this.options.zoom ) === "number" && this.options.zoom !== 1 && this.isIOS() ){
  414. // targetCoondinates.top = targetCoondinates.top - ( 1 - this.options.zoom ) * targetCoondinates.top;
  415. // targetCoondinates.bottom = targetCoondinates.bottom - ( 1 - this.options.zoom ) * targetCoondinates.bottom;
  416. // }
  417. var node = this.node;
  418. if( this.resetWidth ){
  419. node.setStyles({
  420. overflow : "visible",
  421. width : "auto"
  422. });
  423. if(this.arrowNode)this.arrowNode.setStyle("display","");
  424. this.resetWidth = false;
  425. }
  426. var containerScroll = this.container.getScroll();
  427. var containerSize = this.container.getSize();
  428. var nodeSize = node.getSize();
  429. var left;
  430. var arrowX, arrowY;
  431. var offsetX = (parseFloat(this.options.offset.x).toString() !== "NaN") ? parseFloat(this.options.offset.x) : 0;
  432. offsetX += this.options.hasArrow ? 10 : 0;
  433. if( this.options.position.x == "left" ) {
  434. left = targetCoondinates.left - nodeSize.x - offsetX;
  435. this.positionX = "left";
  436. arrowX = "right";
  437. }else if( this.options.position.x == "right" ){
  438. left = targetCoondinates.right + offsetX;
  439. this.positionX = "right";
  440. arrowX = "left";
  441. }else{
  442. var priorityOfAuto = this.options.priorityOfAuto;
  443. if( priorityOfAuto && priorityOfAuto.x ){
  444. for( var i=0; i<priorityOfAuto.x.length; i++ ){
  445. if( priorityOfAuto.x[i] == "left" ){
  446. if( targetCoondinates.left - containerScroll.x > containerSize.x - targetCoondinates.right){
  447. left = targetCoondinates.left - nodeSize.x - offsetX;
  448. this.positionX = "left";
  449. arrowX = "right";
  450. break;
  451. }
  452. }
  453. if( priorityOfAuto.x[i] == "right" ){
  454. if( containerSize.x + containerScroll.x - targetCoondinates.right > nodeSize.x ){
  455. left = targetCoondinates.right + offsetX;
  456. this.positionX = "right";
  457. arrowX = "left";
  458. break;
  459. }
  460. }
  461. }
  462. }
  463. if( !left ){
  464. if( targetCoondinates.left - containerScroll.x > containerSize.x - targetCoondinates.right){
  465. left = targetCoondinates.left - nodeSize.x - offsetX;
  466. this.positionX = "left";
  467. arrowX = "right";
  468. }else{
  469. left = targetCoondinates.right + offsetX;
  470. this.positionX = "right";
  471. arrowX = "left";
  472. }
  473. }
  474. }
  475. var top;
  476. if( this.options.position.y == "middle" ){
  477. top = targetCoondinates.top + (targetCoondinates.height/2) - ( nodeSize.y / 2 ) ;
  478. this.positionY = "middle";
  479. arrowY = "middle";
  480. }else if( this.options.position.y == "top" ){
  481. top = targetCoondinates.bottom - nodeSize.y;
  482. this.positionY = "top";
  483. arrowY = "bottom";
  484. }else if( this.options.position.y == "bottom" ){
  485. top = targetCoondinates.top;
  486. this.positionY = "bottom";
  487. arrowY = "top";
  488. }else{
  489. var priorityOfAuto = this.options.priorityOfAuto;
  490. if( priorityOfAuto && priorityOfAuto.y ){
  491. for( var i=0; i<priorityOfAuto.y.length; i++ ){
  492. if( priorityOfAuto.y[i] == "middle" ){
  493. if( targetCoondinates.top + (targetCoondinates.height/2) - ( nodeSize.y / 2 ) > containerScroll.y &&
  494. targetCoondinates.bottom - (targetCoondinates.height/2) + ( nodeSize.y / 2 ) - containerScroll.y < containerSize.y ){
  495. top = targetCoondinates.top + (targetCoondinates.height/2) - ( nodeSize.y / 2 ) ;
  496. this.positionY = "middle";
  497. arrowY = "middle";
  498. break;
  499. }
  500. }
  501. if( priorityOfAuto.y[i] == "top" ){
  502. if( targetCoondinates.top - containerScroll.y > containerSize.y - targetCoondinates.bottom ){
  503. top = targetCoondinates.bottom - nodeSize.y;
  504. this.positionY = "top";
  505. arrowY = "bottom";
  506. break;
  507. }
  508. }
  509. if( priorityOfAuto.y[i] == "bottom" ){
  510. if( containerSize.y + containerScroll.y - targetCoondinates.bottom > nodeSize.y ){
  511. top = targetCoondinates.top;
  512. this.positionY = "bottom";
  513. arrowY = "top";
  514. break;
  515. }
  516. }
  517. }
  518. }
  519. if( !top ){
  520. if( targetCoondinates.top + (targetCoondinates.height/2) - ( nodeSize.y / 2 ) > containerScroll.y &&
  521. targetCoondinates.bottom - (targetCoondinates.height/2) + ( nodeSize.y / 2 ) - containerScroll.y < containerSize.y ){
  522. top = targetCoondinates.top + (targetCoondinates.height/2) - ( nodeSize.y / 2 ) ;
  523. this.positionY = "middle";
  524. arrowY = "middle";
  525. } else if( targetCoondinates.top - containerScroll.y > containerSize.y - targetCoondinates.bottom ){
  526. top = targetCoondinates.bottom - nodeSize.y;
  527. this.positionY = "top";
  528. arrowY = "bottom";
  529. }else{
  530. top = targetCoondinates.top;
  531. this.positionY = "bottom";
  532. arrowY = "top";
  533. }
  534. }
  535. }
  536. var arrowOffsetY = 0;
  537. if( this.options.isFitToContainer ){
  538. if( top < containerScroll.y ){
  539. arrowOffsetY = containerScroll.y - top;
  540. top = containerScroll.y;
  541. }else if( top + nodeSize.y > containerSize.y + containerScroll.y ){
  542. arrowOffsetY = containerSize.y + containerScroll.y - top - nodeSize.y;
  543. top = containerSize.y + containerScroll.y - nodeSize.y;
  544. }
  545. }
  546. if( this.options.overflow == "scroll" ){
  547. if( left < 0 ){
  548. node.setStyles({
  549. "overflow" : "auto",
  550. "width" : nodeSize.x + left - offsetX
  551. });
  552. this.resetWidth = true;
  553. left = 0
  554. }else if( left + nodeSize.x > containerSize.x + containerScroll.x ){
  555. node.setStyles({
  556. "overflow" : "auto",
  557. "width" : Math.abs( containerSize.x + containerScroll.x - left + offsetX )
  558. });
  559. left = left - offsetX;
  560. this.resetWidth = true;
  561. }
  562. }
  563. if( this.resetWidth ){
  564. if( this.arrowNode )this.arrowNode.setStyle("display","none");
  565. }else if( this.options.hasArrow && this.arrowNode ) {
  566. if (arrowX == "left") {
  567. this.arrowNode.setStyles({
  568. "left": "-8px",
  569. "right": "auto",
  570. "background-position": "0px 0px"
  571. });
  572. } else {
  573. this.arrowNode.setStyles({
  574. "left": "auto",
  575. "right": "-8px",
  576. "background-position": "-11px 0px"
  577. });
  578. }
  579. var ah = this.arrowNode.getSize().y / 2;
  580. //var th = targetCoondinates.height / 2 - ah;
  581. var h = Math.min(targetCoondinates.height, nodeSize.y) / 2 - ah;
  582. var radiusDv = 0; //圆角和箭头偏移量的差值
  583. var radius = 0;
  584. if (arrowY == "middle") {
  585. this.arrowNode.setStyles({
  586. "top": (nodeSize.y / 2 - ah) - arrowOffsetY + "px",
  587. "bottom": "auto"
  588. })
  589. } else if (arrowY == "top") {
  590. radius = this.node.getStyle("border-top-" + arrowX + "-radius");
  591. radius = radius ? parseInt(radius) : 0;
  592. if (radius > h) {
  593. radiusDv = radius - h;
  594. }
  595. this.arrowNode.setStyles({
  596. "top": h + radiusDv - arrowOffsetY + "px",
  597. "bottom": "auto"
  598. })
  599. } else {
  600. radius = this.node.getStyle("border-bottom-" + arrowX + "-radius");
  601. radius = radius ? parseInt(radius) : 0;
  602. if (radius > h) {
  603. radiusDv = radius - h;
  604. }
  605. this.arrowNode.setStyles({
  606. "top": "auto",
  607. "bottom": h + radiusDv + arrowOffsetY + "px"
  608. })
  609. }
  610. var t = top;
  611. if (radiusDv) {
  612. if (arrowY == "top") {
  613. t = t - radiusDv;
  614. } else if (arrowY == "bottom") {
  615. t = t + radiusDv;
  616. }
  617. }
  618. }
  619. if( this.options.isParentOffset ){
  620. var pOffset = this.getParentOffset();
  621. t = (t || top) + pOffset.y;
  622. left = left + pOffset.x;
  623. }
  624. var obj = {
  625. "left" : left,
  626. "top" : t || top
  627. };
  628. this.fireEvent( "setCoondinates", [obj] );
  629. node.setStyles({
  630. "left" : obj.left,
  631. "top" : obj.top
  632. });
  633. this.fireEvent( "postSetCoondinates", [arrowX, arrowY, obj] );
  634. },
  635. setCoondinates_y : function(){
  636. var targetCoondinates = this.target ? this.target.getCoordinates( this.container ) : this.targetCoordinates ;
  637. // if( o2.typeOf( this.options.zoom ) === "number" && this.options.zoom !== 1 && this.isIOS() ){
  638. // targetCoondinates.left = targetCoondinates.left - ( 1 - this.options.zoom ) * targetCoondinates.left;
  639. // targetCoondinates.right = targetCoondinates.right - ( 1 - this.options.zoom ) * targetCoondinates.right;
  640. // }
  641. var node = this.node;
  642. if( this.resetHeight ){
  643. node.setStyles({
  644. overflow : "visible",
  645. height : "auto"
  646. });
  647. if(this.arrowNode)this.arrowNode.setStyle("display","");
  648. this.resetHeight = false;
  649. }
  650. var containerScroll = this.container.getScroll();
  651. var containerSize = this.container.getSize();
  652. var nodeSize = node.getSize();
  653. var top;
  654. var arrowX, arrowY;
  655. var offsetY = (parseFloat(this.options.offset.y).toString() !== "NaN") ? parseFloat(this.options.offset.y) : 0;
  656. offsetY += this.options.hasArrow ? 10 : 0;
  657. if( this.options.position.y == "top" ){
  658. top = targetCoondinates.top - nodeSize.y - offsetY;
  659. this.positionY = "top";
  660. arrowY = "bottom";
  661. }else if( this.options.position.y == "bottom" ){
  662. top = targetCoondinates.bottom + offsetY;
  663. this.positionY = "bottom";
  664. arrowY = "top";
  665. }else{
  666. var priorityOfAuto = this.options.priorityOfAuto;
  667. if( priorityOfAuto && priorityOfAuto.y ){
  668. for( var i=0; i<priorityOfAuto.y.length; i++ ){
  669. if( priorityOfAuto.y[i] == "top" ){
  670. if( targetCoondinates.top - containerScroll.y > containerSize.y - targetCoondinates.bottom ){
  671. top = targetCoondinates.top - nodeSize.y - offsetY;
  672. this.positionY = "top";
  673. arrowY = "bottom";
  674. break;
  675. }
  676. }
  677. if( priorityOfAuto.y[i] == "bottom" ){
  678. if( containerSize.y + containerScroll.y - targetCoondinates.bottom > nodeSize.y ){
  679. top = targetCoondinates.bottom + offsetY;
  680. this.positionY = "bottom";
  681. arrowY = "top";
  682. break;
  683. }
  684. }
  685. }
  686. }
  687. if( !top ){
  688. if( targetCoondinates.top - containerScroll.y > containerSize.y - targetCoondinates.bottom){
  689. top = targetCoondinates.top - nodeSize.y - offsetY;
  690. this.positionY = "top";
  691. arrowY = "bottom";
  692. }else{
  693. top = targetCoondinates.bottom + offsetY;
  694. this.positionY = "bottom";
  695. arrowY = "top";
  696. }
  697. }
  698. }
  699. var left;
  700. if( this.options.position.x == "center" ){
  701. left = targetCoondinates.left + (targetCoondinates.width/2) - ( nodeSize.x / 2 ) ;
  702. this.positionX = "center";
  703. arrowX = "center";
  704. }else if( this.options.position.x == "left" ){
  705. left = targetCoondinates.right - nodeSize.x;
  706. this.positionX = "left";
  707. arrowX = "right";
  708. }else if( this.options.position.x == "right" ){
  709. left = targetCoondinates.left;
  710. this.positionX = "right";
  711. arrowX = "left";
  712. }else{
  713. var priorityOfAuto = this.options.priorityOfAuto;
  714. if( priorityOfAuto && priorityOfAuto.x ){
  715. for( var i=0; i<priorityOfAuto.x.length; i++ ){
  716. if( priorityOfAuto.x[i] == "center" ){
  717. if( targetCoondinates.left + (targetCoondinates.width/2) - ( nodeSize.x / 2 ) > containerScroll.x &&
  718. targetCoondinates.right - (targetCoondinates.width/2) + ( nodeSize.x / 2 ) - containerScroll.x < containerSize.x ){
  719. left = targetCoondinates.left + (targetCoondinates.width/2) - ( nodeSize.x / 2 ) ;
  720. this.positionX = "center";
  721. arrowX = "center";
  722. break;
  723. }
  724. }
  725. if( priorityOfAuto.x[i] == "left" ){
  726. if( targetCoondinates.left - containerScroll.x > containerSize.x - targetCoondinates.right){
  727. left = targetCoondinates.right - nodeSize.x;
  728. this.positionX = "left";
  729. arrowX = "right";
  730. break;
  731. }
  732. }
  733. if( priorityOfAuto.x[i] == "right" ){
  734. if( containerSize.x + containerScroll.x - targetCoondinates.right > nodeSize.x ){
  735. left = targetCoondinates.left;
  736. this.positionX = "right";
  737. arrowX = "left";
  738. break;
  739. }
  740. }
  741. }
  742. }
  743. if( !left ){
  744. if( targetCoondinates.left + (targetCoondinates.width/2) - ( nodeSize.x / 2 ) > containerScroll.x &&
  745. targetCoondinates.right - (targetCoondinates.width/2) + ( nodeSize.x / 2 ) - containerScroll.x < containerSize.x ){
  746. left = targetCoondinates.left + (targetCoondinates.width/2) - ( nodeSize.x / 2 ) ;
  747. this.positionX = "center";
  748. arrowX = "center";
  749. } else if( targetCoondinates.left - containerScroll.x > containerSize.x - targetCoondinates.right ){
  750. left = targetCoondinates.right - nodeSize.x;
  751. this.positionX = "left";
  752. arrowX = "right";
  753. }else{
  754. left = targetCoondinates.left;
  755. this.positionX = "right";
  756. arrowX = "left";
  757. }
  758. }
  759. }
  760. var arrowOffsetX = 0;
  761. if( this.options.isFitToContainer ){
  762. if( left < containerScroll.x ){
  763. arrowOffsetX = containerScroll.x - left;
  764. left = containerScroll.x;
  765. }else if( left + nodeSize.x > containerSize.x + containerScroll.x ){
  766. arrowOffsetX = containerSize.x + containerScroll.x - left - nodeSize.x;
  767. left = containerSize.x + containerScroll.x - nodeSize.x;
  768. }
  769. }
  770. if( this.options.overflow == "scroll" ){
  771. if( top < 0 ){
  772. node.setStyles({
  773. "overflow" : "auto",
  774. "height" : nodeSize.y + top - offsetY
  775. });
  776. this.resetHeight = true;
  777. top = 0
  778. }else if( top + nodeSize.y > containerSize.y + containerScroll.y ){
  779. node.setStyles({
  780. "overflow" : "auto",
  781. "height" : Math.abs( containerSize.y + containerScroll.y - top + offsetY )
  782. });
  783. top = top - offsetY;
  784. this.resetHeight = true;
  785. }
  786. }
  787. if( this.resetHeight ){
  788. if( this.arrowNode )this.arrowNode.setStyle("display","none");
  789. }else if( this.options.hasArrow && this.arrowNode ){
  790. if( arrowY == "top" ){
  791. this.arrowNode.setStyles( {
  792. "top" : "-8px",
  793. "bottom" : "auto",
  794. "background-position": "0px -18px"
  795. });
  796. }else{
  797. this.arrowNode.setStyles( {
  798. "top" : "auto",
  799. "bottom" : "-8px",
  800. "background-position": "0px -28px"
  801. });
  802. }
  803. var aw = this.arrowNode.getSize().x / 2 ;
  804. //var tw = targetCoondinates.width / 2 - aw;
  805. var w = Math.min( targetCoondinates.width , nodeSize.x )/ 2 - aw;
  806. var radiusDv = 0; //圆角和箭头偏移量的差值
  807. var radius = 0; //圆角值
  808. if( arrowX == "center" ) {
  809. this.arrowNode.setStyles({
  810. "left": (nodeSize.x/2 - aw - arrowOffsetX )+"px",
  811. "right": "auto"
  812. })
  813. }else if( arrowX == "left" ){
  814. radius = this.node.getStyle("border-"+arrowY+"-left-radius");
  815. radius = radius ? parseInt( radius ) : 0;
  816. if( radius > w ){
  817. radiusDv = radius - w;
  818. }
  819. this.arrowNode.setStyles({
  820. "left" : w + radiusDv - arrowOffsetX + "px",
  821. "right" : "auto"
  822. })
  823. }else{
  824. radius = this.node.getStyle("border-" + arrowY + "-right-radius");
  825. radius = radius ? parseInt(radius) : 0;
  826. if( radius > w ){
  827. radiusDv = radius - w;
  828. }
  829. this.arrowNode.setStyles({
  830. "left" : "auto",
  831. "right" : w + radiusDv + arrowOffsetX +"px"
  832. })
  833. }
  834. var l = left;
  835. if( radiusDv ){
  836. if( arrowX == "left" ){
  837. l = l - radiusDv;
  838. }else if( arrowX == "right" ){
  839. l = l + radiusDv;
  840. }
  841. }
  842. }
  843. if( this.options.isParentOffset ){
  844. var pOffset = this.getParentOffset();
  845. top = top + pOffset.y;
  846. l = (l || left) + pOffset.x;
  847. }
  848. var obj = {
  849. "left" : l || left,
  850. "top" : top
  851. };
  852. this.fireEvent( "setCoondinates", [obj] );
  853. node.setStyles({
  854. "left" : obj.left,
  855. "top" : obj.top
  856. });
  857. this.fireEvent( "postSetCoondinates", [arrowX, arrowY, obj] );
  858. },
  859. getParentOffset: function(){
  860. var parentNode = this.container;
  861. while( parentNode && parentNode.tagName !== "BODY" && !["absolute", "relatvie", "fixed"].contains(parentNode.getStyle("position")) ){
  862. parentNode = parentNode.getParent();
  863. }
  864. if( parentNode !== this.container ){
  865. return this.container.getPosition(parentNode);
  866. }else{
  867. return {x: 0, y: 0}
  868. }
  869. },
  870. setPosition : function(){
  871. if( this.options.axis == "x" ){
  872. this.setPosition_x();
  873. }else{
  874. this.setPosition_y();
  875. }
  876. },
  877. setPosition_x : function(){
  878. var top, left;
  879. var targetCoondinates = this.target ? this.target.getCoordinates( this.container ) : this.targetCoordinates ;
  880. var node = this.node;
  881. var nodeSize = this.node.getSize();
  882. var offsetX = (parseFloat(this.options.offset.x).toString() !== "NaN") ? parseFloat(this.options.offset.x) : 0;
  883. offsetX += this.options.hasArrow ? 10 : 0;
  884. if( this.positionX === "left" ){
  885. left = targetCoondinates.left - nodeSize.x - offsetX;
  886. }else if( this.positionX === "right" ){
  887. left = targetCoondinates.right + offsetX;
  888. }
  889. if( this.positionY === "top" ){
  890. top = targetCoondinates.top - nodeSize.y;
  891. }else if( this.positionY === "bottom" ){
  892. top = targetCoondinates.bottom;
  893. }else if( this.positionX === "middle" ){
  894. top = targetCoondinates.top + (targetCoondinates.height/2) - ( nodeSize.y / 2 )
  895. }
  896. // if( this.options.isParentOffset ){
  897. // var pOffset = this.getParentOffset();
  898. // top = top + pOffset.y;
  899. // left = left + pOffset.x;
  900. // }
  901. node.setStyles({
  902. "left" : left,
  903. "top" : top
  904. });
  905. },
  906. setPosition_y : function(){
  907. var top, left;
  908. var targetCoondinates = this.target ? this.target.getCoordinates( this.container ) : this.targetCoordinates ;
  909. var node = this.node;
  910. var nodeSize = this.node.getSize();
  911. var offsetY = (parseFloat(this.options.offset.y).toString() !== "NaN") ? parseFloat(this.options.offset.y) : 0;
  912. offsetY += this.options.hasArrow ? 10 : 0;
  913. if( this.positionY === "top" ){
  914. top = targetCoondinates.top - nodeSize.y - offsetY;
  915. }else if( this.positionY === "bottom" ){
  916. top = targetCoondinates.bottom + offsetY;
  917. }
  918. if( this.positionX === "left" ){
  919. left = targetCoondinates.right - nodeSize.x;
  920. }else if( this.positionX === "right" ){
  921. left = targetCoondinates.left;
  922. }else if( this.positionX === "center" ){
  923. left = targetCoondinates.left + (targetCoondinates.width/2) - ( nodeSize.x / 2 )
  924. }
  925. // if( this.options.isParentOffset ){
  926. // var pOffset = this.getParentOffset();
  927. // top = top + pOffset.y;
  928. // left = left + pOffset.x;
  929. // }
  930. node.setStyles({
  931. "left" : left,
  932. "top" : top
  933. });
  934. },
  935. destroy: function(){
  936. //if( this.options.event == "click" && this.node ){
  937. // this.container.removeEvent("mousedown",this.hideFun );
  938. //}
  939. if( this.options.event == "click" && this.app ){
  940. if(this.hideFun_resize)this.app.removeEvent("resize",this.hideFun_resize );
  941. if(this.setCoondinatesFun_resize)this.app.removeEvent("resize",this.setCoondinatesFun_resize );
  942. }
  943. if( this.targetClickFun )this.target.removeEvent( "click", this.targetClickFun );
  944. if( this.targetMouseenterFun )this.target.removeEvent( "mouseenter", this.targetMouseenterFun );
  945. if( this.targetMouseenterFun2 )this.target.removeEvent( "mouseenter", this.targetMouseenterFun2 );
  946. if( this.targetMouseleaveFun )this.target.removeEvent( "mouseleave", this.targetMouseleaveFun );
  947. if( this.targetMouseleaveFun2 )this.target.removeEvent( "mouseleave", this.targetMouseleaveFun2 );
  948. if( this.node ){
  949. this.node.destroy();
  950. this.node = null;
  951. }
  952. this.fireEvent("destroy",[this]);
  953. MWF.release(this);
  954. },
  955. _getHtml : function(){
  956. //var data = this.data;
  957. //var titleStyle = "font-size:14px;color:#333";
  958. //var valueStyle = "font-size:14px;color:#666;padding-right:20px";
  959. //var persons = [];
  960. //data.invitePersonList.each( function( p ){
  961. // persons.push(p.split("@")[0] )
  962. //}.bind(this));
  963. //
  964. //var html =
  965. // "<div style='overflow: hidden;padding:15px 20px 20px 10px;height:16px;line-height:16px;'>" +
  966. // " <div style='font-size: 12px;color:#666; float: right'>"+ this.lp.applyPerson +":" + data.applicant.split("@")[0] +"</div>" +
  967. // " <div style='font-size: 16px;color:#333;float: left'>"+ this.lp.meetingDetail +"</div>"+
  968. // "</div>"+
  969. // "<div style='font-size: 18px;color:#333;padding:0px 10px 15px 20px;'>"+ data.subject +"</div>"+
  970. // "<div style='height:1px;margin:0px 20px;border-bottom:1px solid #ccc;'></div>"+
  971. // "<table width='100%' bordr='0' cellpadding='7' cellspacing='0' style='margin:13px 13px 13px 13px;'>" +
  972. // "<tr><td style='"+titleStyle+"' width='70'>"+this.lp.beginTime+":</td>" +
  973. // " <td style='"+valueStyle+"'>" + data.startTime + "</td></tr>" +
  974. // "<tr><td style='"+titleStyle+"'>"+this.lp.endTime+":</td>" +
  975. // " <td style='"+valueStyle+"'>" + data.completedTime + "</td></tr>" +
  976. // "<tr><td style='"+titleStyle+"'>"+this.lp.selectRoom +":</td>" +
  977. // " <td style='"+valueStyle+"' item='meetingRoom'></td></tr>" +
  978. // "<tr><td style='"+titleStyle+"'>"+this.lp.invitePerson2+":</td>" +
  979. // " <td style='"+valueStyle+"' item='invitePerson'>"+persons.join(",")+"</td></tr>" +
  980. // "<tr><td style='"+titleStyle+"'>"+this.lp.meetingDescription+":</td>" +
  981. // " <td style='"+valueStyle+"'>"+ data.description +"</td></tr>" +
  982. // "<tr><td style='"+titleStyle+"'>"+this.lp.meetingAttachment+":</td>" +
  983. // " <td style='"+valueStyle+"' item='attachment'></td></tr>"+
  984. // "</table>";
  985. return "";
  986. },
  987. _customNode : function( node, contentNode ){
  988. this.fireEvent("customContent", [contentNode, node])
  989. },
  990. _setContent : function( contentNode ){
  991. this.contentNode = contentNode;
  992. if( this.node ){
  993. this.node.empty();
  994. this.contentNode.inject( this.node );
  995. }
  996. },
  997. _loadCustom : function( callback ){
  998. if(callback)callback();
  999. }
  1000. });
  1001. MWF.xApplication.Template = MWF.xApplication.Template || {};
  1002. MWF.xApplication.Template.MTooltips = MTooltips;