jquery-powerFloat-min.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878
  1. /*!
  2. * jquery-powerFloat.js
  3. * jQuery 万能浮动层插件
  4. * http://www.zhangxinxu.com/wordpress/?p=1328
  5. * © by zhangxinxu
  6. * 2010-12-06 v1.0.0 插件编写,初步调试
  7. * 2010-12-30 v1.0.1 限定尖角字符字体,避免受浏览器自定义字体干扰
  8. * 2011-01-03 v1.1.0 修复连续获得焦点显示后又隐藏的bug
  9. 修复图片加载正则判断不准确的问题
  10. * 2011-02-15 v1.1.1 关于居中对齐位置判断的特殊处理
  11. * 2011-04-15 v1.2.0 修复浮动层含有过高select框在IE下点击会隐藏浮动层的问题,同时优化事件绑定
  12. * 2011-09-13 v1.3.0 修复两个菜单hover时间间隔过短隐藏回调不执行的问题
  13. * 2012-01-13 v1.4.0 去除ajax加载的存储
  14. 修复之前按照ajax地址后缀判断是否图片的问题
  15. 修复一些脚本运行出错
  16. 修复hover延时显示时,元素没有显示但鼠标移出依然触发隐藏回调的问题
  17. * 2012-02-27 v1.5.0 为无id容器创建id逻辑使用错误的问题
  18. 修复无事件浮动出现时同页面点击空白区域浮动层不隐藏的问题
  19. 修复点击与hover并存时特定时候o.trigger报为null错误的问题
  20. * 2012-03-29 v1.5.1 修复连续hover时候后面一个不触发显示的问题
  21. * 2012-05-02 v1.5.2 点击事件 浮动框再次点击隐藏的问题修复
  22. * 2012-11-02 v1.6.0 兼容jQuery 1.8.2
  23. * 2012-01-28 v1.6.1 target参数支持funtion类型,以实现类似动态Ajax地址功能
  24. */
  25. (function ($) {
  26. $.fn.powerFloat = function (options) {
  27. return $(this).each(function () {
  28. var s = $.extend({}, defaults, options || {})
  29. var init = function (pms, trigger) {
  30. if (o.target && o.target.css('display') !== 'none') {
  31. o.targetHide()
  32. }
  33. o.s = pms
  34. o.trigger = trigger
  35. }; var hoverTimer
  36. switch (s.eventType) {
  37. case 'hover': {
  38. $(this).hover(function () {
  39. if (o.timerHold) {
  40. o.flagDisplay = true
  41. }
  42. var numShowDelay = parseInt(s.showDelay, 10)
  43. init(s, $(this))
  44. // 鼠标hover延时
  45. if (numShowDelay) {
  46. if (hoverTimer) {
  47. clearTimeout(hoverTimer)
  48. }
  49. hoverTimer = setTimeout(function () {
  50. o.targetGet.call(o)
  51. }, numShowDelay)
  52. } else {
  53. o.targetGet()
  54. }
  55. }, function () {
  56. if (hoverTimer) {
  57. clearTimeout(hoverTimer)
  58. }
  59. if (o.timerHold) {
  60. clearTimeout(o.timerHold)
  61. }
  62. o.flagDisplay = false
  63. o.targetHold()
  64. })
  65. if (s.hoverFollow) {
  66. // 鼠标跟随
  67. $(this).mousemove(function (e) {
  68. o.cacheData.left = e.pageX
  69. o.cacheData.top = e.pageY
  70. o.targetGet.call(o)
  71. return false
  72. })
  73. }
  74. break
  75. }
  76. case 'click': {
  77. $(this).click(function (e) {
  78. if (o.display && o.trigger && e.target === o.trigger.get(0)) {
  79. o.flagDisplay = false
  80. o.displayDetect()
  81. } else {
  82. init(s, $(this))
  83. o.targetGet()
  84. if (!$(document).data('mouseupBind')) {
  85. $(document).bind('mouseup', function (e) {
  86. var flag = false
  87. if (o.trigger) {
  88. var idTarget = o.target.attr('id')
  89. if (!idTarget) {
  90. idTarget = 'R_' + Math.random()
  91. o.target.attr('id', idTarget)
  92. }
  93. $(e.target).parents().each(function () {
  94. if ($(this).attr('id') === idTarget) {
  95. flag = true
  96. }
  97. })
  98. if (s.eventType === 'click' && o.display && e.target != o.trigger.get(0) && !flag) {
  99. o.flagDisplay = false
  100. o.displayDetect()
  101. }
  102. }
  103. return false
  104. }).data('mouseupBind', true)
  105. }
  106. }
  107. })
  108. break
  109. }
  110. case 'focus': {
  111. $(this).focus(function () {
  112. var self = $(this)
  113. setTimeout(function () {
  114. init(s, self)
  115. o.targetGet()
  116. }, 200)
  117. }).blur(function () {
  118. o.flagDisplay = false
  119. setTimeout(function () {
  120. o.displayDetect()
  121. }, 190)
  122. })
  123. break
  124. }
  125. default: {
  126. init(s, $(this))
  127. o.targetGet()
  128. // 放置页面点击后显示的浮动内容隐掉
  129. $(document).unbind('mouseup').data('mouseupBind', false)
  130. }
  131. }
  132. })
  133. }
  134. var o = {
  135. targetGet: function () {
  136. // 一切显示的触发来源
  137. if (!this.trigger) { return this }
  138. var attr = this.trigger.attr(this.s.targetAttr); var target = typeof this.s.target === 'function' ? this.s.target.call(this.trigger) : this.s.target
  139. switch (this.s.targetMode) {
  140. case 'common': {
  141. if (target) {
  142. var type = typeof (target)
  143. if (type === 'object') {
  144. if (target.size()) {
  145. o.target = target.eq(0)
  146. }
  147. } else if (type === 'string') {
  148. if ($(target).size()) {
  149. o.target = $(target).eq(0)
  150. }
  151. }
  152. } else {
  153. if (attr && $('#' + attr).length) {
  154. o.target = $('#' + attr)
  155. }
  156. }
  157. if (o.target) {
  158. o.targetShow()
  159. } else {
  160. return this
  161. }
  162. break
  163. }
  164. case 'ajax': {
  165. // ajax元素,如图片,页面地址
  166. var url = target || attr
  167. this.targetProtect = false
  168. if (!url) { return }
  169. if (!o.cacheData[url]) {
  170. o.loading()
  171. }
  172. // 优先认定为图片加载
  173. var tempImage = new Image()
  174. tempImage.onload = function () {
  175. var w = tempImage.width; var h = tempImage.height
  176. var winw = $(window).width(); var winh = $(window).height()
  177. var imgScale = w / h; var winScale = winw / winh
  178. if (imgScale > winScale) {
  179. // 图片的宽高比大于显示屏幕
  180. if (w > winw / 2) {
  181. w = winw / 2
  182. h = w / imgScale
  183. }
  184. } else {
  185. // 图片高度较高
  186. if (h > winh / 2) {
  187. h = winh / 2
  188. w = h * imgScale
  189. }
  190. }
  191. var imgHtml = '<img class="float_ajax_image" src="' + url + '" width="' + w + '" height = "' + h + '" />'
  192. o.cacheData[url] = true
  193. o.target = $(imgHtml)
  194. o.targetShow()
  195. }
  196. tempImage.onerror = function () {
  197. // 如果图片加载失败,两种可能,一是100%图片,则提示;否则作为页面加载
  198. if (/(\.jpg|\.png|\.gif|\.bmp|\.jpeg)$/i.test(url)) {
  199. o.target = $('<div class="float_ajax_error">图片加载失败。</div>')
  200. o.targetShow()
  201. } else {
  202. $.ajax({
  203. url: url,
  204. success: function (data) {
  205. if (typeof (data) === 'string') {
  206. o.cacheData[url] = true
  207. o.target = $('<div class="float_ajax_data">' + data + '</div>')
  208. o.targetShow()
  209. }
  210. },
  211. error: function () {
  212. o.target = $('<div class="float_ajax_error">数据没有加载成功。</div>')
  213. o.targetShow()
  214. }
  215. })
  216. }
  217. }
  218. tempImage.src = url
  219. break
  220. }
  221. case 'list': {
  222. // 下拉列表
  223. var targetHtml = '<ul class="float_list_ul">'; var arrLength
  224. if ($.isArray(target) && (arrLength = target.length)) {
  225. $.each(target, function (i, obj) {
  226. var list = ''; var strClass = ''; var text; var href
  227. if (i === 0) {
  228. strClass = ' class="float_list_li_first"'
  229. }
  230. if (i === arrLength - 1) {
  231. strClass = ' class="float_list_li_last"'
  232. }
  233. if (typeof (obj) === 'object' && (text = obj.text.toString())) {
  234. if (href = (obj.href || 'javascript:')) {
  235. list = '<a href="' + href + '" class="float_list_a">' + text + '</a>'
  236. } else {
  237. list = text
  238. }
  239. } else if (typeof (obj) === 'string' && obj) {
  240. list = obj
  241. }
  242. if (list) {
  243. targetHtml += '<li' + strClass + '>' + list + '</li>'
  244. }
  245. })
  246. } else {
  247. targetHtml += '<li class="float_list_null">列表无数据。</li>'
  248. }
  249. targetHtml += '</ul>'
  250. o.target = $(targetHtml)
  251. this.targetProtect = false
  252. o.targetShow()
  253. break
  254. }
  255. case 'remind': {
  256. // 内容均是字符串
  257. var strRemind = target || attr
  258. this.targetProtect = false
  259. if (typeof (strRemind) === 'string') {
  260. o.target = $('<span>' + strRemind + '</span>')
  261. o.targetShow()
  262. }
  263. break
  264. }
  265. default: {
  266. var objOther = target || attr; var type = typeof (objOther)
  267. if (objOther) {
  268. if (type === 'string') {
  269. // 选择器
  270. if (/^.[^:#\[\.,]*$/.test(objOther)) {
  271. if ($(objOther).size()) {
  272. o.target = $(objOther).eq(0)
  273. this.targetProtect = true
  274. } else if ($('#' + objOther).size()) {
  275. o.target = $('#' + objOther).eq(0)
  276. this.targetProtect = true
  277. } else {
  278. o.target = $('<div>' + objOther + '</div>')
  279. this.targetProtect = false
  280. }
  281. } else {
  282. o.target = $('<div>' + objOther + '</div>')
  283. this.targetProtect = false
  284. }
  285. o.targetShow()
  286. } else if (type === 'object') {
  287. if (!$.isArray(objOther) && objOther.size()) {
  288. o.target = objOther.eq(0)
  289. this.targetProtect = true
  290. o.targetShow()
  291. }
  292. }
  293. }
  294. }
  295. }
  296. return this
  297. },
  298. container: function () {
  299. // 容器(如果有)重装target
  300. var cont = this.s.container; var mode = this.s.targetMode || 'mode'
  301. if (mode === 'ajax' || mode === 'remind') {
  302. // 显示三角
  303. this.s.sharpAngle = true
  304. } else {
  305. this.s.sharpAngle = false
  306. }
  307. // 是否反向
  308. if (this.s.reverseSharp) {
  309. this.s.sharpAngle = !this.s.sharpAngle
  310. }
  311. if (mode !== 'common') {
  312. // common模式无新容器装载
  313. if (cont === null) {
  314. cont = 'plugin'
  315. }
  316. if (cont === 'plugin') {
  317. if (!$('#floatBox_' + mode).size()) {
  318. $('<div id="floatBox_' + mode + '" class="float_' + mode + '_box"></div>').appendTo($('body')).hide()
  319. }
  320. cont = $('#floatBox_' + mode)
  321. }
  322. if (cont && typeof (cont) !== 'string' && cont.size()) {
  323. if (this.targetProtect) {
  324. o.target.show().css('position', 'static')
  325. }
  326. o.target = cont.empty().append(o.target)
  327. }
  328. }
  329. return this
  330. },
  331. setWidth: function () {
  332. var w = this.s.width
  333. if (w === 'auto') {
  334. if (this.target.get(0).style.width) {
  335. this.target.css('width', 'auto')
  336. }
  337. } else if (w === 'inherit') {
  338. this.target.width(this.trigger.width())
  339. } else {
  340. this.target.css('width', w)
  341. }
  342. return this
  343. },
  344. position: function () {
  345. if (!this.trigger || !this.target) {
  346. return this
  347. }
  348. var pos; var tri_h = 0; var tri_w = 0; var cor_w = 0; var cor_h = 0; var tri_l; var tri_t; var tar_l; var tar_t; var cor_l; var cor_t
  349. var tar_h = this.target.data('height'); var tar_w = this.target.data('width')
  350. var st = $(window).scrollTop()
  351. var off_x = parseInt(this.s.offsets.x, 10) || 0; var off_y = parseInt(this.s.offsets.y, 10) || 0
  352. var mousePos = this.cacheData
  353. // 缓存目标对象高度,宽度,提高鼠标跟随时显示性能,元素隐藏时缓存清除
  354. if (!tar_h) {
  355. tar_h = this.target.outerHeight()
  356. if (this.s.hoverFollow) {
  357. this.target.data('height', tar_h)
  358. }
  359. }
  360. if (!tar_w) {
  361. tar_w = this.target.outerWidth()
  362. if (this.s.hoverFollow) {
  363. this.target.data('width', tar_w)
  364. }
  365. }
  366. pos = this.trigger.offset()
  367. tri_h = this.trigger.outerHeight()
  368. tri_w = this.trigger.outerWidth()
  369. tri_l = pos.left
  370. tri_t = pos.top
  371. var funMouseL = function () {
  372. if (tri_l < 0) {
  373. tri_l = 0
  374. } else if (tri_l + tri_h > $(window).width()) {
  375. tri_l = $(window).width() - tri_w
  376. }
  377. }; var funMouseT = function () {
  378. if (tri_t < 0) {
  379. tri_t = 0
  380. } else if (tri_t + tri_h > $(document).height()) {
  381. tri_t = $(document).height() - tri_h
  382. }
  383. }
  384. // 如果是鼠标跟随
  385. if (this.s.hoverFollow && mousePos.left && mousePos.top) {
  386. if (this.s.hoverFollow === 'x') {
  387. // 水平方向移动,说明纵坐标固定
  388. tri_l = mousePos.left
  389. funMouseL()
  390. } else if (this.s.hoverFollow === 'y') {
  391. // 垂直方向移动,说明横坐标固定,纵坐标跟随鼠标移动
  392. tri_t = mousePos.top
  393. funMouseT()
  394. } else {
  395. tri_l = mousePos.left
  396. tri_t = mousePos.top
  397. funMouseL()
  398. funMouseT()
  399. }
  400. }
  401. var arrLegalPos = ['4-1', '1-4', '5-7', '2-3', '2-1', '6-8', '3-4', '4-3', '8-6', '1-2', '7-5', '3-2']
  402. var align = this.s.position; var alignMatch = false; var strDirect
  403. $.each(arrLegalPos, function (i, n) {
  404. if (n === align) {
  405. alignMatch = true
  406. }
  407. })
  408. if (!alignMatch) {
  409. align = '4-1'
  410. }
  411. var funDirect = function (a) {
  412. var dir = 'bottom'
  413. // 确定方向
  414. switch (a) {
  415. case '1-4': case '5-7': case '2-3': {
  416. dir = 'top'
  417. break
  418. }
  419. case '2-1': case '6-8': case '3-4': {
  420. dir = 'right'
  421. break
  422. }
  423. case '1-2': case '8-6': case '4-3': {
  424. dir = 'left'
  425. break
  426. }
  427. case '4-1': case '7-5': case '3-2': {
  428. dir = 'bottom'
  429. break
  430. }
  431. }
  432. return dir
  433. }
  434. // 居中判断
  435. var funCenterJudge = function (a) {
  436. if (a === '5-7' || a === '6-8' || a === '8-6' || a === '7-5') {
  437. return true
  438. }
  439. return false
  440. }
  441. var funJudge = function (dir) {
  442. var totalHeight = 0; var totalWidth = 0; var flagCorner = !!((o.s.sharpAngle && o.corner))
  443. if (dir === 'right') {
  444. totalWidth = tri_l + tri_w + tar_w + off_x
  445. if (flagCorner) {
  446. totalWidth += o.corner.width()
  447. }
  448. if (totalWidth > $(window).width()) {
  449. return false
  450. }
  451. } else if (dir === 'bottom') {
  452. totalHeight = tri_t + tri_h + tar_h + off_y
  453. if (flagCorner) {
  454. totalHeight += o.corner.height()
  455. }
  456. if (totalHeight > st + $(window).height()) {
  457. return false
  458. }
  459. } else if (dir === 'top') {
  460. totalHeight = tar_h + off_y
  461. if (flagCorner) {
  462. totalHeight += o.corner.height()
  463. }
  464. if (totalHeight > tri_t - st) {
  465. return false
  466. }
  467. } else if (dir === 'left') {
  468. totalWidth = tar_w + off_x
  469. if (flagCorner) {
  470. totalWidth += o.corner.width()
  471. }
  472. if (totalWidth > tri_l) {
  473. return false
  474. }
  475. }
  476. return true
  477. }
  478. // 此时的方向
  479. strDirect = funDirect(align)
  480. if (this.s.sharpAngle) {
  481. // 创建尖角
  482. this.createSharp(strDirect)
  483. }
  484. // 边缘过界判断
  485. if (this.s.edgeAdjust) {
  486. // 根据位置是否溢出显示界面重新判定定位
  487. if (funJudge(strDirect)) {
  488. // 该方向不溢出
  489. (function () {
  490. if (funCenterJudge(align)) { return }
  491. var obj = {
  492. top: {
  493. right: '2-3',
  494. left: '1-4'
  495. },
  496. right: {
  497. top: '2-1',
  498. bottom: '3-4'
  499. },
  500. bottom: {
  501. right: '3-2',
  502. left: '4-1'
  503. },
  504. left: {
  505. top: '1-2',
  506. bottom: '4-3'
  507. }
  508. }
  509. var o = obj[strDirect]; var name
  510. if (o) {
  511. for (name in o) {
  512. if (!funJudge(name)) {
  513. align = o[name]
  514. }
  515. }
  516. }
  517. })()
  518. } else {
  519. // 该方向溢出
  520. (function () {
  521. if (funCenterJudge(align)) {
  522. var center = {
  523. '5-7': '7-5',
  524. '7-5': '5-7',
  525. '6-8': '8-6',
  526. '8-6': '6-8'
  527. }
  528. align = center[align]
  529. } else {
  530. var obj = {
  531. top: {
  532. left: '3-2',
  533. right: '4-1'
  534. },
  535. right: {
  536. bottom: '1-2',
  537. top: '4-3'
  538. },
  539. bottom: {
  540. left: '2-3',
  541. right: '1-4'
  542. },
  543. left: {
  544. bottom: '2-1',
  545. top: '3-4'
  546. }
  547. }
  548. var o = obj[strDirect]; var arr = []
  549. for (name in o) {
  550. arr.push(name)
  551. }
  552. if (funJudge(arr[0]) || !funJudge(arr[1])) {
  553. align = o[arr[0]]
  554. } else {
  555. align = o[arr[1]]
  556. }
  557. }
  558. })()
  559. }
  560. }
  561. // 已确定的尖角
  562. var strNewDirect = funDirect(align); var strFirst = align.split('-')[0]
  563. if (this.s.sharpAngle) {
  564. // 创建尖角
  565. this.createSharp(strNewDirect)
  566. cor_w = this.corner.width(), cor_h = this.corner.height()
  567. }
  568. // 确定left, top值
  569. if (this.s.hoverFollow) {
  570. // 如果鼠标跟随
  571. if (this.s.hoverFollow === 'x') {
  572. // 仅水平方向跟随
  573. tar_l = tri_l + off_x
  574. if (strFirst === '1' || strFirst === '8' || strFirst === '4') {
  575. // 最左
  576. tar_l = tri_l - (tar_w - tri_w) / 2 + off_x
  577. } else {
  578. // 右侧
  579. tar_l = tri_l - (tar_w - tri_w) + off_x
  580. }
  581. // 这是垂直位置,固定不动
  582. if (strFirst === '1' || strFirst === '5' || strFirst === '2') {
  583. tar_t = tri_t - off_y - tar_h - cor_h
  584. // 尖角
  585. cor_t = tri_t - cor_h - off_y - 1
  586. } else {
  587. // 下方
  588. tar_t = tri_t + tri_h + off_y + cor_h
  589. cor_t = tri_t + tri_h + off_y + 1
  590. }
  591. cor_l = pos.left - (cor_w - tri_w) / 2
  592. } else if (this.s.hoverFollow === 'y') {
  593. // 仅垂直方向跟随
  594. if (strFirst === '1' || strFirst === '5' || strFirst === '2') {
  595. // 顶部
  596. tar_t = tri_t - (tar_h - tri_h) / 2 + off_y
  597. } else {
  598. // 底部
  599. tar_t = tri_t - (tar_h - tri_h) + off_y
  600. }
  601. if (strFirst === '1' || strFirst === '8' || strFirst === '4') {
  602. // 左侧
  603. tar_l = tri_l - tar_w - off_x - cor_w
  604. cor_l = tri_l - cor_w - off_x - 1
  605. } else {
  606. // 右侧
  607. tar_l = tri_l + tri_w - off_x + cor_w
  608. cor_l = tri_l + tri_w + off_x + 1
  609. }
  610. cor_t = pos.top - (cor_h - tri_h) / 2
  611. } else {
  612. tar_l = tri_l + off_x
  613. tar_t = tri_t + off_y
  614. }
  615. } else {
  616. switch (strNewDirect) {
  617. case 'top': {
  618. tar_t = tri_t - off_y - tar_h - cor_h
  619. if (strFirst == '1') {
  620. tar_l = tri_l - off_x
  621. } else if (strFirst === '5') {
  622. tar_l = tri_l - (tar_w - tri_w) / 2 - off_x
  623. } else {
  624. tar_l = tri_l - (tar_w - tri_w) - off_x
  625. }
  626. cor_t = tri_t - cor_h - off_y - 1
  627. cor_l = tri_l - (cor_w - tri_w) / 2
  628. break
  629. }
  630. case 'right': {
  631. tar_l = tri_l + tri_w + off_x + cor_w
  632. if (strFirst == '2') {
  633. tar_t = tri_t + off_y
  634. } else if (strFirst === '6') {
  635. tar_t = tri_t - (tar_h - tri_h) / 2 + off_y
  636. } else {
  637. tar_t = tri_t - (tar_h - tri_h) + off_y
  638. }
  639. cor_l = tri_l + tri_w + off_x + 1
  640. cor_t = tri_t - (cor_h - tri_h) / 2
  641. break
  642. }
  643. case 'bottom': {
  644. tar_t = tri_t + tri_h + off_y + cor_h
  645. if (strFirst == '4') {
  646. tar_l = tri_l + off_x
  647. } else if (strFirst === '7') {
  648. tar_l = tri_l - (tar_w - tri_w) / 2 + off_x
  649. } else {
  650. tar_l = tri_l - (tar_w - tri_w) + off_x
  651. }
  652. cor_t = tri_t + tri_h + off_y + 1
  653. cor_l = tri_l - (cor_w - tri_w) / 2
  654. break
  655. }
  656. case 'left': {
  657. tar_l = tri_l - tar_w - off_x - cor_w
  658. if (strFirst == '2') {
  659. tar_t = tri_t - off_y
  660. } else if (strFirst === '6') {
  661. tar_t = tri_t - (tar_w - tri_w) / 2 - off_y
  662. } else {
  663. tar_t = tri_t - (tar_h - tri_h) - off_y
  664. }
  665. cor_l = tar_l + cor_w
  666. cor_t = tri_t - (tar_w - cor_w) / 2
  667. break
  668. }
  669. }
  670. }
  671. // 尖角的显示
  672. if (cor_h && cor_w && this.corner) {
  673. this.corner.css({
  674. left: cor_l,
  675. top: cor_t,
  676. zIndex: this.s.zIndex + 1
  677. })
  678. }
  679. // 浮动框显示
  680. this.target.css({
  681. position: 'absolute',
  682. left: tar_l,
  683. top: tar_t,
  684. zIndex: this.s.zIndex
  685. })
  686. return this
  687. },
  688. createSharp: function (dir) {
  689. var bgColor; var bdColor; var color1 = ''; var color2 = ''
  690. var objReverse = {
  691. left: 'right',
  692. right: 'left',
  693. bottom: 'top',
  694. top: 'bottom'
  695. }; var dirReverse = objReverse[dir] || 'top'
  696. if (this.target) {
  697. bgColor = this.target.css('background-color')
  698. if (parseInt(this.target.css('border-' + dirReverse + '-width')) > 0) {
  699. bdColor = this.target.css('border-' + dirReverse + '-color')
  700. }
  701. if (bdColor && bdColor !== 'transparent') {
  702. color1 = 'style="color:' + bdColor + ';"'
  703. } else {
  704. color1 = 'style="display:none;"'
  705. }
  706. if (bgColor && bgColor !== 'transparent') {
  707. color2 = 'style="color:' + bgColor + ';"'
  708. } else {
  709. color2 = 'style="display:none;"'
  710. }
  711. }
  712. var html = '<div id="floatCorner_' + dir + '" class="float_corner float_corner_' + dir + '">' +
  713. '<span class="corner corner_1" ' + color1 + '>◆</span>' +
  714. '<span class="corner corner_2" ' + color2 + '>◆</span>' +
  715. '</div>'
  716. if (!$('#floatCorner_' + dir).size()) {
  717. $('body').append($(html))
  718. }
  719. this.corner = $('#floatCorner_' + dir)
  720. return this
  721. },
  722. targetHold: function () {
  723. if (this.s.hoverHold) {
  724. var delay = parseInt(this.s.hideDelay, 10) || 200
  725. if (this.target) {
  726. this.target.hover(function () {
  727. o.flagDisplay = true
  728. }, function () {
  729. if (o.timerHold) {
  730. clearTimeout(o.timerHold)
  731. }
  732. o.flagDisplay = false
  733. o.targetHold()
  734. })
  735. }
  736. o.timerHold = setTimeout(function () {
  737. o.displayDetect.call(o)
  738. }, delay)
  739. } else {
  740. this.displayDetect()
  741. }
  742. return this
  743. },
  744. loading: function () {
  745. this.target = $('<div class="float_loading"></div>')
  746. this.targetShow()
  747. this.target.removeData('width').removeData('height')
  748. return this
  749. },
  750. displayDetect: function () {
  751. // 显示与否检测与触发
  752. if (!this.flagDisplay && this.display) {
  753. this.targetHide()
  754. this.timerHold = null
  755. }
  756. return this
  757. },
  758. targetShow: function () {
  759. o.cornerClear()
  760. this.display = true
  761. this.container().setWidth().position()
  762. this.target.show()
  763. if ($.isFunction(this.s.showCall)) {
  764. this.s.showCall.call(this.trigger, this.target)
  765. }
  766. return this
  767. },
  768. targetHide: function () {
  769. this.display = false
  770. this.targetClear()
  771. this.cornerClear()
  772. if ($.isFunction(this.s.hideCall)) {
  773. this.s.hideCall.call(this.trigger)
  774. }
  775. this.target = null
  776. this.trigger = null
  777. this.s = {}
  778. this.targetProtect = false
  779. return this
  780. },
  781. targetClear: function () {
  782. if (this.target) {
  783. if (this.target.data('width')) {
  784. this.target.removeData('width').removeData('height')
  785. }
  786. if (this.targetProtect) {
  787. // 保护孩子
  788. this.target.children().hide().appendTo($('body'))
  789. }
  790. this.target.unbind().hide()
  791. }
  792. },
  793. cornerClear: function () {
  794. if (this.corner) {
  795. // 使用remove避免潜在的尖角颜色冲突问题
  796. this.corner.remove()
  797. }
  798. },
  799. target: null,
  800. trigger: null,
  801. s: {},
  802. cacheData: {},
  803. targetProtect: false
  804. }
  805. $.powerFloat = {}
  806. $.powerFloat.hide = function () {
  807. o.targetHide()
  808. }
  809. var defaults = {
  810. width: 'auto', // 可选参数:inherit,数值(px)
  811. offsets: {
  812. x: 0,
  813. y: 0
  814. },
  815. zIndex: 999,
  816. eventType: 'hover', // 事件类型,其他可选参数有:click, focus
  817. showDelay: 0, // 鼠标hover显示延迟
  818. hideDelay: 0, // 鼠标移出隐藏延时
  819. hoverHold: true,
  820. hoverFollow: false, // true或是关键字x, y
  821. targetMode: 'common', // 浮动层的类型,其他可选参数有:ajax, list, remind
  822. target: null, // target对象获取来源,优先获取,如果为null,则从targetAttr中获取。
  823. targetAttr: 'rel', // target对象获取来源,当targetMode为list时无效
  824. container: null, // 转载target的容器,可以使用"plugin"关键字,则表示使用插件自带容器类型
  825. reverseSharp: false, // 是否反向小三角的显示,默认ajax, remind是显示三角的,其他如list和自定义形式是不显示的
  826. position: '4-1', // trigger-target
  827. edgeAdjust: true, // 边缘位置自动调整
  828. showCall: $.noop,
  829. hideCall: $.noop
  830. }
  831. })(jQuery)