ES6:
const randomColor = () => {
return `#${((1<<24)*Math.random()|0).toString(16)}`;
}
console.log(randomColor());
ES5:
var randomColor = function() {
return '#' + ((1<<24)*Math.random()|0).toString(16);
}
console.log(randomColor());
const randomColor = () => {
return `#${((1<<24)*Math.random()|0).toString(16)}`;
}
console.log(randomColor());
function isInt(n){
return Number(n) === n && n % 1 === 0;
}
function isFloat(n){
return Number(n) === n && n % 1 !== 0;
}
Простая функция, которая переберет в цикле нужные вам для проверки свойства CSS и проверит поддерживает ли их браузер.
function checkCssSupport(containerSelector) {
var supportValues = [
{
feature: "display",
value : "flex",
}
], supportIndex, curFeature,
curValue, notSupportedClass;
for (supportIndex in supportValues) {
curFeature = supportValues[supportIndex].feature;
curValue = supportValues[supportIndex].value;
notSupportedClass = 'no-' + curValue + '-support';
$(containerSelector).addClass(notSupportedClass);
if (typeof(CSS) !== 'undefined') {
if (CSS.supports(curFeature, curValue)) {
$(containerSelector).removeClass(notSupportedClass);
}
}
}
}
/**
* @param {Number} from
* @param {Number} to
* @param {Number} speed
* @param {Function} update
*/
const animateNumber = function(from, to, speed, update) {
const piece = (to - from) / (3.6 * speed);
const step = () => {
num += piece;
update(num);
(num <= to) && requestAnimationFrame(step);
};
let num = from;
requestAnimationFrame(step);
};
Часто бывает необходимо удалить классы, начинающиеся с определенной строки.
Например: has-state-active
, has-state-pending
, has-state-disabled
.
Простейший и очевидный способ - это использовать символы подставноки: has-state-*
.
Этим скриптом можно получить изображение из буфера обмена при нажатии ctrl+v на js. Работает только в хроме и мозиле. Может кто обращал внимание, в вк, в переписке есть возможность прикрепления картинки в диалог прямо из буфера, с этим скриптом вы можете реализовать то же самое.
// проверяем, поддерживает ли браузер объект Clipboard
// если нет создаем элемент с атрибутом contenteditable
if (!window.Clipboard) {
var pasteCatcher = document.createElement("div");
// Firefox вставляет все изображения в элементы с contenteditable
pasteCatcher.setAttribute("contenteditable", "");
pasteCatcher.style.position = "absolute";
pasteCatcher.style.left = "-3000px";
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 && e.clipboardData.items) {
// получаем все содержимое буфера
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;
}
Этим скриптом можно получить изображение из буфера обмена при нажатии 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;
}
Асинхронная очередь
function Queue() {
var self = this;
self.queue = [];
self.push = function (fn, context, params) {
params = params || [];
context = context || this;
self.queue.push({fn: fn, params: params, context: context});
return self;
};
self.pushFront = function (fn, context, params) {
params = params || [];
context = context || this;
self.queue.unshift({fn: fn, params: params, context: context});
return self;
};
function callback() {
if (self.queue.length > 0) {
var item = self.queue.pop();
var args = item.params;
args.push(callback);
item.fn.apply(item.context, args);
}else{
self.final();
}
}
self.start = function (cb) {
self.final = cb;
callback();
}
}
/** Example **/
var q = new Queue();
q.push(function (cb) {
console.log(1);
setTimeout(function () {
cb();
}, 2000);
}, this);
q.pushFront(function (cb) {
console.log(2);
setTimeout(function () {
cb();
}, 1000);
}, this);
q.pushFront(function (cb) {
console.log(3);
setTimeout(function () {
cb();
}, 3000);
}, this);
q.start(function () {
console.log('done');
});
var testObj2 = {
m2: 'm2Value'
}
var testObj = {
method1: function() { return testObj },
method2: function() { return testObj },
obj2: testObj2
}
//оригинальное значение
var testVal = may(testObj)
.pipe(function(item) { return 1 }) // переписали оригинальное значение
.pipe(function(item) { return item + 12 }) // добавили к 1 еще 12 итого 13
.pipe(function(item) { return item + 12 }) // по той же схеме, получаем 25
.value
console.log('test testObj.pipe() is 25 :=> ', testVal);
// допустим у нас есть функция которая при вызове вернет еще функцию и так 5 раз
var callbackHell = function() {
var l4 = function() { return 'done' };
var l3 = function() { return l4; };
var l2 = function() { return l3; };
var l1 = function() { return l2; };
return l1;
}
//передаем саму функцию не вызывая
var cbHellTest = may(callbackHell)
.run(function(item) { return item }) // вызов callbackHell()
.run(function(item) { return item }) // вызов l1()
.run(function(item) { return item }) // вызов l2()
.run(function(item) { return item }) // вызов l3()
.run(function(item) { return item }) // вызов l4() которая вернет нам "done"
.value;
console.log('test cbHellTest.run() is "done" :=> ', cbHellTest);
//так же вызовы можно комбинировать
var testCall = may(testObj)
.run(function(item) { return item.method1 }) // метод вернет testObj
.run(function(item) { return item.method2 }) // метод так же вернет testObj
.run(function(item) { return item.method3 }) // а такого метода нет, значит мы пропустим вызов
.pipe(function(item) { return item.obj2 }) // тут item это результат вызова item.method2()
.pipe(function(item) { return item.m2 }) // тут item равен результату из предыдущей цепочки
.value
//проверочные функции для наглядности
console.log('test testObj.run() is ', testObj2.m2, ' :=> ', testCall);
//если значение null или undefined то вернется значение переданное в or
console.log('test null.or(12) :=> ', may(null).or(12).value);
console.log('test 24.or(12) :=> ', may(24).or(12).value);
console.log('test 128.value :=> ', may(128).value);
// применить функцию переданную в map к значению
console.log('test 128.map(x => x * 2) :=> ', may(128).map(function(val) { return val*2 }).value);
// выполняет проверку значения на пустоту и кладет результат в value
console.log('test "undefined".empty() :=> ', may(void 0).empty().value);
// с этим результатом так же можно работать через pipe, or, map,
console.log('test "undefined".empty().pipe() is "undefined" :=> ', may(void 0).empty().pipe(function(val) { return val }).value);
function may(val) {
var value = val, tempValue = value,
empty = function (expr) { return typeof expr === 'undefined' || expr === null; },
or = function (oVal, nVal) { return empty(oVal) ? may(nVal) : self; },
self = {
value: tempValue,
or: or.bind(self, tempValue),
empty: function() { return empty(tempValue) ? may(true) : self; },
pipe: function (cb) { var cbVal = cb(tempValue), orMay = empty(cbVal) ? self : may(cbVal); tempValue = orMay.value; return orMay; },
run: function(f) { var mapMay = self.map(f(tempValue)); tempValue = mapMay.value; return mapMay; },
map: function (f) { return typeof(f) === "function" ? may(f(tempValue)) : self; }
};
return self;
}