Ответы пользователя по тегу JavaScript
  • Можно ли вставить виджет на страницу сайта в React?

    nowm
    @nowm
    У Elfsight есть справка на этут тему.

    1. Установите react-elfsight-widget

    npm install react-elfsight-widget

    2. Используйте такой код:

    import React from 'react';
    import { ElfsightWidget } from 'react-elfsight-widget';
    
    function Component() {
      return <ElfsightWidget widgetID="хххххххх-хххх-хххх-хххх-хххххххххххх" />;
    }


    Соответственно, вместо хххххххх-хххх-хххх-хххх-хххххххххххх подставьте идентификатор вашего виджета.
    Ответ написан
  • Как считать измененный атрибут?

    nowm
    @nowm
    У jQuery есть проблемы с кэшированием в data. Я когда работал с ним, всегда старался делать что-то вроде container.attr('data-blocked'), чтобы не ловить самые неожиданные глюки.

    // Прочитать значение data-blocked
    container.attr('data-blocked');
    
    // Установить новое значение data-blocked
    container.attr('data-blocked', 'some value');
    Ответ написан
  • Как прапвильно использовать Document.getElementsByClassName?

    nowm
    @nowm
    Метод getElementById возвращает один элемент, а метод getElementsByClassName возвращает HTMLCollection.

    Соответственно, нужно сначала из HTMLCollection получить элементы, и уже этим элементам задавать свойство hidden

    function showForm(className) {
        const elements = document.getElementsByClassName(className);
    
        for (let index = 0; index < elements.length; index++) {
            elements[index].hidden = false;
        }
    }
    Ответ написан
  • Как вставить изображение из input в img?

    nowm
    @nowm
    Чтобы вставить изображение из input type="file", нужно после загрузки изображения прочитать содержимое этого файла с помощью FileReader, сконвертировать в формат data url и только потом это применять к тегу img.

    myImg.onchange = function(event) {
        var target = event.target;
    
        if (!FileReader) {
            alert('FileReader не поддерживается — облом');
            return;
        }
    
        if (!target.files.length) {
            alert('Ничего не загружено');
            return;
        }
    
        var fileReader = new FileReader();
        fileReader.onload = functino() {
            img1.src = fileReader.result;
        }
    
        fileReader.readAsDataURL(target.files[0]);
    }


    В вашем коде myImg — это input type="file". У таких инпутов нет src. Когда с их помощью подгружаются файлы, в свойстве files, находятся все загруженные в этот инпут файлы. Точнее не файлы, а специальные объекты-интерфейсы, привязанные к загруженным файлам. С помощью этих интерфейсов уже можно делать различные действия с соответствующими файлами: узнавать название файла, дату последнего изменения, MIME-тип файла, читать его содержимое и так далее.
    Ответ написан
    7 комментариев
  • Вопрос по таблице приведения/преобразования типов?

    nowm
    @nowm
    В этой таблице подразумевется, что значение из первой колонки присваивается переменной x, а из второй — переменной y. После этого делаются сравнения x == y, x === y и Object.is(x, y).

    Соответственно, шестая строка подразумевает, что вы делаете такое присваивание:

    const x = {foo: "bar"};
    const y = x;
    Ответ написан
    Комментировать
  • Как сделать анимацию изменения цвета в секундах?

    nowm
    @nowm
    Можно сделать так:

    const colors = ['black', '#252240', /*далее все нужные цвета по этому же принципу*/];
    
    // Это вместо всех блоков if (seconds.innerText == N)
    seconds.style.color = colors[parseInt(seconds.innerText) || 0] || colors[0];
    Ответ написан
    Комментировать
  • Функция toLocaleString. Не получается сделать отступы?

    nowm
    @nowm
    Вместо ${data.items[key].price*1.2} можно написать
    ${parseInt(data.items[key].price*1.2).toLocaleString('ru-RU')}
    и не будет никакой проблемы, и не нужно будет дополнительно делать $('.content__api__price').each(function() {}) и фиксить формат.

    (Извиняюсь за форматирование. Я всё писал в одну строку, просто «Хабр Q&A» не умеет переносить длинный код внутри строки и получается не очень красиво, когда он его начинает лепить с новой строки.)
    Ответ написан
    1 комментарий
  • Почему происходит неправильный вывод двумерного массива?

    nowm
    @nowm
    function cityToCountry(city) {
        const countries = ['Казахстан', 'Россия', 'Китай', 'США'];
    
        let cities = [[],[],[],[]]
        array[0][0] = 'Астана';
        array[0][1] = 'Караганда';
        array[0][2] = 'Актобе';
        array[0][3] = 'Алмата';
        array[1][0] = 'Москва';
        array[1][1] = 'Новосибирск';
        array[1][2] = 'Сочи';
        array[1][3] = 'Омск';
        array[2][0] = 'Пекин';
        array[2][1] = 'Шанхай';
        array[2][2] = 'Сиань';
        array[2][3] = 'Харбин';
        array[3][0] = 'Нью-йорк';
        array[3][1] = 'Чикаго';
        array[3][2] = 'Вашингтон';
        array[3][3] = 'Даллас';
    
        for (let i in cities) {
            if (!cities.hasOwnProperty(i)) {
                continue;
            }
    
            for (let j in cities[i]) {
                if (!cities[i].hasOwnProperty(j)) {
                    continue;
                }
    
                if (cities[i][j] === city && countries[i]) {
                    return countries[i];
                }
            }
        }
    
        return 'Город не найден';
    }
    
    let city = prompt('Введите название города:', '');
    
    alert(cityToCountry(city));


    Я где-то прочитал ваш комментарий о том, что вам обязательно нужно использовать массивы и конкретно в таком виде, как вы их описали. На эту тему могу сказать, что вам, возможно кто-то навязывает методы решения задачи, которые изначально заставляют вас ходить кругами и писать долбанутый код. Либо вы самостоятельно хотите нарезать круги вместо того, чтобы кратчайшим способом прийти к решению.

    Самый короткий путь для решения такой задачи:

    const cityToCountry = {
        'Астана': 'Казахстан',
        'Караганда': 'Казахстан',
        'Актобе': 'Казахстан',
        'Алмата': 'Казахстан',
        'Москва': 'Россия',
        'Новосибирск': 'Россия',
        'Сочи': 'Россия',
        'Омск': 'Россия',
        'Пекин': 'Китай',
        'Шанхай': 'Китай',
        'Сиань': 'Китай',
        'Харбин': 'Китай',
        'Нью-йорк': 'США',
        'Чикаго': 'США',
        'Вашингтон': 'США',
        'Даллас': 'США',
    };
    
    const city = prompt('Введите название города:', '');
    if (!cityToCountry.hasOwnProperty(city)) {
        alert('Такого города не найдено');
    } else {
        alert(`Для города «${city}» найдена страна «${cityToCountry[city]}»`);
    }


    Этот код работает быстрее, и подход, который в нём используется, уменьшает количество точек отказа. Если вы всегда будете стремиться идти к цели прямыми путями, а не нарезать круги, вы лучше состоитесь, как программист. Но это дело ваше.
    Ответ написан
    1 комментарий
  • Как присвоить данные из callback functions в внешнюю переменную?

    nowm
    @nowm
    Вообще, тут всё правильно (за исключением того, что нужно писать «снаружи», а не «с наружи»). Просто вы видите в консоли undefined из-за того, что пытаетесь читать значения снаружи до того, как нажали кнопку — переменным в этот момент тупо не присвоились никакие значения.

    Чтобы вы понимали логику:

    // Шаг 1: Определяются переменные
    let control_input1;
    let control_input2;
    
    // Шаг 2: Вешается обработчик
    Proekt_button.addEventListener('click',function(){
        // Шаг 4: Кнопка нажата
    });
    
    // Шаг 3: Что-то печатается в консоль
    console.log('Данные снаружи функции',control_input1);
    console.log('Данные снаружи функции', control_input2);


    Так вот, шаги 1, 2, и 3 выполняются сразу — без задержек. А шаг 4 выполняется только когда вы нажимаете кнопку. То есть, в момент, когда выполняется шаг 4, шаг 3 уже давно прошёл и вы увидели в консоли значение undefined не после нажатия кнопки, а до.

    Чтобы у вас всё время всё было заполнено, можно определять переменные так:

    // Неправильно
    // let control_input1;
    // let control_input2;
    
    // Правильно — вот так надо делать
    let control_input1 = Control_1.value;
    let control_input2 = Control_2.value;


    То есть, если до нажатия кнопки в инпутах будут какие-то дефолтные значения, они сразу попадут в эти переменные — до нажатия кнопки.
    Ответ написан
    1 комментарий
  • Как сделать чтоб при клике на кнопку появлялся div,при клике вне его чтоб закрывался?

    nowm
    @nowm
    Обычно, если вы хотите добавить какую-то вещь, вам нужно полностью понимать её логику работы, чтобы это описать в коде. То есть, если вы можете описать весь функционал с помощью алгоритма, есть смысл самостоятельно это писать. В противном случае, лучше воспользоваться готовым решением, вроде Dropdowns или Modals из Bootstrap, потому что это поможет сэкономить время и обеспечит определённую надёжность работы за счёт использования дополнительных ресурсов (нужно подгружать CSS- и JS-файлы бутстрапа).

    Самостоятельное понимание обычно приходит с опытом. То есть, например, если я хочу написать модал, я сначала должен понять, что такое этот мой модал и как он себя должен вести в различных ситуациях. По сути, это какой-то элемент, который выводится на переднем плане и блокирует всё остальное. То есть, мне нужно создать один полноэкранный элемент (1), который будет блокировать всё остальное, а потом поместить в него другой элемент (2), который будет отображать нужный мне контент. При клике по элементу 1 мне нужно скрывать оба элемента, освобождая всё, что находится на заднем плане. При этом, если я кликаю внутри элемента 2, ничего не должно происходить. Дальше, мне нужно показывать элементы 1 и 2 после определённого события, например, если я кликаю по кнопке (3).

    Вот простейший код который работает как АК-47 (так же доступно на JsFiddle для тестирования):

    HTML
    <span id="element-3">Open modal</span>
    <div id="element-1">
      <div id="element-2">
        Modal content
      </div>
    </div>


    CSS:
    body {  
      width: 100vw;
      height: 100vh;
      background-color: green;
      margin: 0;
      padding: 0;
    }
    
    #element-3 {
      border: 1px solid black;
      background-color: white;
    }
    
    #element-1 {
      display: none;
      position: fixed;
      background-color: blue;
      width: 100vw;
      height: 100vh;
      top: 0;
      left: 0;
    }
    
    #element-1.show {
      display: block;
    }
    
    #element-2 {
      background-color: red;
      width: 50vw;
      height: 50vh;
      margin: 0 auto;
    }


    JS
    var element1 = document.getElementById('element-1');
    var element2 = document.getElementById('element-2');
    var element3 = document.getElementById('element-3');
    
    element3.onclick = function() {
    	element1.classList.add('show');
    };
    
    element1.onclick = function(event) {
    	if (event.target !== event.currentTarget) {
      	return;
      }
    	element1.classList.remove('show');
    };


    После того, как вы сделали стабильно работающий функционал, можно начать его развивать. Например, нужно сделать, чтобы элемент 1 был прозрачным. Или нужно сделать, чтобы он и элемент2 появлялись/исчезали, используя анимацию, а не мгновенно. Или нужно избавиться от этих красно-сине-зелёных цветов и отображать у элемента 2 закруглённые уголки и центрировать его по вертикали. Это уже задачи другого уровня, которые решаются другими методами, которые тоже можно разбить на подзадачи и решать их так, чтобы они не ломали задачи более высокого уровня. В таком случае у вас всегда всё будет работать надёжно и предсказуемо.

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

    nowm
    @nowm
    Можно вместо split("-") сделать split(" - "), но, вообще, лучше использовать JSON, чтобы название трека и артист были в отдельных полях. Это будет надёжнее работать, потому что входные данные могут быть непредсказуемыми. Например, название артиста будет содержать «–» с пробелами, и всё опять сломается.
    Ответ написан
  • Как назначить метод обработки на input в Sweetalert2?

    nowm
    @nowm
    Можно прослушивать события на уровне документа:

    const myMethod = event => {
        if (event.target && event.target.id === 'swal-input1') {
            // Поймали событие "input" для элемента #swal-input1
        }
    };
    
    document.addEventListener('input', myMethod);
    
    const { value: formValues } = await Swal.fire({/* . . . */});
    
    document.removeEventListener('input', myMethod);


    Кстати, если вы используете ReactJS, то можно использовать sweetalert2-react-content. С ним у вас будет возможность в качестве HTML использовать компоненты ReactJS, в которых можно делать всё, что угодно, включая кастомные обработчики событий, привязанные к конкретным элементам. Можно делать примерно такую вещь:

    import SwalRaw from "sweetalert2";
    import withReactContent from 'sweetalert2-react-content';
    
    const Swal = withReactContent(SwalRaw);
    
    Swal.fire({
        html: (
            <div>
                <input onInput={console.log} id="swal-input1" className="swal2-input">
                <input id="swal-input2" className="swal2-input">
            </div>
        ),
    });


    Swal вызывается как обычно, но можно дополнительно использовать компоненты ReactJS для таких options как: title, html, confirmButtonText, denyButtonText, cancelButtonText, footer и closeButtonHtml.
    Ответ написан
  • Почему gulp uglify выдаёт ошибку?

    nowm
    @nowm
    Uglify не поддерживает ES6 и следующие версии JavaScript. Это значит, что он будет падать с ошибкой, если в коде используются такие вещи:

    const alertLangs = langs => alert(langs);
    
    localStorage.getItem(key: "langs");


    Чтобы Uglify не ругался, нужно либо писать код, который соответствует стандарту «ECMAScript 5», либо использовать препроцессоры, вроде gulp-babel до вызова .pipe(uglify()).

    const babel = require('gulp-babel');
    
    ...
    return src(path.src.js, {base: './src/assets/js/'})
        .pipe(...)
        .pipe(...)
        .pipe(babel({
            presets: ['@babel/preset-env']
        }))
        .pipe(uglify())
        .pipe(...)
        .pipe(...)
    
    ...
    Ответ написан
    Комментировать
  • Как организовать структуру хранения javascrirpt-файлов для многостраничного сайта?

    nowm
    @nowm
    Лично мне понравилось использование webpack. Я прописываю в конфиге все entry-файлы, а webpack потом за меня генерирует итоговый JS-файл. При этом, webpack во время генерации выдёргивает только тот код, который реально используется. Например, у меня есть файл functions.js:

    export function function1() {
        alert('function 1');
    }
    
    export function function2 () {
        alert('function 2);
    }


    Далее, я создаю файл landing.js:

    import {function1} from './functions';
    
    function1();


    После работы webpack будет создан файл, который содержит код из landing.js и functions.js, при этом function2 там не будет, потому что этот код не использовался.

    Посоветовать хорошее руководство по конфигурации webpack не могу, потому что я разбирался с ним сам — по документации. Сразу предупреждаю, что это не самая простая технология для освоения, и у вас может уйти несколько часов на одно только написание конфига. Но его плюсы перевешивают минусы, так что советую попробовать.

    P.S. На хабре есть много статей про webpack. Есть смысл начать поиски там. Я уверен, что среди over 900 статей там есть что-нибудь для новичков. Ну, или, гугл в помощь.
    Ответ написан
    Комментировать
  • Почему try..catch не отлавливает ошибку?

    nowm
    @nowm
    Проблема в том, что XMLHttpRequest выкидывает только два исключения:

    exception XMLHttpRequestException {
      unsigned short     code;
    };
    const unsigned short NETWORK_ERR = 101;
    const unsigned short ABORT_ERR = 102;


    NETWORK_ERR — ошибка сети.
    ABORT_ERR — пользователь отменил запрос.

    Ещё один немаловажный момент: NETWORK_ERR и ABORT_ERR не выкидываются в асинхронном режиме.

    Всё остальное отлавливаться не будет, и нужно писать свой обработчик, который, например, будет реагировать на код ответа 404 от сервера и т.д.

    function test(data) {
     // taking care of data
    }
    
    function handler() {
     if(this.readyState == 4 && this.status == 200) {
      // so far so good
      if(this.responseXML != null && this.responseXML.getElementById('test').firstChild.data)
         // success!
       test(this.responseXML.getElementById('test').firstChild.data);
      else
       test(null);
     } else if (this.readyState == 4 && this.status != 200) {
      // fetched the wrong page or network error...
      test(null);
     }
    }
    
    var client = new XMLHttpRequest();
    client.onreadystatechange = handler;
    client.open("GET", "test.xml");
    client.send();


    Здесь function handler() — обработчик, а client.onreadystatechange = handler; — привязка этого обработчика к экземпляру XMLHttpRequest.

    Просто ответ от сервера с кодом «404 Страница не найдена» не считается за NETWORK_ERR, потому что сервер ответил на запрос. А то, с каким он кодом ответил — это уже на другом уровне обрабатывается.
    Ответ написан
    6 комментариев
  • Почему получается неверный результат RegExp в javascript?

    nowm
    @nowm
    r.test("абвabc"), кстати, тоже покажет true. У вас регулярка написана так, что она возвращает true, если в строке есть хотя бы один символ из [A-Za-z0-9], но она совсем не запрещает использовать кроме разрешённых символов остальные. Если в куче неразрешённых символов будет хотя бы один разрешённый, она вернёт true. Нужно по краям регулярки добавить символы начала и конца строки:

    var r = new RegExp("^[A-Za-z0-9]+$");
    Ответ написан
    Комментировать
  • Почему не работает javascript, если к домену приписать "www.", и как выйти из положения?

    nowm
    @nowm
    Если вы посмотрите содержимое страницы, которая открывается с www, то в теге «BASE» будет прописан адрес без www. Это такая особенность опенкарта. В кнопке «заказать» адрес выглядит как «index.php?route=бла-бла-бла». Так как у этого адреса нет в начале знака «/», браузер возьмёт для построения полного адреса значение из BASE. Тогда получается, что на странице «http://www.site.ru» ссылка для кнопки «заказать» выглядит как «http://site.ru/index.php?route=бла-бла-бла». И это уже кросс-доменный запрос, который в вашем случае не работает.

    Как решение, все страницы должны открываться по одному домену. Нужно сделать перенаправление с www-адресов на адреса без www с помощью .htaccess.

    RewriteCond %{HTTP_HOST} ^www.site.ru
    RewriteRule (.*) http://site.ru/$1 [R=301,L]


    Это будет более простое решение, чем исправлять адреса в движке Opencart, так как я находил там около 90 адресов, которые в таком случае придётся править. Вы, допустим, правкой адреса поправите работу кнопки «заказать», но от этого не начнут работать кнопки «добавить в желаемое», «добавить в сравнение» и т.п. Там куча таких моментов. Так что, настройка перенаправления в .htaccess позволит решить сразу все эти проблемы.
    Ответ написан
    2 комментария
  • Как передать значение переменной из php-скрипта в javascript?

    nowm
    @nowm
    Первый способ: Отдельный AJAX-запрос к PHP-файлу, который вернёт что-нибудь вроде JSON-данных, которые потом будут доступны из JS.

    Второй способ: В PHP-файле можно определить какую нибудь переменную во время генерации страницы, а потом из любых скриптов к ней обращаться. Например так:

    PHP-файл:
    <?php
    $a = 'text for js_variable';
    ?>
    <!DOCTYPE html>
    <html>
      <head>
        <script>
          //Определяется переменная, которая будет доступна для 
          // всех JavaScript, подключаемых на данной странице
          var js_variable = '<?php echo $a; ?>';
        </script>
        <!-- 
          В файле /scripts/myscript.js происходит обращение 
          к переменной js_variable 
        -->
        <script src="/scripts/myscript.js"></script>
      </head>
      <body>blah-blah-blah</body>
    </html>


    Файл /scripts/myscript.js:
    // Выскочит алерт с текстом «text for js_variable».
    alert(js_variable);


    Вот. В HEAD-части HTML-страницы вы определяете переменную, которая будет доступна для остального JS-кода. Главное — нужно её определять до того, как будут подключены скрипты, которые будут её использовать.

    Третий способ: Если ваш web-сервер — Apache, то можно добавить в .htaccess в корне сайта такие строки:
    AddType application/x-httpd-php .js
    AddHandler x-httpd-php5 .js
    
    <FilesMatch "\.js$">
    SetHandler application/x-httpd-php
    </FilesMatch>


    Тогда вы сможете прямо в JS-файлах выполнять PHP-код. Но выполняться он будет только в тех JS-файлах, которые находятся в папке с сайтом. Если будут загружаться скрипты со сторонних ресурсов, там PHP-код работать не будет.
    Ответ написан
    Комментировать
  • Как вырасти из верстальщика в JS-программиста?

    nowm
    @nowm
    «Гордое звание» — это когда есть награды, дипломы, сертификации и прочее. Вообще, к слову, я уже лет 5 пишу на PHP почти каждый день и всё равно не считаю себя программистом. Возможно, когда у меня будет диплом от Zend, я буду думать, что я что-то вроде программиста.

    Если вам шашечки нужны, то сдавайте всякие_сертификации, если же нужно ехать, то лучше просто писать код и не загоняться, гордое у вас звание или нет.

    Upd. А вообще, извините за ёрничество. Возможно вам помогут некоторые мысли на эту тему:

    Выражение «просто пиши код», на самом деле, — это квинтэссенция. Просто некоторым людям становится неохота несколько раз разными словами описывать одно и тоже, и родился такой концентрат — который, как Yupi, куда можно «просто добавить воды», и получится готовый продукт. По сути, большую часть советов можно свести к этой одной фразе [пиши код]. Можно (даже нужно) для развития прочитать кучу книжек, но если вы мысли из этих книг не оформите кодом, толка от этого развития не будет, и программистом вы не станете. Мышцы будут развиваться только в том случае, если вы их напрягаете, а не только читаете инструкции, как их правильно напрягать. Инструкции помогут это делать правильно, но без практики не будет никакого развития.

    Для постоянного развития нужен постоянный поток работы с новыми необычными заданиями. В веб-студиях обычно с новыми необычными заданиями очень туго бывает. Моё мнение, что долгая работа в веб-студии — дорога, которая убивает любознательность начисто. Через некоторое время работа становится настолько однотипной, что, кажется, можно бота написать, который будет за вас её делать. Новые задачи, которые напрягают мозги и не позволяют пользоваться готовыми решениями — очень хороший движитель, но за целый день делания однотипной работы в веб-студии, самостоятельно искать новые задачи становится неохота — всё же есть такая штука как оффлайн и, вообще, банальная усталость и тупиздняк от однотипной работы.

    Когда вы пользуетесь каким-нибудь готовым решением, полезно заглядывать к нему под капот. У меня примерно похожая история была с Opencart. Я в какой-то момент очень сильно начал загоняться процессами, происходящими на этапе инициализации движка и отдельными классами, входящими в его состав. В результате родилось решение, которое позволило использовать PDO, вместо mysql_*, при этом, оно хорошо работало на боевых серверах и не ломало модули, где использовался старый подход. По сути, особенно заметной разницы в быстродействии не стало, но лично для меня это был хороший буст. (Я потом ещё загнался тем, чтобы выдрать из опенкарта костяк и использовать его в качестве своеобразного бутстрапа, на котором можно собрать любой сайт. Вряд ли я всё это дело буду где-то публиковать и использовать, но, опять же, лично для меня это было полезным для развития процессом.)

    После того, как вы сделали работу, тысячу раз её перепроверьте и сделайте кучу ненужных замеров производительности и потребления ресурсов. Попробуйте всё это дело как-нибудь оптимизировать. Например, сдали работу — всех всё устраивает, денег заплатили и т.п. В этой ситуации нужно загнаться тем, чтобы снизить потребление памяти на 10% процентов. Никто не заметит, что вы огромную работу сделали, чтобы снизить потребление, но это будет лично для вас практика. Можно сделать какую-нибудь ненужную работу, вроде выкидывания из исходников jQuery всех функций, которые вы никогда не будете использовать. Или, наоборот, можно что-то своё добавить. По сути, постоянное развитие — это как жизнь киргизского комсомольца, который постоянно ищет себе проблемы, чтобы потом их героически преодолевать.

    А ещё... а ещё... У меня очень большая куча мыслей — я наверное когда-нибудь напишу книжку, чтобы все их аккуратно уложить в голове.

    Первый шаг, который нужно сделать: заняться каким-нибудь личным проектом, где вы сможете развивать свои навыки (и, даже, не обязательно его выпускать за пределы локальной машины). Что угодно. Например, калькулятор с какими-нибудь расширенными функциями. Тут как раз на вёрстку будет минимальный упор. В этом проекте нужно отказаться от использования любых сторонних библиотек и изобретать свои решения. Например, вам хочется делать выбор элементов из DOM простыми селекторами с синтаксисом, похожим на jQuery, смотрите, как это реализовано в jQuery и пишите с нуля свой аналог. Главное не копипастить, а писать самостоятельно. Пусть будет похоже, но будет не точная копия. Вы в процессе будете напрягать мозги и развиваться. Будете часто лазать в документацию по языку. У вас появится понимание не многочисленных фреймворков, а именно чистого нативного кода и функций. И мыслить вы начнёте не категориями «какую функцию jQuery можно использовать», а категориями «какой алгоритм сюда можно придумать».

    Это всё сравнимо с обычной грамотностью и умением выражать мысли — чтобы развиваться, нужно читать и писать. В любом случае, писать код всё равно придётся. Без этого программистом не станешь.
    Ответ написан
    4 комментария
  • Как называется подход, обеспечивающий работоспособность сайта с отключенным javascript?

    nowm
    @nowm
    Как один из вариантов, это называется Progressive enhancement (EN). На хабре ещё есть статья про такой подход.
    Ответ написан
    Комментировать