123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- /**
- * Input(TODO resize)
- * @param {type} $
- * @param {type} window
- * @param {type} document
- * @returns {undefined}
- */
- (function($, window, document) {
- var CLASS_ICON = $.className('icon');
- var CLASS_ICON_CLEAR = $.className('icon-clear');
- var CLASS_ICON_SPEECH = $.className('icon-speech');
- var CLASS_ICON_SEARCH = $.className('icon-search');
- var CLASS_ICON_PASSWORD = $.className('icon-eye');
- var CLASS_INPUT_ROW = $.className('input-row');
- var CLASS_PLACEHOLDER = $.className('placeholder');
- var CLASS_TOOLTIP = $.className('tooltip');
- var CLASS_HIDDEN = $.className('hidden');
- var CLASS_FOCUSIN = $.className('focusin');
- var SELECTOR_ICON_CLOSE = '.' + CLASS_ICON_CLEAR;
- var SELECTOR_ICON_SPEECH = '.' + CLASS_ICON_SPEECH;
- var SELECTOR_ICON_PASSWORD = '.' + CLASS_ICON_PASSWORD;
- var SELECTOR_PLACEHOLDER = '.' + CLASS_PLACEHOLDER;
- var SELECTOR_TOOLTIP = '.' + CLASS_TOOLTIP;
- var findRow = function(target) {
- for (; target && target !== document; target = target.parentNode) {
- if (target.classList && target.classList.contains(CLASS_INPUT_ROW)) {
- return target;
- }
- }
- return null;
- };
- var Input = function(element, options) {
- this.element = element;
- this.options = options || {
- actions: 'clear'
- };
- if (~this.options.actions.indexOf('slider')) { //slider
- this.sliderActionClass = CLASS_TOOLTIP + ' ' + CLASS_HIDDEN;
- this.sliderActionSelector = SELECTOR_TOOLTIP;
- } else { //clear,speech,search
- if (~this.options.actions.indexOf('clear')) {
- this.clearActionClass = CLASS_ICON + ' ' + CLASS_ICON_CLEAR + ' ' + CLASS_HIDDEN;
- this.clearActionSelector = SELECTOR_ICON_CLOSE;
- }
- if (~this.options.actions.indexOf('speech')) { //only for 5+
- this.speechActionClass = CLASS_ICON + ' ' + CLASS_ICON_SPEECH;
- this.speechActionSelector = SELECTOR_ICON_SPEECH;
- }
- if (~this.options.actions.indexOf('search')) {
- this.searchActionClass = CLASS_PLACEHOLDER;
- this.searchActionSelector = SELECTOR_PLACEHOLDER;
- }
- if (~this.options.actions.indexOf('password')) {
- this.passwordActionClass = CLASS_ICON + ' ' + CLASS_ICON_PASSWORD;
- this.passwordActionSelector = SELECTOR_ICON_PASSWORD;
- }
- }
- this.init();
- };
- Input.prototype.init = function() {
- this.initAction();
- this.initElementEvent();
- };
- Input.prototype.initAction = function() {
- var self = this;
- var row = self.element.parentNode;
- if (row) {
- if (self.sliderActionClass) {
- self.sliderAction = self.createAction(row, self.sliderActionClass, self.sliderActionSelector);
- } else {
- if (self.searchActionClass) {
- self.searchAction = self.createAction(row, self.searchActionClass, self.searchActionSelector);
- self.searchAction.addEventListener('tap', function(e) {
- $.focus(self.element);
- e.stopPropagation();
- });
- }
- if (self.speechActionClass) {
- self.speechAction = self.createAction(row, self.speechActionClass, self.speechActionSelector);
- self.speechAction.addEventListener('click', $.stopPropagation);
- self.speechAction.addEventListener('tap', function(event) {
- self.speechActionClick(event);
- });
- }
- if (self.clearActionClass) {
- self.clearAction = self.createAction(row, self.clearActionClass, self.clearActionSelector);
- self.clearAction.addEventListener('tap', function(event) {
- self.clearActionClick(event);
- });
- }
- if (self.passwordActionClass) {
- self.passwordAction = self.createAction(row, self.passwordActionClass, self.passwordActionSelector);
- self.passwordAction.addEventListener('tap', function(event) {
- self.passwordActionClick(event);
- });
- }
- }
- }
- };
- Input.prototype.createAction = function(row, actionClass, actionSelector) {
- var action = row.querySelector(actionSelector);
- if (!action) {
- var action = document.createElement('span');
- action.className = actionClass;
- if (actionClass === this.searchActionClass) {
- action.innerHTML = '<span class="' + CLASS_ICON + ' ' + CLASS_ICON_SEARCH + '"></span><span>' + this.element.getAttribute('placeholder') + '</span>';
- this.element.setAttribute('placeholder', '');
- if (this.element.value.trim()) {
- row.classList.add($.className('active'));
- }
- }
- row.insertBefore(action, this.element.nextSibling);
- }
- return action;
- };
- Input.prototype.initElementEvent = function() {
- var element = this.element;
- if (this.sliderActionClass) {
- var tooltip = this.sliderAction;
- var timer = null;
- var showTip = function() { //每次重新计算是因为控件可能被隐藏,初始化时计算是不正确的
- tooltip.classList.remove(CLASS_HIDDEN);
- var offsetLeft = element.offsetLeft;
- var width = element.offsetWidth - 28;
- var tooltipWidth = tooltip.offsetWidth;
- var distince = Math.abs(element.max - element.min);
- var scaleWidth = (width / distince) * Math.abs(element.value - element.min);
- tooltip.style.left = (14 + offsetLeft + scaleWidth - tooltipWidth / 2) + 'px';
- tooltip.innerText = element.value;
- if (timer) {
- clearTimeout(timer);
- }
- timer = setTimeout(function() {
- tooltip.classList.add(CLASS_HIDDEN);
- }, 1000);
- };
- element.addEventListener('input', showTip);
- element.addEventListener('tap', showTip);
- element.addEventListener($.EVENT_MOVE, function(e) {
- e.stopPropagation();
- });
- } else {
- if (this.clearActionClass) {
- var action = this.clearAction;
- if (!action) {
- return;
- }
- $.each(['keyup', 'change', 'input', 'focus', 'cut', 'paste'], function(index, type) {
- (function(type) {
- element.addEventListener(type, function() {
- action.classList[element.value.trim() ? 'remove' : 'add'](CLASS_HIDDEN);
- });
- })(type);
- });
- element.addEventListener('blur', function() {
- action.classList.add(CLASS_HIDDEN);
- });
- }
- if (this.searchActionClass) {
- element.addEventListener('focus', function() {
- element.parentNode.classList.add($.className('active'));
- });
- element.addEventListener('blur', function() {
- if (!element.value.trim()) {
- element.parentNode.classList.remove($.className('active'));
- }
- });
- }
- }
- };
- Input.prototype.setPlaceholder = function(text) {
- if (this.searchActionClass) {
- var placeholder = this.element.parentNode.querySelector(SELECTOR_PLACEHOLDER);
- placeholder && (placeholder.getElementsByTagName('span')[1].innerText = text);
- } else {
- this.element.setAttribute('placeholder', text);
- }
- };
- Input.prototype.passwordActionClick = function(event) {
- if (this.element.type === 'text') {
- this.element.type = 'password';
- } else {
- this.element.type = 'text';
- }
- this.passwordAction.classList.toggle($.className('active'));
- event.preventDefault();
- };
- Input.prototype.clearActionClick = function(event) {
- var self = this;
- self.element.value = '';
- $.focus(self.element);
- self.clearAction.classList.add(CLASS_HIDDEN);
- event.preventDefault();
- };
- Input.prototype.speechActionClick = function(event) {
- if (window.plus) {
- var self = this;
- var oldValue = self.element.value;
- self.element.value = '';
- document.body.classList.add(CLASS_FOCUSIN);
- plus.speech.startRecognize({
- engine: 'iFly'
- }, function(s) {
- self.element.value += s;
- $.focus(self.element);
- plus.speech.stopRecognize();
- $.trigger(self.element, 'recognized', {
- value: self.element.value
- });
- if (oldValue !== self.element.value) {
- $.trigger(self.element, 'change');
- $.trigger(self.element, 'input');
- }
- // document.body.classList.remove(CLASS_FOCUSIN);
- }, function(e) {
- document.body.classList.remove(CLASS_FOCUSIN);
- });
- } else {
- alert('only for 5+');
- }
- event.preventDefault();
- };
- $.fn.input = function(options) {
- var inputApis = [];
- this.each(function() {
- var inputApi = null;
- var actions = [];
- var row = findRow(this.parentNode);
- if (this.type === 'range' && row.classList.contains($.className('input-range'))) {
- actions.push('slider');
- } else {
- var classList = this.classList;
- if (classList.contains($.className('input-clear'))) {
- actions.push('clear');
- }
- if (!($.os.android && $.os.stream) && classList.contains($.className('input-speech'))) {
- actions.push('speech');
- }
- if (classList.contains($.className('input-password'))) {
- actions.push('password');
- }
- if (this.type === 'search' && row.classList.contains($.className('search'))) {
- actions.push('search');
- }
- }
- var id = this.getAttribute('data-input-' + actions[0]);
- if (!id) {
- id = ++$.uuid;
- inputApi = $.data[id] = new Input(this, {
- actions: actions.join(',')
- });
- for (var i = 0, len = actions.length; i < len; i++) {
- this.setAttribute('data-input-' + actions[i], id);
- }
- } else {
- inputApi = $.data[id];
- }
- inputApis.push(inputApi);
- });
- return inputApis.length === 1 ? inputApis[0] : inputApis;
- };
- $.ready(function() {
- $($.classSelector('.input-row input')).input();
- });
- })(mui, window, document);
|