Для получения полного доступа
зарегистрируйтесь.
RSS

Все сниппеты с тэгом «JavaScript»

JavaScript / JS
JavaScript — прототипно-ориентированный сценарный язык программирования. Является реализацией языка ECMAScript (стандарт ECMA-262). JavaScript обычно используется как встраиваемый язык для программного доступа к объектам приложений.


Gravatar image
Антон
  • Репутация: 3
  • Сниппеты: 1
  • Ревизии: 0

JS-костыль, чтобы писать отдельные CSS или JS под MacOS

//если нет Modernizr на проекте
if (navigator.userAgent.indexOf('Mac') > 0) {
    var elemHTML = document.getElementsByTagName('html')[0];
 
    elemHTML.className += " mac-os";
 
    if (navigator.userAgent.indexOf('Safari') > 0) elemHTML.className += " mac-safari";
    if (navigator.userAgent.indexOf('Chrome') > 0) elemHTML.className += " mac-chrome";
}

//если есть Modernizr на проекте
Modernizr.addTest({ macos: !!(navigator.userAgent.indexOf('Mac') + 1) });

Modernizr.addTest({
    macsafari: Modernizr.macos ? !!(navigator.userAgent.indexOf('Safari') + 1) : false,
    macchrome: Modernizr.macos ? !!(navigator.userAgent.indexOf('Chrome') + 1) : false
});

Valentin Sayik
  • Репутация: 37
  • Сниппеты: 5
  • Ревизии: 0

Этим скриптом можно получить изображение из буфера обмена при нажатии ctrl+v на js. Работает только в хроме и мозиле. Может кто обращал внимание, в вк, в переписке есть возможность прикрепления картинки в диалог прямо из буфера, с этим скриптом вы можете реализовать то же самое.

// проверяем, поддерживает ли браузер объект Clipboard
// если нет создаем элемент с атрибутом contenteditable
if (!window.Clipboard) {
   var pasteCatcher = document.createElement("div");
    
   // Firefox вставляет все изображения в элементы с contenteditable
   pasteCatcher.setAttribute("contenteditable", "");
    
   pasteCatcher.style.display = "none";
   document.body.appendChild(pasteCatcher);
 
   // элемент должен быть в фокусе
   pasteCatcher.focus();
   document.addEventListener("click", function() { pasteCatcher.focus(); });
} 
// добавляем обработчик событию
window.addEventListener("paste", pasteHandler);
 
function pasteHandler(e) {
// если поддерживается event.clipboardData (Chrome)
      if (e.clipboardData) {
      // получаем все содержимое буфера
      var items = e.clipboardData.items;
      if (items) {
         // находим изображение
         for (var i = 0; i < items.length; i++) {
            if (items[i].type.indexOf("image") !== -1) {
               // представляем изображение в виде файла
               var blob = items[i].getAsFile();
               // создаем временный урл объекта
               var URLObj = window.URL || window.webkitURL;
               var source = URLObj.createObjectURL(blob);                
               // добавляем картинку в DOM
               createImage(source);
            }
         }
      }
   // для Firefox проверяем элемент с атрибутом contenteditable
   } else {      
      setTimeout(checkInput, 1);
   }
}
 
function checkInput() {
    var child = pasteCatcher.childNodes[0];   
   pasteCatcher.innerHTML = "";    
   if (child) {
// если пользователь вставил изображение – создаем изображение
      if (child.tagName === "IMG") {
         createImage(child.src);
      }
   }
}
 
function createImage(source) {
   var pastedImage = new Image();
   pastedImage.onload = function() {
      // теперь у нас есть изображение из буфера
   }
   pastedImage.src = source;
}

Gravatar image
zular
  • Репутация: 36
  • Сниппеты: 7
  • Ревизии: 0

Регулярное выражение для проверки ФИО.

Пример валидный имен

  • Петров Петр Петрович
  • Петров-Черный Петр Петрович
  • И Иван Иванович
  • Ли Лу Янг
  • Dwain Simmons
  • Dwain-Branden Simmons
  • Салим-оглы Мамед
  • Салим-кызы Лейла

Не проходит валидацию

  • фамильные приставки (фон, цу, ибн-, абу-)

Исправлено

  • фамилии из одной буквы (И Иван Иванович)
  • тюрские отчества с постфиксными -оглы/кызы
/^([А-ЯA-Z]|[А-ЯA-Z][\x27а-яa-z]{1,}|[А-ЯA-Z][\x27а-яa-z]{1,}\-([А-ЯA-Z][\x27а-яa-z]{1,}|(оглы)|(кызы)))\040[А-ЯA-Z][\x27а-яa-z]{1,}(\040[А-ЯA-Z][\x27а-яa-z]{1,})?$/

Реализация от пользователя Kosuha606
/^[А-ЯA-Z][а-яa-zА-ЯA-Z\-]{0,}\s[А-ЯA-Z][а-яa-zА-ЯA-Z\-]{1,}(\s[А-ЯA-Z][а-яa-zА-ЯA-Z\-]{1,})?$/

function test (value){
    var regExp = /^([А-ЯA-Z]|[А-ЯA-Z][\x27а-яa-z]{1,}|[А-ЯA-Z][\x27а-яa-z]{1,}\-([А-ЯA-Z][\x27а-яa-z]{1,}|(оглы)|(кызы)))\040[А-ЯA-Z][\x27а-яa-z]{1,}(\040[А-ЯA-Z][\x27а-яa-z]{1,})?$/
    return regExp.test(value)
}

Пример использования:

test("Иванов Иван Иванович"); //true
test("Ли Лу Янг"); //true
test("Dwain Simmons"); //true
test("Dwain-Branden Simmons"); //true
test("И Иван Иванович"); //true
test("Салим-оглы Мамед"); //true
test("Салим-кызы Лейла"); //true

Артем Леготин
  • Репутация: 18
  • Сниппеты: 5
  • Ревизии: 0

Склоняет слово в соответствии с числом

var wordCase = function( num, words ) {
	var word = '';
	
	num = Math.abs( num );
    
    if ( num.toString().indexOf( '.' ) > -1 ) {
        word = words[ 2 ];
    } else { 
        word = (
            num % 10 === 1 && num % 100 !== 11 
                ? words[ 1 ]
                : num % 10 >= 2 && num % 10 <= 4 && ( num % 100 < 10 || num % 100 >= 20)  
                    ? words[ 2 ]
                    : words[ 0 ]
        );
    }
    
    return word;
};

/* использование: */

var words = [ 'яблок', 'яблоко', 'яблока' ];// [ 'ноль яблок', 'одно яблоко', 'два яблока' ]

wordCase( 0, words );// яблок
wordCase( 1, words );// яблоко
wordCase( 2, words );// яблока
wordCase( 5, words );// яблок
wordCase( 10, words );// яблок
Артем Леготин
  • Репутация: 18
  • Сниппеты: 5
  • Ревизии: 0

Перемешивает входящий массив

var shuffle = function( array ) {
	return array.sort( function() {
		return Math.random() - 0.5;
	} );
};
Gravatar image
qRoC
  • Репутация: 7
  • Сниппеты: 2
  • Ревизии: 0

Можно сделать интересное меню или другие штуки.

Примеры: https://jsfiddle.net/qRoC/0dkv6dq7/2/ https://jsfiddle.net/qRoC/szmfmezz/3/

(function($)
{
    'use strict';

    // ========================================================================
    function factorial(n) { return (n <= 1) ? 1 : n * factorial(n - 1); }

    function Vec2(x, y)
    {
        this.x = x;
        this.y = y;
    }

    function fillArray(array, val, repeat)
    {
        for (var i = 0; i < repeat; i++)
            array.push(val);
    }

    // ========================================================================
    /**
     * @param Array[] pivot_points Массив опорных точек. В формате [x, y].
     * @param double step Шаг при расчёте кривой. От 0 до 1.
     */
    function Bezier(pivot_points, step)
    {
        this.points = [];
        this.pivot_points = pivot_points;

        for (var t = 0; t < 1 + step; t += step)
        {
            if (t > 1) t = 1;

            var point = new Vec2(0, 0);

            for (var i = 0; i < this.pivot_points.length; i++)
            {
                var b = this.getBasis(i, this.pivot_points.length - 1, t);

                point.x += this.pivot_points[i][0] * b;
                point.y += this.pivot_points[i][1] * b;
            }

            this.points.push(point);
        }
    }

    /**
     * Возвращает i-й элемент полинома Берштейна.
     *
     * @param i Номер вершины.
     * @param n Количество вершин.
     * @param t Положение кривой. От 0 до 1.
     */
    Bezier.prototype.getBasis = function(i, n, t)
    {
        return (factorial(n) / (factorial(i) * factorial(n - i))) * Math.pow(t, i) * Math.pow(1 - t, n - i);
    }

    Bezier.prototype.getPoints = function()
    {
        return this.points;
    }

    Bezier.prototype.debugRender = function($obj)
    {
        var $point = $( "<div />" );

        $point.css({
            position: 'absolute',
            top: 0,
            left: 0,
            width: '1px',
            height: '1px',
            backgroundColor: '#000'
        });

        for (var i = 0; i < this.points.length; i++)
        {
            var $point_tmp = $point.clone(false);

            $point_tmp.css({
                left: this.points[i].x,
                top:  this.points[i].y
            });

            $obj.append($point_tmp);
        }

        for (var i = 0; i < this.pivot_points.length; i++)
        {
            var $point_tmp = $point.clone(false);

            $point_tmp.css({
                left: this.pivot_points[i][0],
                top:  this.pivot_points[i][1],
                width: '4px',
                height: '4px',
                backgroundColor: '#ff0000'
            });

            $obj.append($point_tmp);
        }
    }

    // ========================================================================
    function BezierNav($obj, options)
    {
        var settings = $.extend({
            '$parent': $obj,

            'bezier_points': [],                            // Опорные точки. В формате [x, y].
            'bezier_step': 0.01,                            // Шаг для расчёта кривой. От 0 до 1.
            'bezier_render': false,                         // Рендерить ли базье. Только для отладки.

            'menu': [],                                     // Элементы меню. Массив из идентификаторов.
            'menu_item_correction': function($el, key){},   // Колбек для корректировки отображения элементов меню.
            'menu_padding': 5,                              // Отступ между элементами меню. Зависит от bezier_step.
            'menu_active_padding': 15,                      // Отступ от активного элемента меню. Зависит от bezier_step.
            'menu_default_active': undefined                // Активный пункт меню по умолчанию.
        }, options);

        //
        var bezier = new Bezier(settings.bezier_points, settings.bezier_step);

        if (settings.bezier_render)
            bezier.debugRender(settings.$parent);

        this.road_points = bezier.getPoints();
        this.menu_items  = prepareMenuItems(settings.menu, settings.menu_item_correction);
        this.active      = undefined;
        this.tasks       = [];

        this.menu_padding        = settings.menu_padding;
        this.menu_active_padding = settings.menu_active_padding;

        if (typeof settings.menu_default_active !== 'undefined')
            this.setActiveById(settings.menu_default_active);
        else
            this.setActive(0);

        for (var i = 0; i < this.menu_items.length; i++)
            settings.$parent.append(this.menu_items[i].$el);
    };

    function prepareMenuItems(items, cb)
    {
        var $blueprint = $( "<div class='menu_item'/>" );

        $blueprint.css({
            position: 'absolute',
            top:  0,
            left: 0
        });

        var menu_items = [];

        for (var i = 0; i < items.length; i++)
        {
            var $el = $blueprint.clone(false),
                id  = items[i];

            cb($el, id);

            menu_items.push({
                id: id,
                $el: $el,
                point_n: -1
            });
        }

        return menu_items;
    }

    BezierNav.prototype.menuSearchPosById = function(id)
    {
        for (var pos = 0; pos < this.menu_items.length; pos++)
            if (this.menu_items[pos].id == id)
                return pos;

        throw new Error("Bad element id");
    }

    function setPossition(item, points, point_n)
    {
        if (point_n < 0 || point_n >= points.lenght)
            return;

        item.point_n = point_n;

        var point = points[item.point_n];

        item.$el.css({
            left: point.x - item.$el.width() / 2,
            top:  point.y - item.$el.height() / 2
        });
    }

    function moveByPointRoad(item, points, queue, toleft, _tasks)
    {
        _tasks.push(undefined);

        var start_point_n = item.point_n;
        var shift = toleft ? -1 : 1;

        requestAnimationFrame(function animate()
        {
            setPossition(item, points, item.point_n + shift);

            if (toleft && start_point_n - item.point_n === queue[0])
            {
                start_point_n = item.point_n;
                queue.shift();
            }
            else if (!toleft && start_point_n + queue[0] === item.point_n)
            {
                start_point_n = item.point_n;
                queue.shift();
            }

            if (queue.length)
                requestAnimationFrame(animate);
            else
                _tasks.pop();
        });
    }

    BezierNav.prototype.$innerSampleMove = function(pos)
    {
        var central_point = Math.floor(this.road_points.length / 2);
        var left_point    = central_point - this.menu_active_padding;
        var right_point   = central_point + this.menu_active_padding;

        // center
        setPossition(this.menu_items[pos], this.road_points, central_point);

        // left
        for (var i = pos - 1; i >= 0; i--)
        {
            setPossition(this.menu_items[i], this.road_points, left_point);
            left_point -= this.menu_padding;
        }

        // right
        for (var i = pos + 1; i < this.menu_items.length; i++)
        {
            setPossition(this.menu_items[i], this.road_points, right_point);
            right_point += this.menu_padding;
        }
    }

    BezierNav.prototype.$innerAnimationMove = function(pos)
    {
        var diff   = pos - this.active,
            toleft = false,
            menu   = this.menu_items,
            active = this.active;

        if (diff > 0)
            toleft = true;
        else
        {
            diff = Math.abs(diff);

            menu   = this.menu_items.slice().reverse();
            active = this.menu_items.length - active - 1;
        }

        for (var i = 0; i < menu.length; i++)
        {
            var item  = menu[i];
            var queue = [];

            if (i < active) // Уже в стороне направления
            {
                fillArray(queue, this.menu_padding, diff);
            }
            else if(i == active) // Смещение активного элемента.
            {
                fillArray(queue, this.menu_active_padding, 1); // Уходим в сторону
                fillArray(queue, this.menu_padding, diff - 1); // Стандартное смещение в сторону направления
            }
            else if (i - diff == active) // Справа, переходит в центральное положение
            {
                fillArray(queue, this.menu_padding, diff - 1); // Подходим к центру
                fillArray(queue, this.menu_active_padding, 1); // Ставим в центр
            }
            else if (i - diff < active) // Проходит через центр в сторону направления
            {
                fillArray(queue, this.menu_padding, i - active - 1); // Подходим к центру
                fillArray(queue, this.menu_active_padding, 2);       // Проходим центр
                fillArray(queue, this.menu_padding, diff - (i - active) - 1); // Стандартное смещение в сторону направления
            }
            else // В стороне
            {
                fillArray(queue, this.menu_padding, diff);
            }

            moveByPointRoad(item, this.road_points, queue, toleft, this.tasks);
        }
    }

    BezierNav.prototype.setActiveById = function(id)
    {
        this.setActive(this.menuSearchPosById(id));
    }

    BezierNav.prototype.setActive = (function()
    {
        var __first_render = true;

        return function(pos)
        {
            if (this.tasks.length)
                return;

            if (typeof this.active !== 'undefined')
            {
                if (this.active == pos)
                    return;

                this.menu_items[this.active].$el.removeClass("active");
            }

            if (__first_render)
            {
                this.$innerSampleMove(pos);

                __first_render = false;
            }
            else
            {
                this.$innerAnimationMove(pos);
            }

            this.active = pos;

            this.menu_items[this.active].$el.addClass("active");
        }
    })();

    BezierNav.prototype.next = function()
    {
        if (this.active == this.menu_items.length - 1)
            var pos = 0;
        else
            var pos = this.active + 1;

        this.setActive(pos);
    }

    BezierNav.prototype.prev = function()
    {
        if (this.active == 0)
            var pos = this.menu_items.length - 1;
        else
            var pos = this.active - 1;

        this.setActive(pos);
    }

    // ========================================================================
    var bezier_nav = {};

    $.fn.bezierNav = function(data)
    {
        var $obj = this;
        var id   = $obj.attr('id');

        if (!id)
        {
            id = 'bezier_nav_' + Date.now();

            $obj.attr('id', id);
        }

        if (!bezier_nav.hasOwnProperty(id))
            bezier_nav[id] = new BezierNav($obj, data);
        else if (data in bezier_nav[id] && data[0] != '$')
            return bezier_nav[id][data].apply(bezier_nav[id], Array.prototype.slice.call(arguments, 1));
        else
            $.error('Bad method name: ' + data);
    };

})(jQuery);
Gravatar image
Михаил Журавлев
  • Репутация: 5
  • Сниппеты: 3
  • Ревизии: 2

Это Underscore.debounce. http://underscorejs.org/ Возвращает функцию, которая, сколько бы не была вызвана, выполняется только через таймаут после последнего вызова.

// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
_.debounce = function(func, wait, immediate) {
	var timeout;
	return function() {
		var context = this, args = arguments;
		var later = function() {
			timeout = null;
			if (!immediate) func.apply(context, args);
		};
		var callNow = immediate && !timeout;
		clearTimeout(timeout);
		timeout = setTimeout(later, wait);
		if (callNow) func.apply(context, args);
	};
};
Gravatar image
Nepster
  • Репутация: 151
  • Сниппеты: 19
  • Ревизии: 0

Иногда бывает необходимо запустить событие только 1 раз после всех действий. Один из распространенных примеров это resize.

var waitForFinalEvent = (function () {
  var timers = {};
  return function (callback, ms, uniqueId) {
    if (!uniqueId) {
      uniqueId = "Don't call this twice without a uniqueId";
    }
    if (timers[uniqueId]) {
      clearTimeout (timers[uniqueId]);
    }
    timers[uniqueId] = setTimeout(callback, ms);
  };
})();


$(window).resize(function () {
    waitForFinalEvent(function(){
      alert('Resize...');
      //...
    }, 500, "some unique string");
});
Gravatar image
Nepster
  • Репутация: 151
  • Сниппеты: 19
  • Ревизии: 0

Ограничение на ввод символов в текстовом поле.

    $("input[type='number']").on('keyup keypress blur change', function(e) {
        //return false if not 0-9
        if (e.which != 8 && e.which != 0 && (e.which < 48 || e.which > 57)) {
            return false;
        }else{
            //limit length but allow backspace so that you can still delete the numbers.
            if( $(this).val().length >= parseInt($(this).attr('maxlength')) && (e.which != 8 && e.which != 0)){
                return false;
            }
        }
    });
Gravatar image
Nepster
  • Репутация: 151
  • Сниппеты: 19
  • Ревизии: 0

Запрещает ввод всех символов кроме чисел в текстовое поле.

    $("input[type='number']").keydown(function (e) {
        // Allow: backspace, delete, tab, escape, enter and .
        if ($.inArray(e.keyCode, [46, 8, 9, 27, 13, 110, 190]) !== -1 ||
                // Allow: Ctrl+A
            (e.keyCode == 65 && e.ctrlKey === true) ||
                // Allow: Ctrl+C
            (e.keyCode == 67 && e.ctrlKey === true) ||
                // Allow: Ctrl+X
            (e.keyCode == 88 && e.ctrlKey === true) ||
                // Allow: home, end, left, right
            (e.keyCode >= 35 && e.keyCode <= 39)) {
            // let it happen, don't do anything
            return;
        }
        // Ensure that it is a number and stop the keypress
        if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
            e.preventDefault();
        }
    });