• Как отслеживать создание многоугольника на яндекс карте?

    @dmz9
    если присмотреться то в коде добавляется мониторинг состояния редактора полигона.
    var stateMonitor = new ymaps.Monitor(myPolygon.editor.state);
              stateMonitor.add("drawing", function (newValue) {
                  myPolygon.options.set("strokeColor", newValue ? '#FF0000' : '#0000FF');
              });

    мониторится "поле" state.
    к нему документация вот тут https://tech.yandex.ru/maps/doc/jsapi/2.1/ref/refe...
    там где табличка с описанием написано справа что кроме "drawing" есть еще свойство "editing", т.е. состояние "редактируется", и оно булевого типа.
    в обработчиках которые вешаются на свойства, вроде как, передается не только newValue, но и должно передаваться oldValue, поставь его в вызов функции вторым аргументом и проверь так или нет.
    конец редактирования это если newValue==false, oldValue==true, это и будет по идее моментом окончания создания.
    Ответ написан
    1 комментарий
  • Комбинированный if?

    @dmz9
    проваливающийся свич быстрее всех, не слушай никого ыы.
    первый и третий варианты тратят время на создание массивов/объектов соответственно.
    второй вариант, со свичем, ничего не создает, соответственно быстрее.
    var X = 52;
        console.time('someFunction1');
        for (var i=0,x=0; i < 10000; i++) {
            if ([52, 62, 72, 82, 92].indexOf(X) !== -1) {
                x++;
            }
        }
        console.log(x);
        console.timeEnd('someFunction1');
        console.log('--------------');
        console.time('someFunction2');
        for (var i=0,y=0; i < 10000; i++) {
            switch (X) {
                case 52:
                case 62:
                case 72:
                case 82:
                case 92:
                    y++;
                    break;
            }
        }
        console.log(y);
        console.timeEnd('someFunction2');
        console.log('--------------');
        console.time('someFunction3');
    
        for (var i=0,z=0; i < 10000; i++) {
            if({52:1, 62:1, 72:1, 82:1, 92:1}[X]) { z++; }
        }
        console.log(z);
        console.timeEnd('someFunction3');

    10000
    someFunction1: 2.541ms
    --------------
    10000
    someFunction2: 1.192ms
    --------------
    10000
    someFunction3: 3.676ms
    Ответ написан
    2 комментария
  • Алгоритм превращения одноуровневого списка в двухуровневый?

    @dmz9
    посидел на кодеварс - полюбил "сразу-возврат".
    и кстати задачка кажется с какого то подобного ресурса.
    ну вобщем, аккумулятором может быть необязательно массив, это может быть и объект, в котором хранятся флаги, вместо заведения переменных через var или запиливания еще одних функций.
    алсо - зачем запускать "тяжелый" алгоритм если у нас на входе пусто/одно-элементный массив? сразу возвращаем [array].
    единственный минус решения - два раза вызывается typeof в случаях когда он не совпадает.
    ещё один чит-код - reduce вернет аккумулятор. а аккумулятор это объект. а к свойству объекта (result) можно обратиться через точку.
    не будем слепо добавлять в массивы, для этого есть текущий ключ итератора acc.i (который увеличивается когда появился другой тип элемента).
    ну и изначально он = -1, потому что первое же несоответствие last:false !== "какой-то-там-тип-значения" его плюсанет и он станет ноликом.
    и еще - мне это нравится потому что тут всего одна проверка, всё остальное достаточно прямолинейно.
    нет необходимости делать проверки существования начальных значений "флагов" - главное правильно их задать сразу
    function groupByType(array) {
        return (array.length < 2) ? [array] : array.reduce(function(acc, current) {
        	if(typeof current != acc.last){
        		acc.last=typeof current;
        		acc.result.push([]);
        		acc.i++;
        	}
        	acc.result[acc.i].push(current);
            return acc;
        }, { result: [], i: -1,last:false }).result;
    };

    опдейт.:
    подумав и окинув взглядом - можно избавиться и от итератора, он не нужен.
    function groupByType(array) {
        return (array.length < 2) ? [array] : array.reduce(function(acc, current) {
        	if(typeof current != acc.last){
        		acc.last=typeof current;
        		acc.result.push([]);
        	}
        	acc.result[acc.result.length-1].push(current);
            return acc;
        }, { result: [] ,last:false }).result;
    };
    groupByType([1, 2, 3, 'a', 4, 5, 'b', 9, 'n', 'm']);
    Ответ написан
  • Как принудительно заставить загружаться элемент на странице в самую первую очередь?

    @dmz9
    base64-кодирование картинки в инлайн, но размер вырастет.
    картинка станет неотъемлемой частью исходного кода страницы, однако увеличит его на 55-60 кб.
    я бы рассмотрел вариант приведения к цсс-анимации, это будет легче по объему.
    Ответ написан
    2 комментария
  • Какой есть бесплатный редактор для windows XP взамен Brackets?

    @dmz9
    sublime text 2 (3)
    notepad++, у нас тоже люди некоторые в нем работают и вполне-себе замена, даже по фтп редактировать можно если плагинов навернуть сверху
    Ответ написан
    Комментировать
  • Какие книги почитать по sql, php 7, javascript, паттернам проектирования?

    @dmz9
    https://www.ozon.ru/context/detail/id/4884925/
    Фаулер - Шаблоны корпоративных приложений.
    и да, это тоже самое что Архитектура корпоративных (программных) приложений, просто называется немного подругому. объем тот же, все тоже самое, просто кто то "надмозг" слишком сильно.
    ------------------
    Банда четырех это на самом деле вот эта книга
    www.ozon.ru/context/detail/id/2457392
    Приемы объектно-ориентированного проектирования. Паттерны проектирования
    а та книжка с девушкой на обложке в клеточку - мало общего имеет с программированием. наивно, слишком просто, несерьезно, дурацкие картинки, много пустого места в тексте, нестандартный формат книги (почти квадрат). полистал в магазине и не стал брать. и то что там четыре автора вдруг не делает их Gang Of Four )))
    Ответ написан
    Комментировать
  • Как писать много кода, оставляя его простым, как в начале?

    @dmz9
    не знаю зачем тут пацаны советуют чистый код Р. Мартина
    https://www.ozon.ru/context/detail/id/5011068/
    вот что нужно на замену
    https://www.ozon.ru/context/detail/id/138437220/
    есть обе у меня, но красненькую купил раньше. в ней больше информации как внешне так и по сути.

    в чистом коде как то всё "поверхностно" и после "совершенного кода" ощущается какая то "казуальность", а еще там дурацкие картинки, не имеющие отношения к программированию.
    -----------------------------
    боязнь большого кода, как правильно заметил, идет от того что ты не можешь запомнить всё что происходит "вокруг" кода, т.е. не хватает твоей собственной "оперативной памяти". и это вполне нормальное явление, среди нас пока мало киборгов (хотя они и есть уже), а уж с суперкомпьютером в голове так и вовсе нет.

    во многих конвенциях о code-style указываются очень грамотные вещи, и они не просто так там находятся. в общем смысл такой - код должен быть самодокументируемым/самоописательным, а комментарии к коду не должны быть в стиле "моё почтение, капитан!".
    • код должен напоминать хорошую прозу.
    • комменты описывают намерение (зачем?) а не реализацию (как?).
    • прими во внимание время жизни переменной. чем ближе переменная к "месту военных действий" тем лучше. перекликается со временем жизни переменной - чем быстрей "умирает" тем лучше, часто можно даже без переменной обойтись не в убыток читаемости.
    • люди советуют тут ограничиваться конкретным числом строк. имхо - вредный совет. метод не должен ограничиваться. метод должен быть такой длины, которая требуется. иногда без "супер-методов" не обойтись (это не о функциях на 100500 входящих параметров), невозможно просто разбить тяжелую функцию на более мелкие куски, не умножив число запоминаемых переменных/других методов. метод может быть в 3 строки, может быть даже в одну, а может быть в сто-двести строк и более. если из метода ничего нельзя выбросить и нечего добавить - значит он в точности занимает столько сколько нужно.
    • многословие приветствуется но без фанатизма. машине почти всё-равно какой длины у тебя функция (если вы понимаете о чем я), а для тех кому нет - есть минификаторы (для js например)
    • название метода должно однозначно говорить о его назначении. спрашивай себя - зачем этот метод? зачем это свойство? если ты не можешь ответить значит и запомнить/вспомнить не сможешь, значит у метода/свойства нет конкретного предназначения и потом (через какое то время) будет сложно разобраться для чего он вообще нужен.
    • визуально отделяй приватные/публичные методы. это тоже некоторая подсказка которая помогает разбираться в коде.
    • следуй одному стилю как минимум в отдельно-взятом файле. (кемелкейс отдельно, лодаш отдельно).
    • следуй принципу наименьшего удивления (программиста). т.е. поменьше роялей в кустах
    • соблюдай абстракции. если класс это не просто набор статичных методов - значит он описывает какие то действия вполне определенного объекта. не раздувай и не разбивай на несколько классов одну цельную и четкую абстракцию. это поможет сосредоточиться на отдельном куске кода в один момент.
    • старайся не писать рядом в одном классе методы, которые "проникают" во все аспекты приложения (антипаттерн - суперкласс/божественный объект).


    вообще стоит почитать про паттерны и антипатеррны, это конечно не библия но знать хотя бы основные стоит.
    Ответ написан
    2 комментария
  • JS Как отследить нажатие комбинации клавиш(пример - Alt+Ctrl+1)?

    @dmz9
    с джиквери можно сделать так.
    вешаешь keydown на документ, потом слушаешь ивент.
    там среди прочего есть
    event.ctrlKey
    event.altKey
    event.shiftKey (вроде бы)
    ну и сам зажатый event.key (звездочка например)
    кодэ вынеси в функцию, не помню считается ли зажатая кнопка повторением ивента, но если нет просто через интервал запускаешь функцию
    $(document).on('keydown',function (event) {
                if (event.ctrlKey&&event.key=='*') {
                  // кодэ
                }
            })
    Ответ написан
    1 комментарий
  • Как не обновлять значение input'а при пользовательском вводе?

    @dmz9
    т.е. пока инпут в фокусе - не применять валидатор, а как только фокус потерян - применять?
    Ответ написан
    2 комментария
  • Как запустить get через set в Proxy javascript?

    @dmz9
    обращение на чтение к свойству объекта запускает гет.
    просто прочитай это значение и код выполнится, разве нет?
    Ответ написан
  • Как сформировать список select с помощью Ajax запросив с БД MySQL?

    @dmz9
    брррррр...
    1. для шаблонизатора в пхп лучше делать так
    1.1 даже если шаблонизатор не поддерживает шорт-теги, а шаблон это тупо пхп/хтмл файл - всё же стоит выносить пхп код сборки элементов выше чем хтмл-темплейт сам по себе.
    1.2 множественное открытие/закрытие тегов тоже не особо кул. дело не в перфомансе а в читаемости.
    по сути выглядеть должно как то так
    <?php
    $optionsArray = array();
    if (is_array($organizationList)&&!empty($organizationList))
    {
    	foreach ($organizationList as $org)
    	{
    		$optionsArray[]='<option value="'.$org['idn'].'">'.$org['name'].'</option>';
    	}
    }
    ?><!DOCTYPE html>
    <html>
    ..............
    <select name="organization_id" id="getOrg">
        <option disabled selected>Укажите организацию...</option>
        <?=implode("",$optionsArray)?>
    </select>

    2. сборка селектов на джиквери
    2.1 трогать ДОМ много раз - вредно. семь раз create, один раз append.
    2.2 данные лучше присылать в виде "массива" - в пхп это числовой массив.
    элементами массива уже могут быть объекты - в пхп это ассоциативный массив.
    var data = [{
        idn: 3,
        name: 'first'
    }, {
        idn: 4,
        name: 'second'
    }, {
        idn: 5,
        name: 'third'
    }];
    var $select = $('<select/>', {
        class: 'form-control',
        html: $.map(data, function(org) {
            return $('<option/>', {
                value: org.idn,
                text: org.name
            })
        })
    }).on('change', function() {
        console.log($(this).val());
    }).trigger('change');
    $('.container').append($select)

    можно пойти дальше и $select вообще не заводить а сразу внутри инструкции аппенда написать весь конструктор селекта
    ----------------------------
    собственно - после каждого изменения (внутри change колбека) запрашиваешь данные еще раз (можно кешировать), перерисовываешь селекты. лучше иметь какое то отдельное хранилище - объект js. после сохранения в него данных, запускаешь метод сборки. это 2 отдельные функции.
    можно вынести конструктор селекта в обычную функцию, в которую просто передаешь данные, и возвращается jquery-объект, который в success:function аппендит его в нужное место (а лучше сначала почистить контейнер от старых селектов - $('.container').empty().append($select) ).
    ----------------------------
    для отладки используй хром, открой инструменты разработчика, там есть вкладка network, конкретно должно интересовать тебя - фильтр по XHR, и делай запросы, увидишь что возвращается - json или ошибки от пхп.
    Ответ написан
    4 комментария
  • Переход на главную страницу из дочерней?

    @dmz9
    для главной
    <ul id="menu-topen-1" class="menu">
      <li class="menu-item"><a href="#solutions">Solutions</a></li>
      <li class="menu-item"><a href="#team">Team</a></li>
      <li class="menu-item"><a href="#blog">Blog</a></li>
      <li class="menu-item"><a href="#contact">Contact</a></li>
    </ul>

    не для главной
    <ul id="menu-topen-1" class="menu">
      <li class="menu-item"><a href="/#solutions">Solutions</a></li>
      <li class="menu-item"><a href="/#team">Team</a></li>
      <li class="menu-item"><a href="/#blog">Blog</a></li>
      <li class="menu-item"><a href="/#contact">Contact</a></li>
    </ul>
    Ответ написан
  • Как правильно впихнуть данные в json?

    @dmz9
    https://api.jquery.com/jquery.extend/
    var toSendData = $.extend({},myObj,flavor);
    порядок влияет на перезаписываемость свойств.
    лучше экстендить пустой объект (иначе мутирует первый указаный)
    Ответ написан
  • Как различать методы и свойства в ооп?

    @dmz9
    дело в инкапсуляции.
    у объекта могут быть открытые (публичные) и закрытые (приватные) свойства/методы.
    в JS это слабее выражено (но это можно имитировать), но в других языках такие модификаторы есть.
    разница в том что открытые свойства доступны любому другому объекту/методу, взаимодействующему с изначальным объектом. аналогично и публичные методы нужны для открытого взаимодействия. приватные нужны только для себя, также как и некоторые методы нужны только внутри объекта но не снаружи.
    использовать ли для объектов свойства? можно вообще не использовать. вместо этого используй чтения-записи значений. однако это усложняет код.
    если пишешь код на публику - тогда делай эти методы.
    если пишешь код в своем маааленьком приложении - смысла в этом мало.
    пример закрытых и открытых свойств. на самом деле "во внешний мир" отдается другой объект, однако это не значит что он перестал "работать".
    var TheConstructor = function(params) {
        var
            happinessCap = 100,
            desireCap = 100,
            ageFactor = (function(age) {
                return 33 / age;
            })(params.age),
            maxAge=45,
            minAge=18,
            woman = {
                _age: params.age,
                _happiness: 42,
                _desire: 0,
                bitchCoeff: params.bitchCoeff
            };
        woman.dance = function() {
            woman._happiness += woman._age / woman.bitchCoeff;
            if (woman._happiness >= happinessCap) {
                woman._happiness = happinessCap;
            }
        }
        woman.drinkAlcohol = function() {
        	if(woman._age<minAge){
        		throw new AgeRestriction(woman._age);
        	}
        	if(woman._age>maxAge){
        		return;
        	}
            woman._desire += woman._age * ageFactor / woman.bitchCoeff;
            if (woman._desire >= desireCap) {
                woman._desire = desireCap;
            }
        }
        woman.isAccessible = function() {
            return (woman._happiness == happinessCap && woman._desire == desireCap);
        }
        return {
            dance: woman.dance,
            drink: woman.drinkAlcohol,
            isAccessible: woman.isAccessible,
            own:function(){
            	return (woman.bitchCoeff<1)?woman:{};
            }
        }
    }
    function seduce(woman){
    	var maxAttempts = 5;
    	for(var i = 1;i<=maxAttempts;i++){
    		woman.drink();
    		woman.dance();
    		if(woman.isAccessible()){
    			console.log(woman.name + " has been seducted after "+i+" attempts!");
    			console.info(woman.own());
    			return true;
    		}
    	}
    	console.error(woman.name + " is a frigid bitch!");
    	return false;
    }
    var cheerLeader = new TheConstructor({age:20,bitchCoeff:0.25})
    cheerLeader.name = "Masha";
    seduce(cheerLeader);
    var businessWoman = new TheConstructor({age:33,bitchCoeff:2.5})
    businessWoman.name="Olga Victorovna";
    seduce(businessWoman);
    var schoolTeacher = new TheConstructor({age:27,bitchCoeff:1.1})
    schoolTeacher.name="Valentina";
    seduce(schoolTeacher);

    ------------
    свойства начинаются с мелкой буквы, являются именами существительными, если больше 1 слова пишется кемел-кейс.
    приватные свойства начинаются с подчеркивания (так проще различать). например
    если юзаешь джиквери - есть негласное соглашение (а может где то и зафиксировано), что свойство или переменная содержащая джиквери объект начинается с $, например this.$container = $('.container');
    -------------
    методы - тоже начинаются с мелкой буквы, являются глаголами. если больше 1 слова пишется кемел-кейс, первое слово всеравно глагол, остальные могут быть существительными. например this.getStorageData('orders'), типа, получить данные (заказы) из хранилища.
    есть еще методы - конструкторы. это методы объекта которые возвращают не просто результат, а целый новый объект, в который напиханы разные свойства. методы конструктора обычно начинают с БольшойБуквы.
    например
    this.BuildWidget = function(widgetParams){ var widget={params:widgetParams}; ... ; return widget; }.

    -------------
    Ответ написан
  • Про transform: rotate(). Как правильно крутить?

    @dmz9
    1. лучше сделать добавление-удаление класса, вместо накручивания инлайн-стилей.
    в цсс проще пихать вендорные префиксы. а у элемента будет меняться класс, добавляющий ему вращение через цсс.
    2. https://github.com/Modernizr/Modernizr/wiki/HTML5-... -> imsky.github.io/cssFx
    полифилл это скрипт поддержки (js) который поможет тем браузерам где нет реализации каких то вещей.
    3. если нужны кастомные повороты то тут вот что
    3.1 теоретически через несколько тысячелетий появится поддержка attr() внутри любого цсс свойства. пока что поддерживается только content: attr(какой-то-атрибут), т.е. псевдоэлемент. вобщем, когда то можно будет заюзать что то вроде
    <div ang="10"></div>
    div{
      transform:rotate(attr(ang, deg));
    }

    но пока увы это не работает. скрипт менял бы только атрибут ang и все.
    3.2 раз уж там что то у тебя похожее на джиквери то вот
    www.richardfawcett.net/demos/jquery_1.8.0_testing.html
    после 1.8 джиквери сам добавляет вендорные префиксы.
    однако чтобы это юзать надо использовать не выборку дом-элемента, а именно джиквери объект
    var angle=12.5;
    $(marker._icon).css({
      transform:"rotate("+angle+"deg)"
    })

    джиквери сам проставит префиксы. и да, .css метод на джиквери объекте, вместо style на дом-элементе.
    Ответ написан
    Комментировать
  • Модификация массива, как бы так это сделать?

    @dmz9
    map-функция в помощь.
    https://developer.mozilla.org/ru/docs/Web/JavaScri...
    проходит по каждому элементу массива, в конце возвращает массив с таким же количеством элементов.
    вот внутри этой функции-колбека и формируешь под каждый элемент вот такой массив ["1","Володя",3 ,230], и его же return из этой функции.
    Ответ написан
    Комментировать
  • Как сделать, чтобы по клику на нужный адрес, карта показывала это место?

    @dmz9
    строго говоря нарушен принцип "не повторяйся".
    на сайте примере под каждый отдельный селектор тот же самый код, меняются только числа координат.
    само собой напрашивается вынесение этих соответсвий в отдельный js-объект вида
    var coords = {
    	'showMap_1':{
    		[55.66837606904998,37.484163499999944]
    	},
    	'showMap_2':{
    		[55.66266356906509,37.478000999999914]
    	},
    	...
    }

    что интересно - в странице подключен джиквери но скрипт использует ванильные селекторы.
    вобщем, вместо 10 обработчиков на каждом элементе - нужен один вот такой
    $('tr[id=^showMap]').click(function() {
        myMap.setZoom( 15 );
        myMap.panTo(coords[$(this).attr('id')],{flying:1});
        TweenMax.to(window, 0.5, {scrollTo:{y: document.getElementById("map").offsetTop-10}})
    });

    при клике берется идентификатор строки таблицы, по нему сразу получается соответствие из coords по ключу.
    само собой coords должен быть в области видимости рядом с функцией, либо в каком то глобальном объекте (если список координат каждый раз - динамический и пишется в коде страницы на сервере)
    Ответ написан
    Комментировать
  • Как выполнить действии при обнаружении добавления нового элемента dom?

    @dmz9
    обычно нормальные разработчики нормальных js плагинов оставляют возможность работать с событиями, происходящими в их плагинах.
    среди таких событий конкретно для всплывающих окон обычно есть
    "перед началом открытия"
    "после открытия"
    и еще другие, но это как минимум.
    зачем пытаться повешаться на мутацию дома, если можно воспользоваться встроеной возможностью фансибокса?
    обработчики обычно вешаются во время инициализации в параметрах
    fancyapps.com/fancybox
    если юзаешь плагин который не имеет функционала событий на которые можно повешать свои обработчики - это решается очень просто использованием другого плагина, который имеет такой функционал в отличие от первого.
    пролистай вниз, там 3 вкладки, нужна которая "callbacks"
    вообще кстати неграмотно сделано, поиск по странице сразу не дает результатов, такое впечатление как будто функционал отсутствует, а на самом деле инфа в табах. юзабилити хромает у разрабов.
    e3e9ca540d1b488c956ec721bc6e8090.png
    Ответ написан
  • Выполнение на одной странице двух функций javascript?

    @dmz9
    они в любом случае будут выполняться последовательно (даже если их именовать по разному). но можно чуть упростить и вообще сделать их безымянными
    oninput = function() {
        (function() {
            var a = Number(document.getElementById("itemPrice").value);
            var b = Number(document.getElementById("EMC").value);
            var c = Number(document.getElementById("amount").value);
            var d = Number(document.getElementById("koef").value);
            var v = (c * a + b) * 0.1 + c * a + b;
            var f = v * d
            var x = (f * 0.02 + f) + ((f * 0.02 + f) * 0.22)
            if (x >= 0 && v <= 10000) {
                document.getElementById("result").innerHTML = x.toFixed(2);
            }
        }()),
        (function() {
            var W = Number(document.getElementById("itemweight").value);
            var Wresult = W * 14;
            if (Wresult >= 0 && Wresult <= 10000) {
                document.getElementById("resultWeight").innerHTML = Wresult.toFixed(2);
            }
        }())
    }

    это конструкция "мгновенно исполняемой функции", когда пишешь типа (function(){}()), из последних скобок аргументы прилетают в функцию, обозначеную перед ними и функция выполняется. пустые скобки - ну значит аргументов нет, просто берем и выполняем. в этом случае нам даже имя давать не надо (лямбда-функция), они просто по порядку выполнятся с пустыми аргументами.
    и раз попёрла такая мазута - можно даже запятую между этими выражениями поставить чтобы логически было "сначала 1, потом 2". она ни на что не влияет, просто для красоты
    Ответ написан
  • Редактировать сайт с локального файла *.js?

    @dmz9
    имхо, если кто то боится админки друпала - может подумать как её упростить а не велосипедить?
    друпал потому что адрес похож на друпаловский. и да, там страшная и запутаная админка для неподготовленого юзера.
    можно просто настроить внешний вид для какого нибудь аккаунта, чтобы небыло ничего лишнего вообще.
    можно сделать и велосипед.
    ложишь на сервер файл пхп, подключаешь в нем ядро друпала, пишешь принималку-отправлялку данных (с секретным ключом чтобы никто не догадался!), апи там вроде как есть.
    на своем или чьем там компе пишешь спа, раз уж так захотел. редактор постов на жс, пусть это будет форма, просто делаешь ей POST на этот адрес (в файл пхп), аякс-ответ ловишь (да, нет, незнаю, ошибки). форма еще должна посылать секретный ключ (для идентификации - вдруг это злобный хацкер будет пытаться без ключа запостить что нибудь - обломчик).
    а потом еще надо все возможности админки в этот скрипт перетащить.
    и в итоге ты получаешь ту же самую админку только в другом виде, т.е. велосипед. но зато опыт. и время. и бессонные ночи. оно надо? ))
    Ответ написан