Ответы пользователя по тегу JavaScript
  • Замена iframe на js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Попробуйте сохранять вид сайта в картинку через PhantomJS – по ссылке пример, как сохранить главную страницу github в файл png.

    Нужно скачать PhantomJS, создать js-файл с 5 строчками из примера, и запустить из командной строки примерно так: phantomjs github.js

    PhantomJS – это не JS-библиотека, это Webkit браузер, управляемый через JavaScript API. Как заметил hOtRush Google также анонсировал «безголовую» версию своего браузерного движка Chromium, в связи с чем проект PhantomJS может потерять актуальность. Тем не менее, пока он вполне рабочий, и обновляется сообществом разработчиков (последний коммит на сегодня – двухмесячной давности, от 25 июня 2017).

    Вы можете установить PhantomJS на своем сервере и вызывать его через exec() из php-скрипта, принимающего URL сайта, который надо перевести в картинку. Это самый простой вариант. Минус – в том, что PhantomJS жрёт много памяти, и если несколько посетителей запросят одновременно несколько заданий, памяти на всех может не хватить. В таком случае организуйте асинхронную очередь задач. Поступающие запросы с URL ставьте в очередь, которая последовательно обрабатывается всего одним процессом phantomjs. По мере готовности, заказчики смогут забрать готовые картинки сайтов.
    Ответ написан
  • Можно ли написать код лаконичнее?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Переписать код короче – можно:
    $("a").click( function(e){ $(this).attr('href') || e.preventDefault() });


    Если поясните, чего добиваетесь таким кодом, можно предложить решение лучше.
    Ответ написан
    Комментировать
  • Каким образом свойство функции me i (me.i) получает доступ к значению цикла?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Этот вопрос и именно этот пример подробно разбирается на learn.javascript.ru в разделе Армия функций.

    Нажмите кнопку Решение там внизу.
    Ответ написан
    Комментировать
  • Заполнения массива на Javascript?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно просто перебирать по очереди все и проверять выполнение одного из условий:
    принадлежность диагонали, положение точно по середине оси X или Y:
    function makeStar(side) {
      var arr = new Array(side), x, y, mid = (side-1)/2;
      for( y = 0; y < side; y++) {
        row = arr[y] = new Array(side);
        for( x = 0; x < side; x++) {
          row[x] = (y===x || x===side-1-y || x===mid || y===mid) ? 1 : 0;
        }
      }
      return arr;
    }
    
    makeStar(4)
      .reduce((p,c)=>{ return p + c.join(',') + "\n"},'')
    
    /*
    1,0,0,1
    0,1,1,0
    0,1,1,0
    1,0,0,1
    */

    Наверняка, есть очень красивые решения этой же задачи (не искал). Можно использовать подобие – левая верхняя четверть равна нижней правой. Можно обыграть поворот вокруг центра.
    Ответ написан
    Комментировать
  • Как округлить число до сотых js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Метод объекта Number .toFixed() округляет до заданного числа знаков после десятичной точки.

    var kof1 = <?php the_field('kof21'); ?>
      , kof2 = <?php the_field('kof22'); ?>
      , sum1 = <?php the_field('sum2'); ?>
      , total_Sum
    ;
       
    total_Sum = kof1 * kof2 * sum1
    
    document.body.appendChild( document.createTextNode( total_Sum.toFixed(2) );
    Ответ написан
    1 комментарий
  • Как отрисовать данные из одного массива по 6 строк в 3ех столбцах?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Остаток от деления порядкового номера элемента в массиве на число элементов в блоке принимает нулевое значение, когда пора создавать новый блок. А предыдущий готовый, если есть, вставлять в документ.

    var i
      , w
      , div
      , box
      , label
      , parent = document.body // к чему приклеивать блоки
      , perBlock = 5 // сколько в одном блоке
    ;
      
    for( i = 0; i < widgetSettings.length; i++) {
      w = widgetSettings[i];
    
      box = document.createElement('input');
      box.type = 'checkbox';
      box.id = box.name = w.id;
      box.value = w.value;
      
      label = document.createElement('label');
      label.appendChild(box);
      label.appendChild( document.createTextNode(w.text));
      
      if( i % perBlock === 0) {
        if(div) parent.appendChild(div);
        div = document.createElement('div');
      }
      div.appendChild(label);
    }
    if( (i-1) % perBlock) parent.appendChild(div);

    Fiddle
    Ответ написан
    Комментировать
  • Необычный hover эффект?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Событие mousemove или onEnterFrame(),
    пересчитать прозрачность каждой точки, как квадрат расстояния от позиции мыши.

    Сделал пример на canvas.
    upd. добавил инертности/плавности перехода цветов.
    Ответ написан
    3 комментария
  • Как можно получить массив дат от определенной даты?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Сделать объект даты на тот момент, и прибавлять по дню.

    var D = new Date("2017-08-27")
      , Till = new Date()
      , result = []
    ;
    
    function pad(s){ return ('00' + s).slice(-2)}
    
    while( D.getTime() < Till.getTime()) {
      result.push( '' + D.getFullYear() +'-'+ pad(D.getMonth()+1) +'-'+ pad(D.getDate()));
      D.setDate( D.getDate()+1);
    }
    //  2017-08-27,2017-08-28,2017-08-29,2017-08-30,2017-08-31
    Ответ написан
    Комментировать
  • Есть ли функция, которая сравнивает id и возвращает новый массив?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Fiddle
    function findDevice(id) {
      for( let i in devices) {
        if( devices.hasOwnProperty(i) && devices[i].id === id)
          return devices[i];
    	}
    }
    
    function addDevices(p) {
      p.devices = [];
    	for( let i = 0; i < p.devices_ids.length; i++)
    	  p.devices.push( findDevice( p.devices_ids[i]));
      return p;
    }
    
    var result = people.map(addDevices);
    Ответ написан
    Комментировать
  • Как собрать данные с инпута и завернуть их в ссылку?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Fiddle
    var $in = $('#input')
      , $check = $('#check')
    	, $links = $('#links')
    ;
    
    $check.on('click', function () {
    	var val = $in.val();
    	$in.val('');
      $links.append(
    	  "<a class='link' href='#'>%VALUE%</a>"
    		  .replace('%VALUE%', val)
    	);
    });


    То же на чистом JavaScript без jQuery:
    spoiler
    var els = {
    	input: document.getElementById('input'),
    	check: document.getElementById('check'),
    	links: document.getElementById('links'),
    	link: document.createElement('a')
    };
    
    els.link.className = 'link';
    els.link.href = '#';
    
    els.check.addEventListener('click', function(){
    	var a = els.link.cloneNode();
    	a.innerText = els.input.value;
    	els.input.value = '';
    	els.links.appendChild(a);
    });
    Fiddle
    Ответ написан
  • Как сделать подстановку текста в инпут по клику?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    document
      .getElementById('e-example')
      .addEventListener('click', function(){
        document.getElementById('search').value = this.innerText;
      });

    Fiddle
    ef748af96dc149ca8580c9fb97baa66a.png
    Ответ написан
    Комментировать
  • Есть ли способ "самоуничтожить" html документ?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Надёжного / серьёзного способа нет. Миллион способов обойти это ограничение: от снимков экрана (в т.ч. буквальных, на телефон или фотоаппарат), до консоли разработчика, где видны все сетевые запросы и ответы.

    Можно «секретную» часть подгружать через ajax POST-запрос. Пользователь должен быть авторизован на вашем сайте. На сервере проверять, что именно этот пользователь ещё не получал эту инфу, и пометить, что он её получил.

    AJAX-запрос невозможен при выключенном JavaScript. Так что положимся на него же (на JS) для удаления подгруженного контента по таймауту.
    Ответ написан
    Комментировать
  • Как объединить два массива?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    У вас не массивы [] а объекты {}.

    В Underscore.js есть метод extend()
    исходник
    _.extend = createAssigner(_.allKeys);
    
      var createAssigner = function(keysFunc, undefinedOnly) {
        return function(obj) {
          var length = arguments.length;
          if (length < 2 || obj == null) return obj;
          for (var index = 1; index < length; index++) {
            var source = arguments[index],
                keys = keysFunc(source),
                l = keys.length;
            for (var i = 0; i < l; i++) {
              var key = keys[i];
              if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
            }
          }
          return obj;
        };
      };
    
      _.allKeys = function(obj) {
        if (!_.isObject(obj)) return [];
        var keys = [];
        for (var key in obj) keys.push(key);
        if (hasEnumBug) collectNonEnumProps(obj, keys);
        return keys;
      };



    В jQuery тоже есть extend().
    исходник
    jQuery.extend = jQuery.fn.extend = function() {
    	var options, name, src, copy, copyIsArray, clone,
    		target = arguments[ 0 ] || {},
    		i = 1,
    		length = arguments.length,
    		deep = false;
    
    	// Handle a deep copy situation
    	if ( typeof target === "boolean" ) {
    		deep = target;
    
    		// Skip the boolean and the target
    		target = arguments[ i ] || {};
    		i++;
    	}
    
    	// Handle case when target is a string or something (possible in deep copy)
    	if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
    		target = {};
    	}
    
    	// Extend jQuery itself if only one argument is passed
    	if ( i === length ) {
    		target = this;
    		i--;
    	}
    
    	for ( ; i < length; i++ ) {
    
    		// Only deal with non-null/undefined values
    		if ( ( options = arguments[ i ] ) != null ) {
    
    			// Extend the base object
    			for ( name in options ) {
    				src = target[ name ];
    				copy = options[ name ];
    
    				// Prevent never-ending loop
    				if ( target === copy ) {
    					continue;
    				}
    
    				// Recurse if we're merging plain objects or arrays
    				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
    					( copyIsArray = Array.isArray( copy ) ) ) ) {
    
    					if ( copyIsArray ) {
    						copyIsArray = false;
    						clone = src && Array.isArray( src ) ? src : [];
    
    					} else {
    						clone = src && jQuery.isPlainObject( src ) ? src : {};
    					}
    
    					// Never move original objects, clone them
    					target[ name ] = jQuery.extend( deep, clone, copy );
    
    				// Don't bring in undefined values
    				} else if ( copy !== undefined ) {
    					target[ name ] = copy;
    				}
    			}
    		}
    	}
    
    	// Return the modified object
    	return target;
    };
    Ответ написан
    Комментировать
  • Как сделать required для одного из трех select?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Перед тем, как «дальше» проверяйте, выбрано ли значение хотя бы в одном из трёх <select>
    Ответ написан
  • Как отрисовать контур в SVG?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Небольшая проблема была в том, что у вас этот контур состоял из двух кусков: правого верхнего уголка и всего остального (привет дизайнеру?). Исправил путь так, что теперь это один сплошной путь, без лишних точек и без ненужных групп <g>.
    скриншот
    bde82874e0b0474da2c847039e028361.png

    Делаем две копии этого пути, одна под другой. Нижняя – частым синим штрихом. Верхняя – чуть более широким штрихом и цвета фона.

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

    Чтобы срабатывали стили :hover при наведении мышки пришлось обернуть SVG в <div>

    Fiddle
    Ответ написан
    1 комментарий
  • Как написать алгоритм поиска соседних элементов?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Идея с отдельной работой по X и по Y неплохо работает. На каждом кадре проверяем каждую из 200 точек (это совсем не много).

    Сортируем массив точек по их X-координате. Двигаемся слева направо, выбирая очередную точку.

    Смотрим от неё влево (чтобы не проверять одну связь дважды, выбираем полуплоскость от точки) и отбираем только те точки, чей X отличается не более, чем на radius.

    Из них смотрим только на те, у которых Y не более, чем на radius отличается (уже в любую сторону: и вверх и вниз).

    У них проверяем уже евклидово расстояние – корень из суммы квадратов расстояний по X и по Y – чтобы было не больше radius. У таких есть «связь» – рисуем им ребро.

    Работающий fiddle (неминифицированный исходник на github)
    538264abb31847baa28fe05e015ac13c.png

    На компе даёт около 60 fps, на мобильнике от 40 до 55, т.е. совершенно приемлемая скорость при 200 точках.

    Первая версия ответа

    Интересна ситуация, наихудшая для оптимизации: когда за 1 кадр может поменяться максимальное число связей. Предположу, что это сетка из равносторонних треугольников, где длина ребра равна «триггерной» дистанции:
    картинка треугольной сетки
    5297fe1c584f4551aca5b77a2a987549.jpg
    Тут большинство точек, кроме крайних, взаимосвязаны. У каждой по 6 ближайших соседей. Примерно 200 * 6 / 2 = 600 связей (чуть меньше из-за краёв).

    Если такую сетку пропорционально увеличить на любую малую величину, сразу все связи порвутся, их станет ноль. Пусть на месте останется, скажем, левый верхний угол сетки. Тогда наибольший путь проделает нижний правый угол. Тут вопросы к особенностям вашей задачи:
    1. округляются ли координаты до целых или до какой-то точности?
    2. какой наибольший путь может проделать за один кадр точка?

    В идеальном мире всем достаточно проделать бесконечно малый шаг, и, вуаля!, было 600 связей, стало 0. Такой же шажок назад – не было связей, и вот их 600. Т.е. надо бы в каждый кадр проверять 600 ребер. Считать это за теоретический предел оптимизации?

    Сущности
    Точки и рёбра. Ребро ссылается на две точки. Точка ссылается на рёбра. Ребро имеет длину и, в зависимости от длины, может быть «видимым».

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

    Можно давать рёбрам веса, пропорциональные желаемой частоте их обновления. Скажем, от 0 до 1. Вес равный 1 значит, что нужно проверять каждый кадр. Например, вес W = Math.max(0, D - Math.abs( length - D))/D, где D – пороговая дистанция.

    Остаётся сделать механизм, отбирающий рёбра в работу на очередном кадре, исходя из их весов. Запоминать время, когда ребро было обновлено. Приоритет его попадания в обработку равен W * (time - timeUpdated)
    Ответ написан
    3 комментария
  • Как оптимизировать svg-файл, в котором находится 5 000 точек, для встраивания на страницу?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Браузеру тяжеловато отрисовываеть такое количество элементов.

    Canvas вместо SVG не рассматривали?
    Ответ написан
    1 комментарий
  • Как отрисовать SVG при наведении?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Отрисовку делают изменяя смещение очень длинного штриха stroke-dashoffset, так, чтобы штрих появлялся, создавая эффект прорисовки.

    В вашем случае, можно делать наоборот - исчезновение сплошной линии цвета фона, скрывающей под собой такую же, но частым пунктиром.

    Недавно отвечал на близкий вопрос и сделал демо.
    Ответ написан
    3 комментария
  • Как вычислить пересекаются ли много многоугольников?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Вкратце:
    1. набросать фигуры по сетке. Пусть они где-то накладываются, где-то выходят за границу полотна.
    2. дать им «расслабиться» – будто они льдины, свободно плавающие. И при этом взаимно-отталкиваются. Для упрощения можно посчитать, что каждая точка отталкивается от всех точек других фигур, сила пропорциональна квадрату расстояния. Просчитать несколько «шагов» такого плавания.

    Для определения, пересеклись ли полигоны, как уже написал Хасан Истамкулов, надо проверять пересечение отрезков. Если у двух фигур найдётся, что какие-то два отрезка пересеклись, значит есть коллизия:
    8186a53eefde4e0dbbba93ce279bf961.png
    Ответ написан
    Комментировать
  • JS: getImageData / putImageData как скопировать изображение?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    у putImageData() две сигнатуры: 3 аргумента или 7 аргументов:
    ctx.putImageData(imagedata, dx, dy);
    ctx.putImageData(imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight);


    выдрать из него кусочек.. например [0, 0, 10, 10]

    var pixels = context.getImageData(0, 0, 320, 240);
    var data = pixels.data; // в data попадает одномерный массив.
    target.putImageData( pixels, 15, 15, 0, 0, 10, 10);
    /*
    15, 15 – где разместить (отступив по 15px слева сверху в target'е)
    0, 0 – откуда копировать в координатах context'а
    10, 10 – ширина, высота региона копирования
    */
    Ответ написан
    3 комментария