Ответы пользователя по тегу JavaScript
  • Верстка сайта, возможно ли так организовать структуру и переходы(в описании) ??

    devellopah
    @devellopah
    тебе нужно смотреть в сторону библиотек, делающих page transition, типа barba.js
    и уж вряд ли стоит изобретать колесо
    Ответ написан
    Комментировать
  • Почему элемент в консоле неопределён?

    devellopah
    @devellopah
    введи в консоли $('.logo')
    Ответ написан
    Комментировать
  • Таймер на JS работает не корректно при обновлении дива почему?

    devellopah
    @devellopah
    думаю так будет чуток лучше
    const timer = document.getElementById("my_timer");
    
    
    // выбери "время в секундах" или число вызовов функции startTimer() 
    let total = 60;
    
    // сохраним в переменную, чтобы потом очистить
    let timerInterval = setInterval(tick, 1000);
    
    // достаём число, минуты, секунды в числовом формате
    const getHours = x => Math.floor( total / 3600 )
    const getMinutes = x => Math.floor( total % 3600 / 60)
    const getSeconds = x => Math.floor( total % 3600 % 60 )
    
    // приводим вышеуказанные значения в нужный для отображения вид
    const prepair = val => val < 10 ? '0' + val : val
    
    // эта функция принимает фукцию и вызывает её, передав в качестве аргумента total
    const passTotal = fn => fn(total);
    
    
    function tick() {
    	// типа делаем [a, b] = [10, 20] и получаем a = 10 и b = 20 (деструктивное присваивание)
    	const [hour, minutes, seconds] = [getHours, getMinutes, getSeconds].map(passTotal)
    	
    	if (total <= 0) {
    		clearInterval(timerInterval)
    		// return fetchAnotherQuestion()
    	}
    		// отображаем строку
       timer.textContent = prepair(hour)+ ':' + prepair(minutes) + ':' + prepair(seconds)
       
    	 // уменьшаем "время в секундах" на "одну секунду"
    	 total--;
    }
    Ответ написан
    Комментировать
  • Как сравнить 2 строки на соответствие?

    devellopah
    @devellopah
    var name1 = 'Игорь Петрович Иванов';
    var name2 = 'игорь петровичиванов и ещё какие то слова';
    
    function sanitize(str) {
    	return str.toLowerCase().replace(/[^a-z\u0400-\u04FF]/gi,"");
    }
    
    sanitize(name2).includes(sanitize(name1)); // true
    Ответ написан
    Комментировать
  • Неповторяемое rand число?

    devellopah
    @devellopah
    class UnrepeatedRandomInteger {
    	
    	constructor(min, max) {
    		this.min = min;
    		this.max = max;
    		this.range = [];
    		this.defaultRange = [];
    		
    		const makeRange = () => {
    			const range = [];
    			
    			for(let i = this.min; i <= this.max; i++) {
    				range.push(i);
    			}
    			
    			this.range = range;
    			this.defaultRange = range;
    		};
    		
    		makeRange();
    	}
    
    	random() {
    		const index =  Math.floor( Math.random() * this.range.length );
    		const victim = this.range[index];
    		const newRange = this.range.filter(item => item !== victim);
    		
    		this.range = newRange;
    		
    		return victim;
    	}
    	
    	restore() {
    		this.range = this.defaultRange;
    	}
    	
    	emptify() {
    		this.defaultRange.forEach(item => {
    			console.log('i am dying slowly...', this.range);
    			console.log('i am gonna be dropped now and never after! ', this.random());
    			console.log('\n\n');
    		});
    	}
    
    }

    full version - https://repl.it/IG24/1
    Ответ написан
  • В чём разница между new и Object.create()?

    devellopah
    @devellopah
    а вот так не пробовал?
    Ответ написан
    Комментировать
  • Как разрешить ввод только цифр и одной точки с заменой запятой?

    devellopah
    @devellopah
    адаптируй под свои нужды - https://jsbin.com/yeyafe/edit?js,output

    const input = document.querySelector('input');
    const pattern = /^\d+(\.?)\d*$/g;
    
    const allowedCodes = [8, 9, 27, 35, 36, 37, 38, 39, 46, 110, 188];
    
    input.addEventListener('input', onInput);
    
    function onInput(e) {
    	
    	const value = this.value;
    	
    	if( !(value.match(pattern) || allowedCodes.some(code => code === e.keyCode)) ) {
    		this.value = value.slice(0, -1);
    	}
    }
    Ответ написан
  • Как поместить объект в функцию и работать с ним?

    devellopah
    @devellopah
    я тут немного пофантазировал...
    function isNum(pretendent) {
    	return typeof pretendent === "number" && !Number.isNaN(pretendent);
    }
    
    function validate(list) {
    	if( list.every( (item) => isNum(item) ) ) {
    		return true;
    	}
    	console.log('All provided arguments should be numbers!');
    	return false;
    }
    
    const operations = {
    	addTwo: (a, b) => a + b,
    	substractTwo: (a, b) => a - b,
    	divideTwo: (a, b) => a / b,
    	multiplyTwo: (a, b) => a * b
    };
    
    function take(fNum) {
    	if ( !isNum(fNum) )  {
    		console.log('You are supposed to provide number!');
    		return;
    	}
    	return {
    		add: (...args) => validate(args) && args.reduce(operations.addTwo, fNum),
    		substract: (...args) => validate(args) && args.reduce(operations.substractTwo, fNum),
    		divide: (...args) => validate(args) && args.reduce(operations.divideTwo, fNum),
    		multiply: (...args) => validate(args) && args.reduce(operations.multiplyTwo, fNum)
    	};
    }


    https://repl.it/ID7B
    Ответ написан
    Комментировать
  • Как решить задачу js?

    devellopah
    @devellopah
    // validation patterns
    const fname =  /^[a-z ]{5,}$/i;
    const sname = /^[a-z ]{5,}$/i;
    const email = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,6})+$/;
    const phone = /^\+7[0-9]{10}$/;
    
    const patterns = { 
    	name: fname, 
    	surname: sname, 
    	email, 
    	phone, 
    	mobilePhone: phone, 
    	workPhone: phone 
    };
    
    // forms
    const forms = [
      { name: 'Ivan Ivanov', email: 'ivan@test.co', phone: '+79212753690' },
      { name: 'III', email: 'ivan@test', phone: '11111' },
      { name: 'Ivan Ivanov', email: 'ivan@test.co', phone: '+79212753690', mobilePhone: '+79212753690'},
      {},
      { name: 'Ivan Ivanov', email: 'ivan@test.co', phone: '+79212753690', mobilePhone: 'фывыафывафыв'},
      { name: 'Ivan Ivanov', email: 'ivan@test.co', phone: '+79212753690', mobilePhone: '+79212753690', workPhone: 'asfdadsfd', surname: ''},
      { surname: 'Ivan Ivanov', mobilePhone: 'фывафыва', name: 'Ivan Ivanov', email: 'ivan@test.co', phone: '+79212753690', workPhone: '+79212753690'
      }
    ];
    
    validateAll(forms, patterns);
    
    function validateAll(forms, patterns) {
    	return forms.map( form => validate(form, patterns) );
    }
    
    
    function validate(form, patterns) {
    	const keys = Object.keys(form);
    	const errors = [];
    	
    	if(!keys.length) return {target: {}, errors: ['empty form is provided']};
    	
    	keys.forEach(key => {
    		if( !patterns[key].test(form[key]) ) {
    			errors.push(`${key} value is invalid`);
    		}
    	});
    	
    	return {
    		target: JSON.stringify(form),
    		errors
    	};
    }


    https://repl.it/IBuo/1

    spoiler
    p.s. если захочешь отблагодарить - https://money.yandex.ru/to/410013748902785 (не принципиально)
    Ответ написан
    Комментировать
  • Куда подевалось значение?

    devellopah
    @devellopah
    if (typeof head === 'undefined')

    p.s. я бы сделал так
    const reverse = arr =>
    	arr.length > 1 
    		? [arr[arr.length - 1]].concat( reverse(arr.slice(0, -1)) ) 
    		: arr[0];
    Ответ написан
    Комментировать
  • Почему рекурсия не останавливается?

    devellopah
    @devellopah
    я позволил себе добавить второй аргумент(чтобы наращивать строку, указывающую путь до свойства)
    если ты не против, то можно примерно так

    const trunk = {
        listItem1: 1,
        listItem2: {
            subListItem: 1,
            subListItem2: {
                subsubListItem1: 1,
                subsubListItem2: 2
            }
        },
        listItem3: 3
    };
    
    const ones = [];
    
    traverse(trunk, 'root');
    
    function traverse(obj, path) {
    	for(let key in obj) {
    		const newPath = path + ' > ' + key;
    		
    		if (obj[key].constructor.name === "Object") {
    			
    			// console.log(newPath);
    	  	return traverse(obj[key], newPath);
    	  }
    	  
    	  if(obj[key] == "1") {
    	  	ones.push(newPath);
    	  }
    	  
    	}
    	
    	console.log('properties\' pathes which value is equal to 1 \n\n' , ones);
    }
    Ответ написан
    Комментировать
  • Как начать разрабатывать на React?

    devellopah
    @devellopah
    1) у них отличная документация с туториалом
    2) https://github.com/petehunt/react-howto
    Ответ написан
    Комментировать
  • Почему Array(10).map(...) не работает?

    devellopah
    @devellopah
    arr1.fill().forEach((el, idx) => {
      console.log(idx, el);
    });

    ------------------------------------
    Под капотом (не точно)

    forEach
    function forEach(arr, fn) {
    	var i, len = arr.length;
    	
    	for(i = 0; i < len; i++) {
    		fn(arr[i], i, arr);
    	}
    }


    map

    function map(arr, fn) {
    	var i, len = arr.length, result = [];
    	
    	for(i = 0; i < len; i++) {
    		result.push(fn(arr[i], i, arr));
    	}
    	
    	return result;
    }


    как видишь под капотом всё "как обычно". То есть эти методы всего лишь декларативные обёртки поверх всё того же императивного кода. Другими словами, ты не говоришь "как делать", но говоришь "что делать".
    Ответ написан
    Комментировать
  • Как перемножить текстовые значения столбцов?

    devellopah
    @devellopah
    можно так

    const combine = (names, lastNames) =>
    	names.map(name => 
    		lastNames.map(lastName => name + ' ' + lastName)
    	);
    
    
    combine(['John', 'Kenny', 'Mark'], ['Jackson', 'Duglas', 'Kirk']);
    Ответ написан
    Комментировать
  • Небольшой, но масштабируемый js mvc framework?

    devellopah
    @devellopah
    Ответ написан
    Комментировать
  • Как увязать React router и Redux-редьюсеры?

    devellopah
    @devellopah
    просто мысли вслух

    // types
    const types = {
    	UPDATE_FIELD: 'UPDATE_FIELD',
    };
    //types
    
    // operations
    const updateField = (value, error) => (
    	{ type: types.UPDATE_FIELD, value, error }
    );
    
    // reducer
    const initialState = { 
    	values: {email: '', password: ''}, 
    	errors: { email: '', password: '' } 
    };
    
    function someFormReducer(state = initialState, action) {
    	switch(action.type) {
    		case types.UPDATE_FIELD: {
    			return { 
    				values: { ...state.values, ...action.value }, 
    				errors: { ...state.errors, ...action.error };
    		}
    	}
    	
    	return state;
    }
    // reducer
    
    // так примерно выглядит global store
    {
    	...
    	...
    	form: {
    		login: {
    			values: {
    				email: '',
    				password: '',
    			},
    			errors: {
    				email: '',
    				password: ''
    			}
    		},
    	}
    }
    // так примерно выглядит global store
    
    
    import React from 'react';
    import { validateEmail, validatePassword } from 'someValidateLibrary';
    import { connect } from 'react-redux';
    import { browserHistory } from 'react-router';
    	
    import { updateField } from 'path to operations file (action creators)' 
    
    class SomeForm extends React.Component {
    	
    	handleValueChange = (e) => {
    		const field = e.target.name;
    		let error = '';
    		
    		if(field === 'email' && !validateEmail(field)) {
    			error = "You email is so bad, seriously!";
    		} 
    		else if (!validationPassword(field) ) {
    			error = "Your password is sucks!"
    		}
    		
    		this.props.dispatch(
    			updateField(
    				{ field: e.target.value.trim() }, 
    				{ field: error.trim() }
    			)
    		);
    	} 
    
    	proccessForm = () => {
    		const { errors } = this.props;
    		// если ошибок больше нет, то переход на другой роут
    		if(!errors.email && !errors.password) {
    			browserHistory.push('/home');
    		} else {
    			// your code here
    		}
    		
    	}
    	
    	render() {
    		const { values, errros } = this.props;
    		
    		return (
    			// some ui
    			<form onSubmit={this.proccessForm}>
    				<p class="form-field">
    					<input 
    						type="email" 
    						name="email" 
    						onChange={this.handleValueChange} 
    						value={values.email} 
    					/>
    					<span>{errors.email}</span>
    				</p>
    				<p class="form-field">
    					<input 
    						type="text" 
    						name="password" 
    						onChange={this.handleValueChange} 
    						value={values.password} 
    					/>
    					<span>{errors.password}</span>
    				</p>
    				<button 
    					type="submit" 
    					disabled={!values.email && !values.password}>
    						submit
    				</button>
    			</form>
    		);
    	}
    }
    
    const mapStateToProps = ({ form: { login } }) => (
      { values: login.values, errors: login.errors }
    );
    	
    
    connect(mapDispatchToProps)(SomeForm);
    Ответ написан
    4 комментария
  • Убрать клик js в меню?

    devellopah
    @devellopah
    вот этот плагин
    не надо менять его исходный код - работайте с api, который он предоставляет

    p.s. плагин старый и заброшеный ( последний коммит в декабре 2014 ) . поищи что посвежее maybe?
    хотя если пашет и в целом устраивает, почему бы не использовать.
    Ответ написан
  • Почему не происходит сложение массива?

    devellopah
    @devellopah
    Evgenij_nechujveter:

    твой код можно представить немного по-другому для понимания сути

    var a = [2,1];
    var b = [9,5];
    var mergeArray = function() {
    	var a, b, array; // изначально undefined
    	// поскольку в вызове функции ты не передал значения, чтобы присвоить их переменным a и b, они так и остаются undefined
    	// здесь ты пытаешься вызвать метод .concat() у undefined, должна вылетать ошибка по этому поводу
    	// ты ожидаешь что a и b будут взяты из глобального пространства, но этого не произойдёт, поскольку здесь внутри функции (то есть в локальном пространстве) ты объявил переменные c точно такими же идентификаторами, поэтому они "перетерут" глобальных "тёзок".
    	array = a.concat(b); // undefined.concat(undefined);
    };
    
    mergeArray();


    нечистая функция (императивный подход)
    либо не объявляешь локальные a и b (убираешь a, b из объявления функции) и работаешь напрямую с глобальными a и b

    чистая функция (функциональный подход)
    либо оставляешь как есть и просто вызываешь функцию с двумя аргументами (чтобы присвоить локальным a и b соответствующие массивы в качестве значений и ошибок не будет, поскольку у массивов есть метод .concat() "на вооружении")
    Ответ написан
    Комментировать
  • Нужен ли JavaScript?

    devellopah
    @devellopah
    хотя бы на уровне работы с дом(объектной моделью документа) и подключения плагинов(библиотек)
    Ответ написан
    Комментировать