пятница, 22 мая 2015 г.

Клонировать объект типа Date в JavaScript

var d1 = new Date();
var d2 = d1; // так не клонируется
d1.setMonth(d2.getMonth()+1); // меняем месяц в d1 - поменяется ли
                              // при этом d2?
alert(d2-d1); // ноль, потому что меняя  d1, меняем и d2

d2 = new Date(d1.getTime()); // клонируем
d1.setMonth(d2.getMonth()+1);
alert(d2-d1); // не ноль - клонирование прошло успешно 
Кстати, клонировать любой объект в JS можно так (понятно, что имеется в виду «клонировать данные объекта», то есть фактически клонировать JSON структуру с данными, методы объекта, если они есть, при этом не будут клонированы, то есть такой метод не подойдёт для клонирования дат):
// клонируем объект cloningObject
var newObject = JSON.parse(JSON.stringify(cloningObject));

четверг, 3 июля 2014 г.

Центрирование Яндекс карты - JavaScript API 2.x


Задача: используя JavaScript API 2.x Яндекс карт, добавить на карту N точек по их координатам и автоматически подобрать масштаб карты (zoom) и координаты центра.

Решение

// Экземпляр Яндекс карт
var myMap;
// Предполагаем, что points - исходный массив координат точек,
//  добавляемых на карту
var points = [
  ["55.768715", "37.510193"],
  ["55.728373", "37.669054"], 
  ["55.823500", "37.631000"],
  ["55.773300", "37.555100"]
];
// Выполняем наш код, когда API загружен - ymaps.ready()
ymaps.ready(function(){
  // Коллекция гео-точек, добавленных на карту
  var myCollection = new ymaps.GeoObjectCollection();
  // Помещаем карту в элемент DIV с id, равным «map»
  myMap = new ymaps.Map("map", {
    center: [50, 50], // Начальные значения центра карты
    zoom: 15,         // Начальное значение зума карты
    controls: ['zoomControl']
  });

  // Перебираем в цикле точки, которые надо добавить на карту
  for (i = 0; i < points.length; i++ ){
    var myPlacemark = new ymaps.Placemark([
      points[i][0], points[i][1]
    ]);
    // Не забываем добавить точку в коллекцию -
    //  впоследствии мы добавим всю коллекцию на карту
    myCollection.add(myPlacemark);
  }

  // Добавляем точки на карту
  myMap.geoObjects.add( myCollection );	
  // Вычисляем необходимые координаты краёв карты и
  //  устанавливаем их для нашего экземпляра карты	
  myMap.setBounds( myCollection.getBounds() );
});


воскресенье, 23 февраля 2014 г.

Быстро удалить ботов из группы

Плохо, когда в списке подписчиков группы/паблика ВКонтакте много заблокированных аккаунтов - «собачек», это вызывает недоверие пользователей. Собачек надо удалять. Но при количестве подписчиков свыше нескольких тысяч вручную это делать очень долго и утомительно. Все можно автоматизировать - и очень просто:)

Я написал специальный JavaScript код для определения собачек и их автоматического удаления. Код можно выполнить в консоли Chrome Developer, консоли Firebug или - что проще для большинства - просто скопировав его в адресную строку на открытой странице редактирования участников паблика.

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



Простейший способ запустить скрипт - открыть страницу редактирования подписчиков паблика и скопировать код в адресную строку, дополнив его в начале текстом javascript:. Таким образом, текст в адресной строке будет выглядеть как-то так: javascript:var timeout = 20; var head = ... . Можно создать закладку с этим кодом и впоследствии вызывать ее быстро со страницы одним кликом.
Код:

var timeout = 20;
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type= 'text/javascript';
script.src= 'https://code.jquery.com/jquery-2.1.0.min.js';
head.appendChild(script);

function checkJQLoaded(){return typeof $ != 'undefined' && $.fn != 'undefined';}
var loadJQ = setInterval(function () {
    timeout--;
    if (checkJQLoaded()) {
      loadAllAccounts();
      clearInterval(loadJQ);
      return;
    }
    else if (timeout > 0) {
      return;
    }
    else {
      alert('Что-то я не могу загрузить JQuery. '
            + 'Попробуйте обновить страницу и сделать всё заново!');
      clearInterval(loadJQ);
    }
}, 100);


var allCnt = 0;
var dogsCnt = 0;
var accountsCnt;

function loadAllAccounts(){
    var initialHeight = 0; var stops = 0;
    accountsCnt = $('div#gedit_users_summary_members').text()
                  .replace(/\D/g, '');
    var sInterval = setInterval(function(){
        if (initialHeight == document.body.clientHeight
            && $('img.gedit_user_img').length+15 > accountsCnt){
             stops++;
             if (stops > 30
                 && $('img.gedit_user_img').length+15 > accountsCnt) {
                   clearInterval(sInterval); go(); return;
             }
         } else {
             stops = 0;
         }
         initialHeight = document.body.clientHeight;
         $('a#gedit_users_more_members').click();
         scrollTo(0, 9999999999);
    }, 100);
}

function go(){
  $('img.gedit_user_img').each(function(){
    var src = $(this).attr('src');
    allCnt++;
    if (src != '/images/deactivated_200.png' && src != '/images/deactivated_100.png')
      $(this).parent().parent().parent().hide();
    else
      dogsCnt++;
    });

    if (confirm('Всего обработано подписчиков: ' + allCnt
        + '; собачек: '
         + dogsCnt + ' (' + (100*dogsCnt/allCnt).toFixed(2) + '%)\n'
         + 'Удаляем собачек?')){
        var dogsArray = $('img[src="/images/deactivated_200.png"],img[src="/images/deactivated_100.png"]');
        var currentDogIndex = 0;
        var dogsInterval = setInterval(
          function(){
            if (!dogsArray[currentDogIndex]){
              clearInterval(dogsInterval);
              return;
            }

            $(dogsArray[currentDogIndex]).parent().parent().parent()
                .find("a.gedit_user_action").last().click();
            currentDogIndex++;
          },
        1000
      );
    }
}

среда, 22 января 2014 г.

Макросы в Vim



Начало записи макроса: q1 (вместо 1, конечно, может быть любое другое число - это номер макроса, который будет использоваться при его вызове)

Окончание записи макроса: q

Выполнение макроса: @1

Все команды выполняются в визуальном режиме.
И ещё одно вводное видео про Vim:

среда, 11 декабря 2013 г.

Снять ограничения с PDF


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

Запилил свой.

Встречайте - hack-pdf.com - то, как я вижу хороший сервис.


понедельник, 25 ноября 2013 г.

Using Grep command for search in project sources

Problem: fast search some code blocks in big projects with lots of nested directories using command-line tools.

Solving: you need grep command. Its really great tool for search text in files with regular expressions, coming from Unix OS and now available on Windows, *nix and Mac OS. All you need is:

grep -rin --include="*.php" "function Action(" /path/to/directory/

So, let's consider parameters passed to grep command:

  • -r — the search will be recursive, that is in all subdirectories in our main directory
  • -i — the search will be case insensitive
  • -n — output will contain line numbers
  • --include="*.php" — search will be only in files that has php extension. Of course, available all regular expressions for describing needed file names
  • "function Action(" — needed text
  • /path/to/directory — directory for search accordingly

If you need just filenames without in-line matches, you can use parameter -l:

grep -rinl --include="*.php" "function Action(" /path/to/directory/

That's all - good luck in your search:)

среда, 20 ноября 2013 г.

Git и Bitbucket за 20 минут


Git - распределенная система контроля версий файлов, созданная под руководством Линуса Торвальдса. Системы контроля версий позволяют хранить несколько версий одних и тех же файлов с возможностью возврата к старому варианту, просмотра изменений, их авторов и т.д.

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

Про Git есть отличная бесплатная книга с соответствующим названием Pro Git, также спасибо соотечественникам за бескорыстный перевод - рекомендую.

Здесь я приведу краткие данные, позволяющие быстро начать работу с Git и Bitbucket. Bitbucket - это сервис, централизованно хранящий репозитории Git, бесплатный для 5 пользователей и платный для больших команд. Преимущество Bitbucket перед аналогичным сервисом GitHub - возможность создания закрытых репозиториев (не open source).