picker 区分 确认,还是点击外部取消,我这边把 picker.js 源码改了,请查看
xk-yw opened this issue · 1 comments
console.log("$111", $);
-
function($) {
"use strict";
var Picker = function (params) {
var p = this;
var defaults = {
updateValuesOnMomentum: false,
updateValuesOnTouchmove: true,
rotateEffect: false,
momentumRatio: 7,
freeMode: false,
// Common settings
scrollToInput: true,
inputReadOnly: true,
toolbar: true,
toolbarCloseText: '完成',
title: '请选择',
toolbarTemplate: '
{{closeText}}
{{title}}
};
params = params || {};
for (var def in defaults) {
if (typeof params[def] === 'undefined') {
params[def] = defaults[def];
}
}
p.params = params;
p.cols = [];
p.initialized = false;// Inline flag p.inline = p.params.container ? true : false; // 3D Transforms origin bug, only on safari var originBug = $.device.ios || (navigator.userAgent.toLowerCase().indexOf('safari') >= 0 && navigator.userAgent.toLowerCase().indexOf('chrome') < 0) && !$.device.android; // Should be converted to popover function isPopover() { var toPopover = false; if (!p.params.convertToPopover && !p.params.onlyInPopover) return toPopover; if (!p.inline && p.params.input) { if (p.params.onlyInPopover) toPopover = true; else { if ($.device.ios) { toPopover = $.device.ipad ? true : false; } else { if ($(window).width() >= 768) toPopover = true; } } } return toPopover; } function inPopover() { if (p.opened && p.container && p.container.length > 0 && p.container.parents('.popover').length > 0) return true; else return false; } // Value p.setValue = function (arrValues, transition) { var valueIndex = 0; for (var i = 0; i < p.cols.length; i++) { if (p.cols[i] && !p.cols[i].divider) { p.cols[i].setValue(arrValues[valueIndex], transition); valueIndex++; } } }; p.updateValue = function () { var newValue = []; var newDisplayValue = []; for (var i = 0; i < p.cols.length; i++) { if (!p.cols[i].divider) { newValue.push(p.cols[i].value); newDisplayValue.push(p.cols[i].displayValue); } } if (newValue.indexOf(undefined) >= 0) { return; } p.value = newValue; p.displayValue = newDisplayValue; if (p.params.onChange) { // p.params.onChange(p, p.value, p.displayValue); } if (p.input && p.input.length > 0) { $(p.input).trigger('change'); } }; // Columns Handlers p.initPickerCol = function (colElement, updateItems) { var colContainer = $(colElement); var colIndex = colContainer.index(); var col = p.cols[colIndex]; if (col.divider) return; col.container = colContainer; col.wrapper = col.container.find('.picker-items-col-wrapper'); col.items = col.wrapper.find('.picker-item'); var i, j; var wrapperHeight, itemHeight, itemsHeight, minTranslate, maxTranslate; col.replaceValues = function (values, displayValues) { col.destroyEvents(); col.values = values; col.displayValues = displayValues; var newItemsHTML = p.columnHTML(col, true); col.wrapper.html(newItemsHTML); col.items = col.wrapper.find('.picker-item'); col.calcSize(); col.setValue(col.values[0] || '', 0, true); col.initEvents(); }; col.calcSize = function () { if (!col.values.length) return; if (p.params.rotateEffect) { col.container.removeClass('picker-items-col-absolute'); if (!col.width) col.container.css({width:''}); } var colWidth, colHeight; colWidth = 0; colHeight = col.container[0].offsetHeight; wrapperHeight = col.wrapper[0].offsetHeight; itemHeight = col.items[0].offsetHeight; itemsHeight = itemHeight * col.items.length; minTranslate = colHeight / 2 - itemsHeight + itemHeight / 2; maxTranslate = colHeight / 2 - itemHeight / 2; if (col.width) { colWidth = col.width; if (parseInt(colWidth, 10) === colWidth) colWidth = colWidth + 'px'; col.container.css({width: colWidth}); } if (p.params.rotateEffect) { if (!col.width) { col.items.each(function () { var item = $(this); item.css({width:'auto'}); colWidth = Math.max(colWidth, item[0].offsetWidth); item.css({width:''}); }); col.container.css({width: (colWidth + 2) + 'px'}); } col.container.addClass('picker-items-col-absolute'); } }; col.calcSize(); col.wrapper.transform('translate3d(0,' + maxTranslate + 'px,0)').transition(0); var activeIndex = 0; var animationFrameId; // Set Value Function col.setValue = function (newValue, transition, valueCallbacks) { if (typeof transition === 'undefined') transition = ''; var newActiveIndex = col.wrapper.find('.picker-item[data-picker-value="' + newValue + '"]').index(); if(typeof newActiveIndex === 'undefined' || newActiveIndex === -1) { col.value = col.displayValue = newValue; return; } var newTranslate = -newActiveIndex * itemHeight + maxTranslate; // Update wrapper col.wrapper.transition(transition); col.wrapper.transform('translate3d(0,' + (newTranslate) + 'px,0)'); // Watch items if (p.params.updateValuesOnMomentum && col.activeIndex && col.activeIndex !== newActiveIndex ) { $.cancelAnimationFrame(animationFrameId); col.wrapper.transitionEnd(function(){ $.cancelAnimationFrame(animationFrameId); }); updateDuringScroll(); } // Update items col.updateItems(newActiveIndex, newTranslate, transition, valueCallbacks); }; col.updateItems = function (activeIndex, translate, transition, valueCallbacks) { if (typeof translate === 'undefined') { translate = $.getTranslate(col.wrapper[0], 'y'); } if(typeof activeIndex === 'undefined') activeIndex = -Math.round((translate - maxTranslate)/itemHeight); if (activeIndex < 0) activeIndex = 0; if (activeIndex >= col.items.length) activeIndex = col.items.length - 1; var previousActiveIndex = col.activeIndex; col.activeIndex = activeIndex; /* col.wrapper.find('.picker-selected, .picker-after-selected, .picker-before-selected').removeClass('picker-selected picker-after-selected picker-before-selected'); col.items.transition(transition); var selectedItem = col.items.eq(activeIndex).addClass('picker-selected').transform(''); var prevItems = selectedItem.prevAll().addClass('picker-before-selected'); var nextItems = selectedItem.nextAll().addClass('picker-after-selected'); */ //去掉 .picker-after-selected, .picker-before-selected 以提高性能 col.wrapper.find('.picker-selected').removeClass('picker-selected'); if (p.params.rotateEffect) { col.items.transition(transition); } var selectedItem = col.items.eq(activeIndex).addClass('picker-selected').transform(''); if (valueCallbacks || typeof valueCallbacks === 'undefined') { // Update values col.value = selectedItem.attr('data-picker-value'); col.displayValue = col.displayValues ? col.displayValues[activeIndex] : col.value; // On change callback if (previousActiveIndex !== activeIndex) { if (col.onChange) { col.onChange(p, col.value, col.displayValue); } p.updateValue(); } } // Set 3D rotate effect if (!p.params.rotateEffect) { return; } var percentage = (translate - (Math.floor((translate - maxTranslate)/itemHeight) * itemHeight + maxTranslate)) / itemHeight; col.items.each(function () { var item = $(this); var itemOffsetTop = item.index() * itemHeight; var translateOffset = maxTranslate - translate; var itemOffset = itemOffsetTop - translateOffset; var percentage = itemOffset / itemHeight; var itemsFit = Math.ceil(col.height / itemHeight / 2) + 1; var angle = (-18*percentage); if (angle > 180) angle = 180; if (angle < -180) angle = -180; // Far class if (Math.abs(percentage) > itemsFit) item.addClass('picker-item-far'); else item.removeClass('picker-item-far'); // Set transform item.transform('translate3d(0, ' + (-translate + maxTranslate) + 'px, ' + (originBug ? -110 : 0) + 'px) rotateX(' + angle + 'deg)'); }); }; function updateDuringScroll() { animationFrameId = $.requestAnimationFrame(function () { col.updateItems(undefined, undefined, 0); updateDuringScroll(); }); } // Update items on init if (updateItems) col.updateItems(0, maxTranslate, 0); var allowItemClick = true; var isTouched, isMoved, touchStartY, touchCurrentY, touchStartTime, touchEndTime, startTranslate, returnTo, currentTranslate, prevTranslate, velocityTranslate, velocityTime; function handleTouchStart (e) { if (isMoved || isTouched) return; e.preventDefault(); isTouched = true; var position = $.getTouchPosition(e); touchStartY = touchCurrentY = position.y; touchStartTime = (new Date()).getTime(); allowItemClick = true; startTranslate = currentTranslate = $.getTranslate(col.wrapper[0], 'y'); } function handleTouchMove (e) { if (!isTouched) return; e.preventDefault(); allowItemClick = false; var position = $.getTouchPosition(e); touchCurrentY = position.y; if (!isMoved) { // First move $.cancelAnimationFrame(animationFrameId); isMoved = true; startTranslate = currentTranslate = $.getTranslate(col.wrapper[0], 'y'); col.wrapper.transition(0); } e.preventDefault(); var diff = touchCurrentY - touchStartY; currentTranslate = startTranslate + diff; returnTo = undefined; // Normalize translate if (currentTranslate < minTranslate) { currentTranslate = minTranslate - Math.pow(minTranslate - currentTranslate, 0.8); returnTo = 'min'; } if (currentTranslate > maxTranslate) { currentTranslate = maxTranslate + Math.pow(currentTranslate - maxTranslate, 0.8); returnTo = 'max'; } // Transform wrapper col.wrapper.transform('translate3d(0,' + currentTranslate + 'px,0)'); // Update items col.updateItems(undefined, currentTranslate, 0, p.params.updateValuesOnTouchmove); // Calc velocity velocityTranslate = currentTranslate - prevTranslate || currentTranslate; velocityTime = (new Date()).getTime(); prevTranslate = currentTranslate; } function handleTouchEnd (e) { if (!isTouched || !isMoved) { isTouched = isMoved = false; return; } isTouched = isMoved = false; col.wrapper.transition(''); if (returnTo) { if (returnTo === 'min') { col.wrapper.transform('translate3d(0,' + minTranslate + 'px,0)'); } else col.wrapper.transform('translate3d(0,' + maxTranslate + 'px,0)'); } touchEndTime = new Date().getTime(); var velocity, newTranslate; if (touchEndTime - touchStartTime > 300) { newTranslate = currentTranslate; } else { velocity = Math.abs(velocityTranslate / (touchEndTime - velocityTime)); newTranslate = currentTranslate + velocityTranslate * p.params.momentumRatio; } newTranslate = Math.max(Math.min(newTranslate, maxTranslate), minTranslate); // Active Index var activeIndex = -Math.floor((newTranslate - maxTranslate)/itemHeight); // Normalize translate if (!p.params.freeMode) newTranslate = -activeIndex * itemHeight + maxTranslate; // Transform wrapper col.wrapper.transform('translate3d(0,' + (parseInt(newTranslate,10)) + 'px,0)'); // Update items col.updateItems(activeIndex, newTranslate, '', true); // Watch items if (p.params.updateValuesOnMomentum) { updateDuringScroll(); col.wrapper.transitionEnd(function(){ $.cancelAnimationFrame(animationFrameId); }); } // Allow click setTimeout(function () { allowItemClick = true; }, 100); } function handleClick(e) { if (!allowItemClick) return; $.cancelAnimationFrame(animationFrameId); /*jshint validthis:true */ var value = $(this).attr('data-picker-value'); col.setValue(value); } col.initEvents = function (detach) { var method = detach ? 'off' : 'on'; col.container[method]($.touchEvents.start, handleTouchStart); col.container[method]($.touchEvents.move, handleTouchMove); col.container[method]($.touchEvents.end, handleTouchEnd); col.items[method]('click', handleClick); }; col.destroyEvents = function () { col.initEvents(true); }; col.container[0].f7DestroyPickerCol = function () { col.destroyEvents(); }; col.initEvents(); }; p.destroyPickerCol = function (colContainer) { colContainer = $(colContainer); if ('f7DestroyPickerCol' in colContainer[0]) colContainer[0].f7DestroyPickerCol(); }; // Resize cols function resizeCols() { if (!p.opened) return; for (var i = 0; i < p.cols.length; i++) { if (!p.cols[i].divider) { p.cols[i].calcSize(); p.cols[i].setValue(p.cols[i].value, 0, false); } } } $(window).on('resize', resizeCols); // HTML Layout p.columnHTML = function (col, onlyItems) { var columnItemsHTML = ''; var columnHTML = ''; if (col.divider) { columnHTML += '<div class="picker-items-col picker-items-col-divider ' + (col.textAlign ? 'picker-items-col-' + col.textAlign : '') + ' ' + (col.cssClass || '') + '">' + col.content + '</div>'; } else { for (var j = 0; j < col.values.length; j++) { columnItemsHTML += '<div class="picker-item" data-picker-value="' + col.values[j] + '">' + (col.displayValues ? col.displayValues[j] : col.values[j]) + '</div>'; } columnHTML += '<div class="picker-items-col ' + (col.textAlign ? 'picker-items-col-' + col.textAlign : '') + ' ' + (col.cssClass || '') + '"><div class="picker-items-col-wrapper">' + columnItemsHTML + '</div></div>'; } return onlyItems ? columnItemsHTML : columnHTML; }; p.layout = function () { var pickerHTML = ''; var pickerClass = ''; var i; p.cols = []; var colsHTML = ''; for (i = 0; i < p.params.cols.length; i++) { var col = p.params.cols[i]; colsHTML += p.columnHTML(p.params.cols[i]); p.cols.push(col); } pickerClass = 'weui-picker-modal picker-columns ' + (p.params.cssClass || '') + (p.params.rotateEffect ? ' picker-3d' : '') + (p.params.cols.length === 1 ? ' picker-columns-single' : ''); pickerHTML = '<div class="' + (pickerClass) + '">' + (p.params.toolbar ? p.params.toolbarTemplate.replace(/{{closeText}}/g, p.params.toolbarCloseText).replace(/{{title}}/g, p.params.title) : '') + '<div class="picker-modal-inner picker-items">' + colsHTML + '<div class="picker-center-highlight"></div>' + '</div>' + '</div>'; p.pickerHTML = pickerHTML; }; // Input Events function openOnInput(e) { e.preventDefault(); if (p.opened) return; p.open(); if (p.params.scrollToInput && !isPopover()) { var pageContent = p.input.parents('.content'); if (pageContent.length === 0) return; var paddingTop = parseInt(pageContent.css('padding-top'), 10), paddingBottom = parseInt(pageContent.css('padding-bottom'), 10), pageHeight = pageContent[0].offsetHeight - paddingTop - p.container.height(), pageScrollHeight = pageContent[0].scrollHeight - paddingTop - p.container.height(), newPaddingBottom; var inputTop = p.input.offset().top - paddingTop + p.input[0].offsetHeight; if (inputTop > pageHeight) { var scrollTop = pageContent.scrollTop() + inputTop - pageHeight; if (scrollTop + pageHeight > pageScrollHeight) { newPaddingBottom = scrollTop + pageHeight - pageScrollHeight + paddingBottom; if (pageHeight === pageScrollHeight) { newPaddingBottom = p.container.height(); } pageContent.css({'padding-bottom': (newPaddingBottom) + 'px'}); } pageContent.scrollTop(scrollTop, 300); } } } function closeOnHTMLClick(e) { if (inPopover()) return; if (p.input && p.input.length > 0) { if (e.target !== p.input[0] && $(e.target).parents('.weui-picker-modal').length === 0) p.close(); } else { if ($(e.target).parents('.weui-picker-modal').length === 0) p.close(); } } if (p.params.input) { p.input = $(p.params.input); if (p.input.length > 0) { if (p.params.inputReadOnly) p.input.prop('readOnly', true); if (!p.inline) { p.input.on('click', openOnInput); } if (p.params.inputReadOnly) { p.input.on('focus mousedown', function (e) { e.preventDefault(); }); } } } if (!p.inline) $('html').on('click', closeOnHTMLClick); // Open function onPickerClose(str) { p.opened = false; if (p.input && p.input.length > 0) p.input.parents('.page-content').css({'padding-bottom': ''}); if (p.params.onClose && str == "close") p.params.onClose(); else if (p.params.onComfirn && str == "comfirn") p.params.onComfirn(p); // Destroy events p.container.find('.picker-items-col').each(function () { p.destroyPickerCol(this); }); } p.opened = false; p.open = function () { var toPopover = isPopover(); if (!p.opened) { // Layout p.layout(); // Append if (toPopover) { p.pickerHTML = '<div class="popover popover-picker-columns"><div class="popover-inner">' + p.pickerHTML + '</div></div>'; p.popover = $.popover(p.pickerHTML, p.params.input, true); p.container = $(p.popover).find('.weui-picker-modal'); $(p.popover).on('close', function () { onPickerClose("close"); }); $(p.popover).on("comfirn", function () { onPickerClose("comfirn"); }) } else if (p.inline) { p.container = $(p.pickerHTML); p.container.addClass('picker-modal-inline'); $(p.params.container).append(p.container); } else { p.container = $($.openPicker(p.pickerHTML)); $(p.container) .on('close', function () { onPickerClose("close"); }); $(p.container) .on('comfirn', function () { onPickerClose("comfirn"); }); } // Store picker instance p.container[0].f7Picker = p; // Init Events p.container.find('.picker-items-col').each(function () { var updateItems = true; if ((!p.initialized && p.params.value) || (p.initialized && p.value)) updateItems = false; p.initPickerCol(this, updateItems); }); // Set value if (!p.initialized) { if (p.params.value) { p.setValue(p.params.value, 0); } } else { if (p.value) p.setValue(p.value, 0); } } // Set flag p.opened = true; p.initialized = true; if (p.params.onOpen) p.params.onOpen(p); }; // Close p.close = function (force) { if (!p.opened || p.inline) return; if (inPopover()) { $.closePicker(p.popover); return; } else { $.closePicker(p.container); return; } }; // Destroy p.destroy = function () { p.close(); if (p.params.input && p.input.length > 0) { p.input.off('click focus', openOnInput); $(p.input).data('picker', null); } $('html').off('click', closeOnHTMLClick); $(window).off('resize', resizeCols); }; if (p.inline) { p.open(); } return p;
};
$(document).on("click", ".close-picker", function() {
var pickerToClose = $('.weui-picker-modal.weui-picker-modal-visible');
if (pickerToClose.length > 0) {
$.closePicker(pickerToClose);
}
});$(document).on("click", ".comfirn-picker", function() {
var pickerToClose = $('.weui-picker-modal.weui-picker-modal-visible');
if (pickerToClose.length > 0) {
$.comfirnPicker(pickerToClose);
}
});$(document).on("click")
//修复picker会滚动页面的bug
$(document).on($ .touchEvents.move, ".picker-modal-inner", function(e) {
e.preventDefault();
});$.openPicker = function(tpl, className, callback) {
if(typeof className === "function") {
callback = className;
className = undefined;
}$.closePicker();
var container = $("
").appendTo(document.body);
container.show();container.addClass("weui-picker-container-visible");
//关于布局的问题,如果直接放在body上,则做动画的时候会撑开body高度而导致滚动条变化。
var dialog = $(tpl).appendTo(container);dialog.width(); //通过取一次CSS值,强制浏览器不能把上下两行代码合并执行,因为合并之后会导致无法出现动画。
dialog.addClass("weui-picker-modal-visible");
callback && container.on("close", callback);
return dialog;
}$.updatePicker = function(tpl) {
var container = $(".weui-picker-container-visible");
if(!container[0]) return false;container.html("");
var dialog = $(tpl).appendTo(container);
dialog.addClass("weui-picker-modal-visible");
return dialog;
}$.closePicker = function(container, callback) {
if(typeof container === "function") callback = container;
$(".weui-picker-modal-visible").removeClass("weui-picker-modal-visible").transitionEnd(function() {
$(this).parent().remove();
callback && callback();
}).trigger("close");
};$.comfirnPicker = function (container, callback) {
if(typeof container === "function") callback = container;
$(".weui-picker-modal-visible").removeClass("weui-picker-modal-visible").transitionEnd(function() {
$(this).parent().remove();
callback && callback();
}).trigger("comfirn");
};$.fn.picker = function(params) {
var args = arguments;
return this.each(function() {
if(!this) return;
var$this = $ (this);var picker = $this.data("picker"); if(!picker) { params = $.extend({ input: this }, params || {}) // https://github.com/lihongxun945/jquery-weui/issues/432 var inputValue = $this.val(); if(params.value === undefined && inputValue !== "") { params.value = (params.cols && params.cols.length > 1) ? inputValue.split(" ") : [inputValue]; } var p = $.extend({input: this}, params); picker = new Picker(p); $this.data("picker", picker); } if(typeof params === typeof "a") { picker[params].apply(picker, Array.prototype.slice.call(args, 1)); }
});
};
}($);
对了,这行被我注释掉了,放出来吧。
p.params.onChange(p, p.value, p.displayValue);