popoPicker.js 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015
  1. /*!
  2. * popoPicker.js v1.0
  3. * https://po-po.github.io/popoPicker
  4. * Released under the MIT License.
  5. */
  6. ;(function (window,document) {
  7. 'use strict';
  8. function extend() {
  9. var name, options, src, copy;
  10. var length = arguments.length;
  11. var target = arguments[0];
  12. for (var i = 1; i < length; i++) {
  13. options = arguments[i];
  14. if (options != null) {
  15. for (name in options) {
  16. src = target[name];
  17. copy = options[name];
  18. if (copy !== undefined) {
  19. target[name] = copy;
  20. }
  21. }
  22. }
  23. }
  24. return target;
  25. }
  26. var popoPicker = function (el, option) {
  27. //触摸移动
  28. var self = this;
  29. var option = extend({
  30. wheels: [],
  31. container:'body',
  32. scrollType: '3d',
  33. background: 'light',
  34. display: "bottom",
  35. headTitle: '',
  36. init: function () {},
  37. getResult: function () {},
  38. save: function () {},
  39. cancel: function () {}
  40. }, option);
  41. var clickTarget = document.querySelectorAll(el);
  42. var rows = 5;
  43. var itemHeight = 34;
  44. var itemSize2d = 9;
  45. var itemSize3d = 9;
  46. var scroll3dAngle = 360 / (itemSize3d * 2);
  47. var rs = {
  48. result: [],
  49. scrollIdx: null,
  50. scrollEvt: []
  51. };
  52. function getselectedIdx(wheel) {
  53. var index = 0;
  54. for (var i = 0; i < wheel.data.length; i++) {
  55. if (wheel.data[i].value == wheel.selected) {
  56. index = i;
  57. break;
  58. } else {
  59. index = 0;
  60. }
  61. }
  62. return index;
  63. }
  64. function generateItems(wheel, start, end, is3d) {
  65. var data = wheel.data;
  66. var html = '',
  67. value,
  68. display,
  69. len = data.length,
  70. infinite = wheel.infinite,
  71. selectedIdx = getselectedIdx(wheel);
  72. //选中的位置
  73. start += selectedIdx;
  74. end += selectedIdx;
  75. for (var i = start; i <= end; i++) {
  76. var idx = (i < 0 ? len + (i % len) : i) % len;
  77. value = data[idx].value;
  78. display = data[idx].display;
  79. if (is3d) {
  80. var deg = 0;
  81. var show = "list-item";
  82. deg = -(i - selectedIdx) * scroll3dAngle % 360;
  83. if (!infinite) {
  84. if (i < 0 || i > (len - 1)) {
  85. show = "none"
  86. } else {
  87. show = "list-item"
  88. }
  89. }
  90. html += '<li data-index="' + i + '" data-val="' + value + '" style="transform:rotateX(' + deg + 'deg) translateZ(' + (itemHeight * rows / 2) + 'px); display: ' + show + '">' + display + '</li>';
  91. } else {
  92. var opacity = 1;
  93. if (!infinite) {
  94. if (i < 0 || i > (len - 1)) {
  95. opacity = 0
  96. } else {
  97. opacity = 1
  98. }
  99. }
  100. html += '<li data-index="' + i + '" data-val="' + value + '" style="opacity: ' + opacity + '">' + display + '</li>';
  101. }
  102. }
  103. return html;
  104. }
  105. function createEl(wheels) {
  106. var html = '';
  107. html += '<div class="p-select-wrap '+ (option.scrollType == '3d' ? 'p-3d' : '') + (option.display == 'center' ? ' p-center' : '') +(option.background == 'dark' ? ' dark' : '')+'">';
  108. html += '<div class="p-select-main">';
  109. html += '<div class="p-select-head">';
  110. if (option.display != 'center') {
  111. html += '<a href="javascript:void(0)" class="p-select-cancel-btn">取消</a>';
  112. }
  113. if (option.headTitle != '') {
  114. html += '<div class="p-select-title">' + option.headTitle + '</div>';
  115. }
  116. if (option.display != 'center') {
  117. html += '<a href="javascript:void(0)" class="p-select-submit-btn">确认</a>';
  118. }
  119. html += '</div>';
  120. html += '<div class="p-select-body">';
  121. html += '<div class="p-select-line" '+ (option.scrollType=='3d' ? 'style="transform: translateZ(' + (itemHeight * rows / 2 + 4) + 'px)"':'') +'></div>';
  122. for (var i = 0; i < wheels.length; i++) {
  123. var label = wheels[i].label;
  124. html += '<div class="p-select-item">';
  125. html += '<div class="p-select-col">';
  126. html += '<div class="p-select-list" '+ (option.scrollType=='3d' ? 'style="transform: translateZ(' + (itemHeight * rows / 2 +3) + 'px)"':'') +'>';
  127. html += '<ul class="p-select-ul">';
  128. html += generateItems(wheels[i], -itemSize2d, itemSize2d, false);
  129. html += '</ul>';
  130. html += '</div>';
  131. if (option.scrollType == '3d') {
  132. html += '<ul class="p-select-wheel">';
  133. html += generateItems(wheels[i], -itemSize3d, itemSize3d, true);
  134. html += '</ul>';
  135. }
  136. html += '</div>';
  137. if (label) {
  138. html += '<div class="p-select-col p-select-label" '+ (option.scrollType=='3d' ? 'style="transform: translateZ(' + (itemHeight * rows / 2 + 4) + 'px)"':'') +'>' + label + '</div>';
  139. }
  140. html += '</div>';
  141. }
  142. html += '</div>';
  143. if (option.display == 'center') {
  144. html += '<div class="p-select-foot">';
  145. html += '<a href="javascript:void(0)" class="p-select-cancel-btn">取消</a>';
  146. html += '<a href="javascript:void(0)" class="p-select-submit-btn">确认</a>';
  147. html += '</div>';
  148. }
  149. html += '</div>';
  150. html += '<div class="p-select-mask"></div>';
  151. html += '</div>';
  152. var node = document.createElement("div");
  153. node.className = "p-scroll";
  154. node.innerHTML = html;
  155. document.querySelector(option.container).appendChild(node)
  156. }
  157. function snap(pos) {
  158. var pos = Math.round(pos),
  159. n1 = Math.round(pos % itemHeight),
  160. n2 = itemHeight / 2;
  161. if (Math.abs(n1) < n2) {
  162. return pos - n1;
  163. } else {
  164. return pos - n1 + (pos > 0 ? itemHeight : -itemHeight);
  165. }
  166. }
  167. function getVal(pos, data, infinite, selectedIdx) {
  168. var len = data.length,
  169. index = (Math.round(-pos / itemHeight) - itemSize2d + selectedIdx) % len,
  170. index = index < 0 ? len + index : index,
  171. dataIndex = Math.round(-pos / itemHeight) - itemSize2d + selectedIdx,
  172. result = {
  173. value: data[index].value,
  174. display: data[index].display,
  175. dataIndex: dataIndex
  176. };
  177. return result;
  178. }
  179. function getPosition(el) {
  180. var style = getComputedStyle(el),
  181. matrix,
  182. pref = ['t', 'webkitT', 'MozT', 'OT', 'msT'],
  183. px;
  184. for (var i = 0; i < pref.length; i++) {
  185. var v = pref[i];
  186. if (style[v + 'ransform'] !== undefined) {
  187. matrix = style[v + 'ransform'];
  188. break;
  189. }
  190. }
  191. matrix = matrix.split(')')[0].split(', ');
  192. px = Number(matrix[13] || matrix[5]);
  193. return px;
  194. }
  195. function isPC() {
  196. var userAgentInfo = navigator.userAgent;
  197. var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
  198. var flag = true;
  199. for (var i = 0; i < Agents.length; i++) {
  200. if (userAgentInfo.indexOf(Agents[i]) > 0) {
  201. flag = false;
  202. break;
  203. }
  204. }
  205. return flag;
  206. }
  207. function destroy() {
  208. rs = {
  209. result: [],
  210. scrollIdx: 0,
  211. scrollEvt :[],
  212. };
  213. var box = document.querySelector('.p-scroll');
  214. box.className += ' hide';
  215. setTimeout(function () {
  216. box.remove();
  217. }, 300)
  218. }
  219. this.Scroll = function (el, wheel, index, opt) {
  220. this.el = el;
  221. this.wheel = wheel;
  222. this.index = index;
  223. this.opt = extend({
  224. data: this.wheel.data,
  225. scrollEl2d: el.querySelector('.p-select-ul'),
  226. item2d: el.querySelectorAll('.p-select-ul li'),
  227. scrollY: -itemHeight * itemSize2d,
  228. marginTop: 0,
  229. dataLen: this.wheel.data.length,
  230. lastY: 1,
  231. moveY: 0,
  232. current: 0,
  233. infinite: this.wheel.infinite,
  234. rotateX: 0,
  235. selectedIdx: getselectedIdx(wheel),
  236. transTimer: null,
  237. scrollTimer: null,
  238. clickDown: false,
  239. inertia: true
  240. }, opt);
  241. if (option.scrollType == "3d") {
  242. this.opt.scrollEl3d = el.querySelector('.p-select-wheel');
  243. this.opt.item3d = el.querySelectorAll('.p-select-wheel li');
  244. }
  245. this.defaultScrollY = this.opt.scrollY;
  246. this.init();
  247. };
  248. this.Scroll.prototype = {
  249. init: function () {
  250. this.Run(0, this.opt.scrollY);
  251. if (isPC()) {
  252. this.el.addEventListener('mousedown', this.touchStart.bind(this), false);
  253. document.addEventListener('mousemove', this.touchMove.bind(this), false);
  254. document.addEventListener('mouseup', this.touchEnd.bind(this), false);
  255. } else {
  256. this.el.addEventListener('touchstart', this.touchStart.bind(this), false);
  257. this.el.addEventListener('touchmove', this.touchMove.bind(this), false);
  258. this.el.addEventListener('touchend', this.touchEnd.bind(this), false);
  259. this.el.addEventListener('touchcancel', this.touchEnd.bind(this), false);
  260. }
  261. var self = this;
  262. if (option.scrollType == '3d') {
  263. //3d点击事件
  264. this.itemClick(this.opt.item3d);
  265. } else {
  266. //2d点击事件
  267. this.itemClick(this.opt.item2d);
  268. }
  269. },
  270. itemClick: function (itemObj) {
  271. var self = this;
  272. for (var i = 0; i < itemObj.length; i++) {
  273. itemObj[i].addEventListener('click', function (e) {
  274. self.opt.inertia = false;
  275. var curIdx = Number(e.target.dataset.index);
  276. var lastIdx = rs.result[self.index].dataIndex;
  277. var diff = curIdx - lastIdx;
  278. self.cusTouch(diff);
  279. }, false)
  280. }
  281. },
  282. Run: function (interval, pos) {
  283. if (interval == 0) {
  284. this.opt.scrollEl2d.style.webkitTransition = "none";
  285. if (option.scrollType == "3d") {
  286. this.opt.scrollEl3d.style.webkitTransition = "none";
  287. }
  288. } else {
  289. this.opt.scrollEl2d.style.webkitTransition = "transform cubic-bezier(0.190, 1.000, 0.220, 1.000) " + interval + "ms";
  290. if (option.scrollType == "3d") {
  291. this.opt.scrollEl3d.style.webkitTransition = "transform cubic-bezier(0.190, 1.000, 0.220, 1.000) " + interval + "ms";
  292. }
  293. }
  294. this.opt.scrollEl2d.style.webkitTransform = "translate3d(0," + pos + "px, 0)";
  295. if (option.scrollType == "3d") {
  296. pos = Math.round(-(pos * (scroll3dAngle / itemHeight)) - 180);
  297. this.opt.scrollEl3d.style.webkitTransform = "rotateX(" + pos + "deg) translate3d(0,0,0)";
  298. }
  299. },
  300. scrollDone: function () {
  301. clearInterval(this.opt.scrollTimer);
  302. clearTimeout(this.opt.transTimer);
  303. },
  304. onMove: function (pos, cusDiff) {
  305. var self = this,
  306. pos = pos || getPosition(this.opt.scrollEl2d),
  307. index = Math.round(-pos / itemHeight) - itemSize2d,
  308. diff = index - this.opt.current;
  309. if (cusDiff != undefined || diff) {
  310. this.opt.current = index;
  311. //2D
  312. for (var i = 0; i < this.opt.item2d.length; i++) {
  313. var item = this.opt.item2d[i];
  314. var index = Number(item.getAttribute("data-index")) + diff,
  315. len = self.opt.dataLen,
  316. idx = (index < 0 ? len + (index % len) : index) % len,
  317. val = self.opt.data[idx].value,
  318. display = self.opt.data[idx].display;
  319. if (!self.opt.infinite) {
  320. if (index < 0 || index > (len - 1)) {
  321. item.style.opacity = "0"
  322. } else {
  323. item.style.opacity = "1"
  324. }
  325. }
  326. item.setAttribute("data-index", index);
  327. item.setAttribute("data-val", val);
  328. item.innerText = display;
  329. }
  330. if (option.scrollType == "3d") {
  331. //3D
  332. for (var i = 0; i < this.opt.item3d.length; i++) {
  333. var item = this.opt.item3d[i];
  334. var index = Number(item.getAttribute("data-index")) + diff,
  335. len = self.opt.dataLen,
  336. idx = (index < 0 ? len + (index % len) : index) % len,
  337. val = self.opt.data[idx].value,
  338. deg = -(index - self.opt.selectedIdx) * scroll3dAngle,
  339. display = self.opt.data[idx].display;
  340. if (!self.opt.infinite) {
  341. if (index < 0 || index > (len - 1)) {
  342. item.style.display = "none"
  343. } else {
  344. item.style.display = "list-item"
  345. }
  346. }
  347. item.setAttribute("data-index", index);
  348. item.setAttribute("data-val", val);
  349. item.setAttribute("data-idx", idx);
  350. item.innerText = display;
  351. item.style.webkitTransform = "rotateX(" + deg + "deg) translateZ(" + (itemHeight * rows / 2) + "px)";
  352. }
  353. }
  354. //2d margin-top
  355. this.opt.marginTop += diff * itemHeight;
  356. this.opt.scrollEl2d.style.marginTop = this.opt.marginTop + "px";
  357. }
  358. },
  359. touchStart: function (e) {
  360. if (e.type == 'touchstart') {
  361. this.opt.startY = e.targetTouches["0"].clientY;
  362. } else {
  363. this.opt.startY = e.clientY;
  364. this.opt.clickDown = true;
  365. }
  366. this.opt.startTime = new Date();
  367. },
  368. touchMove: function (e) {
  369. if (e.type == 'touchmove') {
  370. e.preventDefault();
  371. for (var i = 0; i < e.targetTouches.length; i++) {
  372. this.opt.curY = e.targetTouches[i].clientY;
  373. }
  374. } else {
  375. if (this.opt.clickDown) {
  376. this.opt.curY = e.clientY;
  377. } else {
  378. return false;
  379. }
  380. }
  381. this.opt.moveY = this.opt.curY - this.opt.startY;
  382. this.opt.distance = this.opt.scrollY + this.opt.moveY;
  383. if (this.opt.curY < this.opt.lastY) {
  384. //move up
  385. this.opt.direction = 1;
  386. } else if (this.opt.curY > this.opt.lastY) {
  387. //move down
  388. this.opt.direction = -1;
  389. }
  390. if (this.opt.direction) {
  391. this.onMove();
  392. this.opt.lastY = this.opt.curY;
  393. this.Run(0, this.opt.distance);
  394. }
  395. },
  396. touchEnd: function (e) {
  397. if (e.type == 'touchend') {
  398. this.opt.lastY = e.changedTouches["0"].clientY;
  399. } else {
  400. if (this.opt.clickDown) {
  401. this.opt.lastY = e.clientY;
  402. this.opt.clickDown = false;
  403. } else {
  404. return false;
  405. }
  406. }
  407. this.opt.endTime = new Date();
  408. var self = this,
  409. interval = this.opt.endTime - this.opt.startTime,
  410. speed = 500,
  411. addPos = 0;
  412. //模拟惯性
  413. if (this.opt.inertia && interval < 300) {
  414. speed = Math.abs(this.opt.moveY / interval);
  415. speed = Math.round(speed * 1000);
  416. addPos = speed / 3 * (this.opt.moveY < 0 ? -1 : 1);
  417. speed = speed < 500 ? 500 : speed;
  418. } else {
  419. addPos = this.opt.moveY;
  420. this.opt.inertia = true
  421. }
  422. this.opt.scrollY += snap(addPos);
  423. this.opt.moveY = 0;
  424. clearInterval(this.opt.scrollTimer);
  425. this.opt.scrollTimer = setInterval(function () {
  426. self.onMove();
  427. }, 100);
  428. clearTimeout(this.opt.transTimer);
  429. this.opt.transTimer = setTimeout(function () {
  430. self.onMove();
  431. self.scrollDone();
  432. }, speed);
  433. //非无限滚动阈值
  434. if (!this.opt.infinite) {
  435. var maxScroll = this.opt.selectedIdx * itemHeight - itemHeight * itemSize2d;
  436. var minScroll = this.opt.selectedIdx * itemHeight - itemHeight * (this.opt.dataLen - 1) - itemHeight * itemSize2d;
  437. if (this.opt.scrollY > maxScroll) {
  438. this.opt.scrollY = maxScroll;
  439. } else if (this.opt.scrollY < minScroll) {
  440. this.opt.scrollY = minScroll;
  441. }
  442. }
  443. this.Run(speed, this.opt.scrollY);
  444. var res = getVal(this.opt.scrollY, this.opt.data, this.opt.infinite, this.opt.selectedIdx);
  445. rs.result[this.index] = res;
  446. rs.scrollIdx = this.index;
  447. option.getResult(rs);
  448. },
  449. cusTouch: function (diff) {
  450. var e1 = {
  451. clientY: 0,
  452. targetTouches: [{clientY: 0}],
  453. type: "click"
  454. };
  455. var e2 = {
  456. clientY: -itemHeight * diff,
  457. targetTouches: [{clientY: -itemHeight * diff}],
  458. type: "click"
  459. };
  460. var e3 = {
  461. clientY: -itemHeight * diff,
  462. changedTouches: [{clientY: -itemHeight * diff}],
  463. type: "click"
  464. };
  465. this.touchStart(e1)
  466. this.touchMove(e2);
  467. this.touchEnd(e3);
  468. },
  469. scrollTo: function (val, interval) {
  470. this.wheel.selected = val;
  471. var selectedIdx = getselectedIdx(this.wheel);
  472. var diff = this.opt.selectedIdx - selectedIdx;
  473. this.opt.scrollY = this.defaultScrollY + diff * itemHeight;
  474. this.Run(interval, this.opt.scrollY);
  475. this.onMove(this.opt.scrollY, true);
  476. },
  477. removeItem: function (valArr) {
  478. var data = this.opt.data,
  479. resultVal = rs.result[this.index].value,
  480. removeLen = 0,
  481. moveEnd = false;
  482. for (var i = 0; i < data.length; i++) {
  483. for (var j = 0; j < valArr.length; j++) {
  484. if (data[i].value == valArr[j]) {
  485. //移除
  486. data.splice(i--, 1);
  487. removeLen++;
  488. } else {
  489. if (valArr[j] == resultVal) {
  490. moveEnd = true;
  491. }
  492. }
  493. }
  494. }
  495. if (moveEnd) {
  496. rs.result[this.index] = {
  497. value: data[data.length - 1].value,
  498. display: data[data.length - 1].display
  499. }
  500. }
  501. this.opt.dataLen = data.length;
  502. this.scrollTo(rs.result[this.index].value, 0);
  503. },
  504. appendItem: function (valArr) {
  505. var data = this.opt.data;
  506. //去重
  507. for (var i = 0; i < data.length; i++) {
  508. for (var j = 0; j < valArr.length; j++) {
  509. if (data[i].value == valArr[j].value) {
  510. valArr.splice(j--, 1)
  511. }
  512. }
  513. }
  514. //添加
  515. for (var i = 0; i < valArr.length; i++) {
  516. data.push(valArr[i]);
  517. }
  518. this.opt.dataLen = data.length;
  519. this.scrollTo(rs.result[this.index].value, 0);
  520. }
  521. };
  522. function init(wheels, target) {
  523. //创建DOM
  524. createEl(wheels);
  525. var el = document.querySelectorAll(".p-select-item");
  526. for (var i = 0; i < el.length; i++) {
  527. //滚动事件
  528. var scroll = new self.Scroll(el[i], wheels[i], i);
  529. //初始结果
  530. var res = getVal(scroll.opt.scrollY, scroll.opt.data, scroll.opt.infinite, scroll.opt.selectedIdx);
  531. rs.result.push(res);
  532. rs.scrollEvt.push(scroll);
  533. rs.scrollIdx = 0;
  534. }
  535. //传出初始结果
  536. option.init(rs);
  537. var submitBtn = document.querySelector('.p-select-submit-btn'),
  538. cancelBtn = document.querySelector('.p-select-cancel-btn'),
  539. mask = document.querySelector('.p-select-mask');
  540. submitBtn.addEventListener('click', function () {
  541. var attr_rs = [],
  542. display = [];
  543. for (var i = 0; i < rs.result.length; i++) {
  544. attr_rs.push(rs.result[i].value);
  545. display.push(rs.result[i].display)
  546. }
  547. target.setAttribute('data-value', attr_rs);
  548. if(target.isInput){
  549. target.value = display;
  550. }else{
  551. target.innerText = display;
  552. }
  553. option.getResult(rs);
  554. option.save(rs, target);
  555. self.target = target;
  556. destroy()
  557. }, false);
  558. cancelBtn.addEventListener('click', function () {
  559. option.cancel();
  560. destroy()
  561. }, false);
  562. mask.addEventListener('click', function () {
  563. option.cancel();
  564. destroy()
  565. }, false);
  566. document.querySelector('.p-scroll').addEventListener('touchmove', function (e) {
  567. e.preventDefault()
  568. }, false);
  569. }
  570. for (var i = 0; i < clickTarget.length; i++) {
  571. var item = clickTarget[i],
  572. wheels = option.wheels,
  573. isInput = item.localName == 'input' || item.localName == 'textarea',
  574. attr_rs = item.getAttribute('data-value');
  575. if(attr_rs){
  576. attr_rs = attr_rs.split(',');
  577. var display = [];
  578. for (var j=0;j<attr_rs.length;j++){
  579. wheels[j].selected = attr_rs[j];
  580. var idx = getselectedIdx(wheels[j])
  581. display.push(wheels[j].data[idx].display)
  582. }
  583. if(isInput){
  584. item.value = display;
  585. }else{
  586. item.innerText = display;
  587. }
  588. }
  589. if(isInput){
  590. item.setAttribute('readonly',"readonly");
  591. item.setAttribute('unselectable','on');
  592. }
  593. item.addEventListener('click', function () {
  594. var target = this,
  595. wheelsCopy = JSON.parse(JSON.stringify(wheels)),
  596. attr_rs = target.getAttribute('data-value');
  597. target.isInput = isInput;
  598. if(isInput){
  599. target.blur();
  600. }
  601. if (attr_rs) {
  602. attr_rs = attr_rs.split(',');
  603. for (var j = 0; j < attr_rs.length; j++) {
  604. wheelsCopy[j].selected = attr_rs[j];
  605. }
  606. init(wheelsCopy, target ,isInput);
  607. }else{
  608. init(wheels, target, isInput);
  609. }
  610. }, false)
  611. }
  612. };
  613. var popoDateTime = function(el,opt){
  614. var opt = extend({
  615. container:'body',
  616. scrollType: "3d",
  617. background:'light',
  618. showLabel: true, //显示label
  619. labelType:'symbol', //symbol符号 text文字 split分割(需date和time同时存在)
  620. display:"bottom",
  621. headResult: false,
  622. // date:true,
  623. // time:true,
  624. beginYear: new Date().getFullYear()-100,
  625. endYear:new Date().getFullYear()+100,
  626. startDate: '',
  627. save:function(){},
  628. cancel:function(){}
  629. },opt);
  630. function addZero(num){
  631. return num<10?"0"+num:String(num);
  632. }
  633. var d = new Date(),
  634. year = d.getFullYear(),
  635. month = d.getMonth() + 1,
  636. day = d.getDate(),
  637. hour = d.getHours(),
  638. minute = d.getMinutes(),
  639. beginYear = opt.beginYear,
  640. endYear = opt.endYear,
  641. yearData = [],
  642. monthData = [],
  643. // dayData = [],
  644. // hourData = [],
  645. // minuteData = [],
  646. lastValue = '',
  647. wheels = [
  648. {
  649. infinite: false,
  650. selected: addZero(year),
  651. label:"<span>-</span>",
  652. data: yearData
  653. },
  654. {
  655. infinite: true,
  656. selected: addZero(month),
  657. label:"<span></span>",
  658. data: monthData
  659. },
  660. ];
  661. for(var i=beginYear;i<=endYear;i++){
  662. yearData.push({value:addZero(i),display:addZero(i)});
  663. }
  664. //月
  665. for(var i=1;i<=12;i++){
  666. monthData.push({value:addZero(i),display:addZero(i)});
  667. }
  668. //Label控制
  669. if(!opt.showLabel){
  670. for(var i=0;i<wheels.length;i++){
  671. delete wheels[i].label;
  672. }
  673. }else{
  674. if(opt.labelType == 'text'){
  675. var text = ['年','月','日','时','分','秒']
  676. for(var i=0;i<wheels.length;i++){
  677. wheels[i].label = text[i];
  678. }
  679. }
  680. if(opt.labelType == 'split' && opt.date && opt.time){
  681. for(var i=0;i<wheels.length;i++){
  682. delete wheels[i].label;
  683. }
  684. wheels[2].label='<div class="p-select-time-split-1"></div>';
  685. }
  686. }
  687. //判断闰年
  688. function isLeapYear(year) {
  689. if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
  690. return true;
  691. } else {
  692. return false;
  693. }
  694. }
  695. //判断大小月
  696. function bigSmallMonth(dayObj,year,month){
  697. var smallMonth = (month=="04" || month=="06" || month=="09" || month=="11");
  698. dayObj.appendItem(
  699. [
  700. {value:"29",display:"29"},
  701. {value:"30",display:"30"},
  702. {value:"31",display:"31"}
  703. ]
  704. );
  705. if(smallMonth){
  706. dayObj.removeItem(["31"]);
  707. }else if(month=="02"){
  708. if(isLeapYear(year)){
  709. dayObj.removeItem(["30","31"]);
  710. }else{
  711. dayObj.removeItem(["29","30","31"]);
  712. }
  713. }
  714. }
  715. //获取结果
  716. function getLastVal(result) {
  717. if(result.length==5){
  718. lastValue = result[0].display+'-'+result[1].display+'-'+result[2].display+' '+result[3].display+':'+result[4].display;
  719. }else if (result.length==3){
  720. lastValue = result[0].display+'-'+result[1].display+'-'+result[2].display;
  721. } else{
  722. lastValue = result[0].display+'-'+result[1].display;
  723. }
  724. if(opt.headResult){
  725. var title = document.querySelector('.p-select-title');
  726. title.innerText = lastValue;
  727. }
  728. }
  729. //日期滚轮
  730. var p = new popoPicker(el,{
  731. wheels: wheels,
  732. scrollType:opt.scrollType,
  733. background: opt.background,
  734. display:opt.display,
  735. headTitle:opt.headResult?1:'',
  736. container:opt.container,
  737. init:function(rs){
  738. if(opt.date){
  739. var year = rs.result[0].value;
  740. var month = rs.result[1].value;
  741. bigSmallMonth(rs.scrollEvt[2],year,month);
  742. }
  743. getLastVal(rs.result)
  744. },
  745. getResult:function(rs){
  746. var n1 = opt.date && (rs.scrollIdx== 0 || rs.scrollIdx== 1);
  747. year = rs.result[0].value,
  748. month = rs.result[1].value;
  749. if(n1){
  750. bigSmallMonth(rs.scrollEvt[2],year,month);
  751. }
  752. getLastVal(rs.result)
  753. },
  754. save:function(rs, target){
  755. if(target.isInput){
  756. target.value = lastValue;
  757. }else{
  758. target.innerText = lastValue;
  759. }
  760. opt.save(lastValue, target);
  761. },
  762. cancel:function(){
  763. opt.cancel();
  764. }
  765. });
  766. //判断是否有自定义初始值
  767. var target = document.querySelectorAll(el);
  768. for(var i=0;i<target.length;i++){
  769. var item = target[i],
  770. isInput = item.localName == 'input' || item.localName == 'textarea',
  771. val = isInput?item.value:item.innerText;
  772. if(val){
  773. val = val.match(/\d+/g);
  774. item.setAttribute('data-value',val);
  775. }
  776. }
  777. };
  778. var popoYear = function(el,opt){
  779. var opt = extend({
  780. container:'body',
  781. scrollType: "3d",
  782. background:'light',
  783. showLabel: true, //显示label
  784. labelType:'symbol', //symbol符号 text文字 split分割(需date和time同时存在)
  785. display:"bottom",
  786. headResult: false,
  787. // date:true,
  788. // time:true,
  789. beginYear: new Date().getFullYear()-100,
  790. endYear:new Date().getFullYear()+100,
  791. startDate: '',
  792. save:function(){},
  793. cancel:function(){}
  794. },opt);
  795. function addZero(num){
  796. return num<10?"0"+num:String(num);
  797. }
  798. var d = new Date(),
  799. year = d.getFullYear(),
  800. month = d.getMonth() + 1,
  801. day = d.getDate(),
  802. hour = d.getHours(),
  803. minute = d.getMinutes(),
  804. beginYear = opt.beginYear,
  805. endYear = opt.endYear,
  806. yearData = [],
  807. monthData = [],
  808. // dayData = [],
  809. // hourData = [],
  810. // minuteData = [],
  811. lastValue = '',
  812. wheels = [
  813. {
  814. infinite: false,
  815. selected: addZero(year),
  816. label:"<span></span>",
  817. data: yearData
  818. }
  819. ];
  820. for(var i=beginYear;i<=endYear;i++){
  821. yearData.push({value:addZero(i),display:addZero(i)});
  822. }
  823. //月
  824. for(var i=1;i<=12;i++){
  825. monthData.push({value:addZero(i),display:addZero(i)});
  826. }
  827. //Label控制
  828. if(!opt.showLabel){
  829. for(var i=0;i<wheels.length;i++){
  830. delete wheels[i].label;
  831. }
  832. }else{
  833. if(opt.labelType == 'text'){
  834. var text = ['年','月','日','时','分','秒']
  835. for(var i=0;i<wheels.length;i++){
  836. wheels[i].label = text[i];
  837. }
  838. }
  839. if(opt.labelType == 'split' && opt.date && opt.time){
  840. for(var i=0;i<wheels.length;i++){
  841. delete wheels[i].label;
  842. }
  843. wheels[2].label='<div class="p-select-time-split-1"></div>';
  844. }
  845. }
  846. //判断闰年
  847. function isLeapYear(year) {
  848. if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
  849. return true;
  850. } else {
  851. return false;
  852. }
  853. }
  854. //判断大小月
  855. function bigSmallMonth(dayObj,year,month){
  856. var smallMonth = (month=="04" || month=="06" || month=="09" || month=="11");
  857. dayObj.appendItem(
  858. [
  859. {value:"29",display:"29"},
  860. {value:"30",display:"30"},
  861. {value:"31",display:"31"}
  862. ]
  863. );
  864. if(smallMonth){
  865. dayObj.removeItem(["31"]);
  866. }else if(month=="02"){
  867. if(isLeapYear(year)){
  868. dayObj.removeItem(["30","31"]);
  869. }else{
  870. dayObj.removeItem(["29","30","31"]);
  871. }
  872. }
  873. }
  874. //获取结果
  875. function getLastVal(result) {
  876. if(result.length==5){
  877. lastValue = result[0].display+'-'+result[1].display+'-'+result[2].display+' '+result[3].display+':'+result[4].display;
  878. }else if (result.length==3){
  879. lastValue = result[0].display+'-'+result[1].display+'-'+result[2].display;
  880. } else{
  881. lastValue = result[0].display;
  882. }
  883. if(opt.headResult){
  884. var title = document.querySelector('.p-select-title');
  885. title.innerText = lastValue;
  886. }
  887. }
  888. //日期滚轮
  889. var p = new popoPicker(el,{
  890. wheels: wheels,
  891. scrollType:opt.scrollType,
  892. background: opt.background,
  893. display:opt.display,
  894. headTitle:opt.headResult?1:'',
  895. container:opt.container,
  896. init:function(rs){
  897. if(opt.date){
  898. var year = rs.result[0].value;
  899. bigSmallMonth(rs.scrollEvt[2],year);
  900. }
  901. getLastVal(rs.result)
  902. },
  903. getResult:function(rs){
  904. var n1 = opt.date && (rs.scrollIdx== 0 || rs.scrollIdx== 1);
  905. year = rs.result[0].value
  906. if(n1){
  907. bigSmallMonth(rs.scrollEvt[2],year);
  908. }
  909. getLastVal(rs.result)
  910. },
  911. save:function(rs, target){
  912. if(target.isInput){
  913. target.value = lastValue;
  914. }else{
  915. target.innerText = lastValue;
  916. }
  917. opt.save(lastValue, target);
  918. },
  919. cancel:function(){
  920. opt.cancel();
  921. }
  922. });
  923. //判断是否有自定义初始值
  924. var target = document.querySelectorAll(el);
  925. for(var i=0;i<target.length;i++){
  926. var item = target[i],
  927. isInput = item.localName == 'input' || item.localName == 'textarea',
  928. val = isInput?item.value:item.innerText;
  929. if(val){
  930. val = val.match(/\d+/g);
  931. item.setAttribute('data-value',val);
  932. }
  933. }
  934. };
  935. window.popoPicker = popoPicker;
  936. window.popoDateTime = popoDateTime;
  937. window.popoYear = popoYear;
  938. })(window,document);