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

Раздел:
Подраздел:
Языки:


Stephen Berezuev
  • Репутация: 5
  • Сниппеты: 3
  • Ревизии: 1

В MongoDB отвратительный полнотекстовый поиск. Для индексации и поиска можно использовать Sphinxsearch. В интернете есть несколько вариантов, как это сделать (при помощи PHP, mongoexport --type=csv, etc).

Но, как показала практика, когда колличество документов в коллекции измеряется миллионами и они собираются из разных источников, перечисленные методы либо вообще не работают (сфинкс ломается о различные спец.символы), либо просто виснут. Самым быстрым и надежным способом в итоге оказалось генерировать индекс силами самого сфинкса.

Ниже пример. Сразу предупрежу, что я специально отказался от использования XML DOM в пользу скорости.

//echo header
print("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
    + "<sphinx:docset>\n"
    + "    <sphinx:schema>\n"
    + "      <sphinx:field name=\"content\"/>\n"
    + "    </sphinx:schema>\n");
    
//echo posts
db.posts.find().forEach( function(post) {
	print('<sphinx:document id="' + post._id.valueOf() + "\">\n"
    + '    <content>' + doc.content.toString().replace(/[><]/g,'') + "</first_name>\n" //обязательно убирайте символы < и >
    + "</sphinx:document>\n");
}

print("</sphinx:docset>");

Если в _id у вас не только цифры (а по умолчанию, если вы ничего не присваиваете в _id, это так и будет), то стоит добавить счетчик i++ вместо post._id.valueOf()

Ну и, исходник в сфинксе:

source sourcename
{
    type = xmlpipe2
    xmlpipe_command = mongo databasename --quiet /path/to/jsfile.js
    xmlpipe_field_string = content
}
Gravatar image
avkvak
  • Репутация: 1
  • Сниппеты: 0
  • Ревизии: 1

Благодарю автора zular за данный скрипт. Хотел написать коммент, но нажал чтото не то :) В общем, чтобы класс таки удалялся, на 6 строке лучше сравнивать в виде ">" а не ">=" ибо в нашем случае $(window).scrollTop() всегда >= 0

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

Зависимости:

  • Jquery

Классы:

  • .nav-afix - само меню
  • .affix - класс который добавляется в после скролла

Преимущества скрипта:

  • не надо высчитывать отступ сверху (скрипт сам его отсчитывает)
// --- affix top menu script ---
$(() => {
    let target = $('.nav-afix');
    let startPosition = target.offset().top;

    $(window).scroll(() => {
        if ($(window).scrollTop() > startPosition) {
            if (!target.hasClass()) {
                target.addClass('affix')
            };
        } else {
            target.removeClass('affix')
        };
    });
});

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

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

Зависимости:

  • Jquery

Классы:

  • .nav-afix - само меню
  • .affix - класс который добавляется в после скролла

Преимущества скрипта:

  • не надо высчитывать отступ сверху (скрипт сам его отсчитывает)
// --- affix top menu script ---
$(() => {
    let target = $('.nav-afix');
    let startPosition = target.offset().top;

    $(window).scroll(() => {
        if ($(window).scrollTop() >= startPosition) {
            if (!target.hasClass()) {
                target.addClass('affix')
            };
        } else {
            target.removeClass('affix')
        };
    });
});

Gravatar image
maxyc
  • Репутация: 29
  • Сниппеты: 4
  • Ревизии: 0

По правде coffescript я тоже не использую. Но не об этом ))) Статья для новичков и для тех, кто стремится изучить эту тему. Для бывалых скорее всего покажется простыми брызгами слюней от "открытия америки".

Есть такая замечательная штука Gulp. Легко гуглится. В кратце это серверный комбайн расширяемый плагинами. Код который привел ниже запускается в командной строке одной лишь командой # gulp При этом он делает следующее

Продолжение »

jestonedev
  • Репутация: 99
  • Сниппеты: 11
  • Ревизии: 1

Вот такие вот задачки иногда попадаются на собеседовании на должность Frontend Web Developer: Написать парсер математических выражений методом рекурсивного спуска. Должны поддерживаться операции сложения, вычитания, умножения, деления, возведения в степень, а также скобки. Хоть задача и тривиальная, но мне стало интересно ваше мнение, как подобная задача коррелирует с должностью? Видимо оценить уровень владения языком?

P.S.: Известные проблемы данной реализации:

  1. Неочевидность сообщения об ошибке: пользователю может быть не всегда понятно, почему в одних случаях выводится Token unexpected, а в других Invalid formula
  2. Проблема двух знаков минус в начале выражения: "(--2)" - вернет NaN, а не "Invalid formula" Писалось на коленке, поэтому прошу понять и простить.

var TokenType = {
    Empty: { name: "Empty" },
    Number: { name: "Number", expectAfter: [ "Empty", "Operator" ] },
    Operator: { name: "Operator", expectAfter: [ "Number", "Expression" ] },
    Expression: { name: "Expression", expectAfter: [ "Empty", "Operator" ] }
};

var Operator = [
    { operator: "^", priority: 3, eval: function(a,b) { return Math.pow(a,b); } },
    { operator: "*", priority: 2, eval: function(a,b) { return a*b; } },
    { operator: "/", priority: 2, eval: function(a,b) { return a/b; } },
    { operator: "+", priority: 1, eval: function(a,b) { return a+b; } },
    { operator: "-", priority: 1, eval: function(a,b) { return a-b; } }
];

function Evaluator()
{
}

Evaluator.prototype = {
    eval: function(str) {
        var tokens = [];
        while(str !== "") {
            var token = this.extractNumber(str, tokens.length === 0);
            if (token === null) {
                token = this.extractOperator(str);
            }
            if (token === null) {
                token = this.extractExpression(str);
            }
            if (token === null) {
                throw Error('Token unexpected '+str);
            }
            this.assert(tokens[tokens.length - 1], token);
            tokens.push(token);
            str = str.substr(token.rawValue.length);
        }
        if (tokens.length === 0) return null;
        if (tokens[tokens.length - 1].type === TokenType.Operator) {
            throw new Error('Invalid formula');
        }
        return this.processTokens(tokens);
    },

    processTokens: function(tokens) {
        var processTokens = [];
        while (tokens.length > 1) {
            var maxPriority = tokens.filter(function(t) {
                return t.type === TokenType.Operator;
            }).map(function(t) {
                return t.operator.priority;
            }).reduce(function (acc, v) {
                return v > acc ? v : acc;
            }, Number.MIN_VALUE);
            for (var i = 0; i < tokens.length; i++) {
                if (tokens[i].type === TokenType.Operator && tokens[i].operator.priority === maxPriority) {
                    var leftOperand = processTokens.pop();
                    var operator = tokens[i].operator;
                    var rightOperand = tokens[i + 1];
                    var evalValue = operator.eval(Number(leftOperand.value), Number(rightOperand.value));
                    processTokens.push({"value": evalValue, "rawValue": evalValue, "type": TokenType.Number});
                    i++;
                } else {
                    processTokens.push(tokens[i])
                }
            }
            tokens = processTokens;
            processTokens = [];
        }
        if (tokens.length === 0) {
            throw new Error('Unexpected error');
        }
        return tokens[0].value;
    },

    assert: function(prevToken, currentToken)
    {
        if (prevToken == undefined && currentToken.type.expectAfter.indexOf("Empty") !== -1)
            return;
        if (prevToken !== undefined && currentToken.type.expectAfter.indexOf(prevToken.type.name) !== -1)
            return;
        throw Error("Invalid formula");
    },

    clear: function(str)
    {
        return str.replace(/\s+/g,"");
    },

    extractNumber: function(str, allowMinus)
    {
        var regExp = new RegExp("^"+(allowMinus ? "[\-]?" : "")+"[0-9]*(?:[.][0-9]+)?","g");
        var match = regExp.exec(str);
        if (match === null || match.length === 0 || match[0].length === 0) return null;
        return { "value": match[0], "rawValue": match[0], "type": TokenType.Number };
    },

    extractOperator: function(str)
    {
        for(var i = 0; i < Operator.length; i++)
        {
            var regExp = new RegExp("^"+ RegExp.escape(Operator[i].operator)+"","g");
            var match = regExp.exec(str);
            if (match !== null && match.length > 0)
                return { "value": match[0], "rawValue": match[0], "operator": Operator[i], "type": TokenType.Operator }
        }
        return null;
    },

    extractExpression: function(str)
    {
        var regExp = /^(\(.*\))/g;
        var match = regExp.exec(str);
        if (match === null || match.length < 2) return null;

        var brackets = ['('];
        var value = match[0];
        for (var i = 1; i < value.length; i++)
        {
            if (value[i] === '(') {
                brackets.push('(');
            }
            if (value[i] === ')') {
                brackets.pop();
            }
            if (brackets.length === 0) {
                break;
            }
        }
        value = value.substr(1, i-1);
        if (value === "") {
            throw new Error("Invalid formula");
        }
        var e = new Evaluator();
        return { "value": e.eval(value), "rawValue": "("+value+")", "type": TokenType.Expression };
    }
};

if (RegExp.escape === undefined) {
	RegExp.escape= function(s) {
		return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
	};
}
Gravatar image
Александр Лис
  • Репутация: 1
  • Сниппеты: 0
  • Ревизии: 1

Нужно загрузить файл на сервер, без перезагрузки страницы? Видел много костылей на эту тему, вот вам простой вариант, который использую сам)

var form = new FormData(document.getElementById('идентификатор формы'));
$.ajax({
    url: "/upload.php",
    type: "POST",
    data: form,
    enctype: 'multipart/form-data',
    processData: false,
    contentType: false,
    success: function (data) {
        // здесь обработка ответа от сервер
    }
});
Gravatar image
maxyc
  • Репутация: 29
  • Сниппеты: 4
  • Ревизии: 0

1) Сложность пароля Качество и сложность пароля - мнение часто субъективно. Но данный сниппет хорошее начало )

^(?=.*[A-Z].*[A-Z])(?=.*[!@#$&*])(?=.*[0-9].*[0-9])(?=.*[a-z].*[a-z].*[a-z]).{8}$

2) Проверка на HEX цвет.

\#([a-fA-F]|[0-9]){3, 6}

3) Проверка email. Данный пункт хорошее начало холивара!

/[A-Z0-9._%+-]+@[A-Z0-9-]+.+.[A-Z]{2,4}/igm

Продолжение »

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

Иногда, что бы сделать сайт максимально быстрым для пользователя (или хотя бы сделать такое впечатление), можно прибегать к таким средствам как в этом сниппете. Суть этих строк в том, что страница на которую ведёт ссылка -- начинает загружаться еще до того как пользователь на нее нажмёт (в тот период как только клавиша миши начала опускаться, а курсор указывает на ссылку), это ускорит загрузку страниц на 50ms.

document.onmousedown = function(e) {
	e.target.click();
}
Gravatar image
finom
  • Репутация: 5
  • Сниппеты: 1
  • Ревизии: 0

Методы, которые были в балалайке, устарели. Теперь bala.js рулит.

Репозиторий Пост на Хабре

$=function(d,e,c,f,g){c=function(a,b){return new f(a,b)};f=function(a,b){e.push.apply(this,a?a.nodeType||a==window?[a]:""+a===a?/</.test(a)?((g=d.createElement(b||"q")).innerHTML=a,g.children):(b&&c(b)[0]||d).querySelectorAll(a):/f/.test(typeof a)?/c/.test(d.readyState)?a():d.addEventListener("DOMContentLoaded",a):a:e)};c.fn=f.prototype=e;c.one=function(a,b){return c(a,b)[0]||null};return c}(document,[]);