Ответы пользователя по тегу JavaScript
  • Как писать приложение на js?

    dunmaksim
    @dunmaksim
    Технический писатель
    Стоит задача написать что-то именно на чистом IS, без библиотек? В таком случае, вам нужно будет пройти несколько этапов.
    1. Разбить проект на базовые модули и собственно приложение
    2. Написать базовые модули для работы с DOM, AJAX, событиями, строками, числами, формами, стилями, потоками, cookies, наследованием, роутингом и т. д. (посмотрите дизайн Dojo Toolkit версии 1. X, там эталонная реализация всего этого уже есть).
    3. Разделить приложение на модули, написать их
    4. Собрать из отдельных частей готовый bundle-файл (не знаю, что сейчас стильно-модно-молодёжно, но вроде WebPack популярен, хотя порог входа очень крутой)
    Ответ написан
    2 комментария
  • Что делать если при значении false, действия все равно выполняются?

    dunmaksim
    @dunmaksim
    Технический писатель
    Вы неправильно используете приведение типов в JavaScript. Ваш код по факту сравнивает не высоту блока с заданным числом, а строку с другой строкой, поэтому и поведение такое странное. Правильно писать так:
    (function (){
        "use strict";
    
        var bgBlock = document.getElementById("background_bar");
    
        if (bgBlock.scrollHeight > 80) { // bgBlock.scrollHeight всегда число
            // Какой-то код, который выполняется для высоты меньше 80 px
        } else {
            // Другой код, если блок меньше
        }
    }());


    Подробнее здесь.
    Ответ написан
  • Способы улучшения JS-кода?

    dunmaksim
    @dunmaksim
    Технический писатель
    Знаки !, -, + заставляют интерпретатор вычислить (в данном случае - выполнить) то, что находится справа. Например, в Bootstrap всюду вставлен знак + для этого.
    Однако, более правильным было бы переписать код так:
    (function ($){
        "use strict";
        
    }(this.jQuery));

    Это тоже шаблон самовызываемой функции, описан в книге Стояна Стефанова "JavaScript. Шаблоны" (люто рекомендую читать не смотря на преклонный для литературы данного типа возраст, где взять - сами знаете).

    Обращение к локальным переменным избавляет от головной боли и долгой отладки, когда непонятно, почему при клике на эту кнопку не только обновляется список записей таблицы, но и увеличивается размер шрифта в заголовке страницы. Глобальные переменные - зло, и с этим нужно бороться. Только замыкания, только хардкор.

    Что касается скорости - в сравнении с перерисовкой DOM любой ваш код будет быстрым, как молния. И да, обращение к глобальным переменным дороже, чем к локальным, т.к. сначала делается поиск в локальной области видимости, и только потом - к глобальной.

    document и window можете помещать, можете не помещать - разница будет только в том, что можно использовать краткие имена:

    (function (W, D){ 
        // W = window   (1 символ против 6)
        // D = document (1 символ против 8)
        "use strict";
    
    }(window, document));


    Всё остальное в указанной книге ну и конечно Николас Закас, "JavaScript. Оптимизация производит....
    Ответ написан
    2 комментария
  • Стоит ли начинающему писать самому плагины на jquery?

    dunmaksim
    @dunmaksim
    Технический писатель
    У меня примерно такая же проблема, мне постоянно хочется улучшать код, который я пишу, из соображений производительности и красоты, но этот перфекционизм излишен и сильно увеличивает сроки разработки.
    Пока нет реально заметных тормозов - не надо ничего оптимизировать. Тенденция не самая хорошая (Witcher 3, Chrome, Assassins Creed - это только вершина айсберга), но пока вы будете делать свой идеальный быстрый плагин, конкуренты напишут кучу глючных кривых костылей, которые уже будут работать, и люди будут пользоваться ими, а когда наконец зарелизите версию 1.0, она уже настолько устареет, что вы и сами ей пользоваться не будете.
    Ответ написан
    Комментировать
  • JSlint настройка проверки JS?

    dunmaksim
    @dunmaksim
    Технический писатель
    Обычно для таких случаев лучше настройки автоформаттера кода подкрутить. Что там у вас: jsfmt, web-beautify, js-beautify? В любом случае, просто найдите опцию "JSLint Happy" или подобную, после чего перепишите код как положено:
    • [FAIL] все переменные объявляются за один var (а вот другая точка зрения)
    • [OK] строгий режим
    • [FAIL] внутри for ... in ... делать проверку hasOwnProperty()
    • [FAIL] пробел перед круглыми скобками декларации анонимных функций
    • ну и так, мелочь всякая, лень перечислять дальше, например, for в вашем случае прекрасно заменяется на forEach(), отличная статья по теме

    Если поможет, в моём конфиге EMACS'а хранятся так же настройки автоформата для JS - файлы сами поймёте какие и куда положить (судя по убунте).
    Ответ написан
    Комментировать
  • Стоит ли изучать TypeScript?

    dunmaksim
    @dunmaksim
    Технический писатель
    "Я русский бы выучил только за то, что им разговаривал Ленин!"
    А TypeScript - из-за Angular 2 и Dojo 2.
    Ответ написан
    Комментировать
  • Что такое провайдер в программировании?

    dunmaksim
    @dunmaksim
    Технический писатель
    Как правило провайдер используется для инкапсуляции более сложного кода, скрывая детали реализации. Он служит этакой обёрткой, реализуя шаблон проектирования "Фасад".
    Вы копируете файл из каталога в каталог, просто перетащив его мышью. Но как это произошло на физическом уровне? Вам этого знать не обязательно, всё скрыто под множественными слоями абстракций.
    Чтобы не думать о каких-либо низкоуровневых вещах, часто вводят провайдеры, сервисы и т.д. Суть одна - скрыть какие-либо часто используемые сложные функции и рутинную работу за простым и понятным интерфейсом.
    Ответ написан
    2 комментария
  • Правильна ли трактовка кода?

    dunmaksim
    @dunmaksim
    Технический писатель
    Всё несколько проще. Вместо "ассоциативный массив" всегда говорите "объект".

    /* Глобальная переменная - лучший друг быдлокодера */
    var map;
    
    /* Создадим с помощью конструктора новый объект */
    var brooklyn = new google.maps.LatLng(40.6743890, -73.9455);
    
    /* Так обычно объявляют константы (до ECMA 2015 нормального синтаксиса не было) */
    var MY_MAPTYPE_ID = 'Purple';
    
    // Обычно такую телегу записывают так (шаблон One-var template, привет, Pascal!):
    var map,
    	  brooklyn = new google.maps.LatLng(40.6743890, -73.9455),
    	  MY_MAPTYPE_ID = 'Purple';
    
    /* Декларируем функцию */
    function initialize() {
    	/* Создаём массив объектов */
        var featureOpts = [
    		{ // Раз
    			stylers: [ //И сразу вложенный объект с полем-массивом объектов
    				{ hue: '#6b20a1' },
    				{ visibility: 'simplified' },
    				{ gamma: 0.5 },
    				{ weight: 0.5 }
    			]
    		}, { // Два
    			elementType: 'labels',
    			stylers: [ // Вложенный массив
    				{ visibility: 'on' }
    			]
    		}, { // Три
    			featureType: 'water',
    			stylers: [
    				{ color: '#6b20a1' }
    			]
    		}];
    } // Закрывающую скобку кто ставить будет, я что ли?
    Ответ написан
    Комментировать
  • Какой вариант правильнее и лучше?

    dunmaksim
    @dunmaksim
    Технический писатель
    Оба плохие. Нужно ставить обработчик на контейнер, содержащий эти элементы, и перехватывать всплытие события по DOM. Подробности гуглите по словам "делегированная обработка событий". Вот хорошая статья по теме.
    Так же все переменные лучше объявлять в начале модуля, a-la Pascal, а не в месте непосредственного использования, чтобы не столкнуться с проблемой всплытия переменной.
    Ответ написан
    9 комментариев
  • Как получить данные из объекта $resource?

    dunmaksim
    @dunmaksim
    Технический писатель
    Правильно писать так:
    (function(A) {
        "use strict";
        A.module('App').controller('Ctrl', ['$resource', '$scope', functino($resource, $scope) {
            var r = $resource('/api/items/:id/', {
                id: '@id'
            }, {
                update: {
                    method: 'PUT' //Необязательная фича для Django REST Framework
                }
            });
            $scope.loading = true;
            $scope.items = [];
    
            r.query({
                //А можно передать параметры, скажем, limit и offset
            }, function(response) {
                $scope.items = response;
                $scope.loading = false;
            }, function(response) {
                $scope.loadign = false;
                $scope.errors = response.data; // Так DRF отдаёт ошибки
            });
        }]);
    }(this.angular));
    Ответ написан
    4 комментария
  • Ресурсоемкая функция подвешивает браузер?

    dunmaksim
    @dunmaksim
    Технический писатель
    Ответ написан
    Комментировать
  • Как настроить переход между страницами в Angular?

    dunmaksim
    @dunmaksim
    Технический писатель
    Ссылки должны начинаться со знака # или со знаков !#, если нужна поисковая оптимизация, тогда не будет перекидывать. К тому же, используйте ng-href.
    Вот тут явная ошибка:
    <li  ng-repeat="list in lists">
       <a href="/">{{list.name}}</a>
    </li>

    У Вас ВСЕ ссылки будут вести на /. Правильно делать так:
    <li ng-repeat="item in links">
        <a ng-href="#/{{ item.link }}">{{ item.title }}</a>
    </li>

    В свою очередь массив ссылок должен выглядеть примерно так:
    links = [
        { link: 'contacts', title: 'Контакты' },
        { link: 'profile',  title: 'Профиль'  }
    ];
    Ответ написан
    9 комментариев
  • Как динамично подключать LESS файлы / какой командой можно откомпилировать.less файл из javascript?

    dunmaksim
    @dunmaksim
    Технический писатель
    Никак.
    Ответ написан
    Комментировать
  • Как понять момент в замыкании(JS)?

    dunmaksim
    @dunmaksim
    Технический писатель
    Переписал код, надеюсь, более понятно стало:
    function makeCounter(){
        //Эта переменная видна только здесь
        var currentCount = 0;
        
        //Эта функция - тоже только здесь, зато она видит currentCount
        function getCountValue(){
            currentCount += 1;
            return currentCount;
        }
        
        //Возвращаем саму функцию, а не её значение
        return getCountValue;
    }
    
    //counter = getCountValue
    var counter = makeCounter();
    
    counter(); //На самом деле - вызов getCountValue()
    Ответ написан
    Комментировать
  • Где почитать про ООП на JavaScript?

    dunmaksim
    @dunmaksim
    Технический писатель
    Стоян Стефанов, "JavaScript. Шаблоны". Ничего лучше по данной теме ещё не видел.
    Ответ написан
    Комментировать
  • Почему не работает роутинг в angulaJs?

    dunmaksim
    @dunmaksim
    Технический писатель
    При инициализации приложения точно импортируется ngRoute? Плагин angular-route подключен к странице? Кстати, есть ещё плагин angular-router, он нерабочий, насколько я знаю. Путь точно '/login' а не '/login/'?

    На всякий случай мой пример использования ngRoute, полностью рабочий:
    (function(A) {
        "use strict";
        A.module('Administrator',
            [ 'ngCookies', 'ngRoute', 'ngResource', 'ui.layout', 'ui.bootstrap',
            'ui.bootstrap.dropdown', 'ui.bootstrap.modal', 
            'ui.bootstrap.collapse', 'ui.grid', 'ui.grid.selection',
            'ui.grid.resizeColumns', 'ui.grid.autoResize',
            'ui.grid.selection', 'ui.grid.i18n', 'ui.layout',
            'ui.grid.infiniteScroll'])
        .config(function($interpolateProvider, $resourceProvider, $routeProvider) {
            //Не хочу использовать Django-тег verbose
            $interpolateProvider.startSymbol('{$');
            $interpolateProvider.endSymbol('$}');
            $resourceProvider.defaults.stripTrailingSlashes = false;//Иначе POST-запросы не работают, Django же
    
            $routeProvider.when('/category/', {
                templateUrl: '/administrator/template/grid/',
                controller: 'CategoryGridController'
            }).when('/tests/', {
                templateUrl: '/administrator/template/grid/',
                controller: 'TestsGridController'
            });
        })
        .run(function($http, $cookies) {
            $http.defaults.headers.post['X-CSRFToken'] = $cookies.csrftoken;
            $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
            $http.defaults.headers.common['X-CSRFToken'] = $cookies.csrftoken;
        });
    }(this.angular, this.jQuery));
    Ответ написан
    1 комментарий
  • Почему при использовании ajax c django появляется ошибка Internal server error 500?

    dunmaksim
    @dunmaksim
    Технический писатель
    1. Вам нужно в Вашего шаблона, который выводится на страницу, включить тег {% csrf token %}
    2. Также нужно, чтобы при загрузке страницы срабатывал вот этот скрипт:
    (function(G) {
    	"use strict";
    	var $ = G.jQuery;
    
    	function csrfSafeMethod(method) {
    		return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    	}
    	function sameOrigin(url) {
    		var host = document.location.host, // host + port
    		    protocol = document.location.protocol,
    		    sr_origin = '//' + host,
    		    origin = protocol + sr_origin;
    		// Allow absolute or scheme relative URLs to same origin
    		return (url == origin || url.slice(0, origin.length + 1) == origin
    				+ '/')
    				|| (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin
    						+ '/') ||
    				!(/^(\/\/|http:|https:).*/.test(url));
    	}
    	$.ajaxSetup({
    		beforeSend : function(xhr, settings) {
    			if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
    				xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
    			}
    		}
    	});
    }(this));

    3. Комментировать middleware csrf_token не надо. Вы уж будьте последовательны - если делаете CSRF, так делайте до конца.
    4. Ваш вид лучше написать так:
    @csrf_protect #Защищать так защищать
    def email_check(request):
        if request.method == "POST":
            post_email = request.POST.get("email")
            user_by_email = User.objects.get(email=post_email)
            if user_by_email is not None: #Такой email уже использован
                return HttpResponse(json.dumps({"success": False, "error": "Пользователь с таким email уже зарегистрирован"}), content_type="application/json")
            else: #E-mail свободен
                return HttpResponse(json.dumps({"success": True}), "application/json")
    Ответ написан
  • Динамическое подключение javascript

    dunmaksim
    @dunmaksim
    Технический писатель
    Ответ написан
    Комментировать
  • Хочу научиться создавать плагины JQuery - с чего начать?

    dunmaksim
    @dunmaksim
    Технический писатель
    Чтобы создавать свои плагины, Вам нужно:
    - хорошо знать JS и его подводные камни;
    - знать, что такое шаблон "модуль" и уметь писать свои модули;
    - помнить, что jQuery.fn - всего лишь псевдоним для jQuery.prototype; добавляя свою функцию к этому свойству, Вы расширяете прототип функции jQuery, и важно ничего там не сломать;
    - следовать соглашению, по которому любой плагин jQuery на выходе должен вернуть исходный или модифицированный массив переданных на вход элементов (шаблон "цепочка", есть ещё антишаблон, следующий из этого, называемый "крушение поезда")

    Собственно, вот Вам заготовка модуля:
    (function ($){
        "use strict";
        function myFunction(items){
            return $(items).each(function(){
                $(this).text("Hello, jQuery!");
            });
        }
    
        $.fn.hellojQuery = myFunction;
    }(jQuery));
    Ответ написан
    1 комментарий
  • Зачем в Twitter Bootstrap + перед объявлением функций?

    dunmaksim
    @dunmaksim Автор вопроса
    Технический писатель
    Из статьи ясно, что это ещё один способ объявления самовызываемой функции. Очень интересный подход.
    Ответ написан
    Комментировать