Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Компактная запись функции (https://javascript.ru/forum/misc/70012-kompaktnaya-zapis-funkcii.html)

AlexTrader 03.08.2017 15:04

Компактная запись функции
 
Есть функция, а точнее портянка:
app.ratingTooltipTpl = function (e) {
        var res = "<div id='set-rating" + e.chainId + "'>";
        var rate = e.rating;
        switch (rate) {
            case 0:
                for (var i = 1; i <= 5; ++i) {
                    res += "<span rate=" + i + " chainId=" + e.chainId + " class='action-tooltip rating-empty' onclick='setRating(this)'></span>";
                }
                break;
            case 1:
                res += "<span rate=1 chainId=" + e.chainId + " class='action-tooltip rating-yellow-star' onclick='setRating(this)'></span>";
                for (var i = 2; i <= 5; ++i) {
                    res += "<span rate=" + i + " chainId=" + e.chainId + " class='action-tooltip rating-empty' onclick='setRating(this)'></span>";
                }
                break;
            case 2:
                res += "<span rate=1 chainId=" + e.chainId + " class='action-tooltip rating-yellow-star' onclick='setRating(this)'></span>";
                res += "<span rate=2 chainId=" + e.chainId + " class='action-tooltip rating-yellow-star' onclick='setRating(this)'></span>";
                for (var i = 3; i <= 5; ++i) {
                    res += "<span rate=" + i + " chainId=" + e.chainId + " class='action-tooltip rating-empty' onclick='setRating(this)'></span>";
                }
                break;
            case 3:
                res += "<span rate=1 chainId=" + e.chainId + " class='action-tooltip rating-yellow-star' onclick='setRating(this)'></span>";
                res += "<span rate=2 chainId=" + e.chainId + " class='action-tooltip rating-yellow-star' onclick='setRating(this)'></span>";
                res += "<span rate=3 chainId=" + e.chainId + " class='action-tooltip rating-yellow-star' onclick='setRating(this)'></span>";
                for (var i = 4; i <= 5; ++i) {
                    res += "<span rate=" + i + " chainId=" + e.chainId + " class='action-tooltip rating-empty' onclick='setRating(this)'></span>";
                }
                break;
            case 4:
                res += "<span rate=1 chainId=" + e.chainId + " class='action-tooltip rating-yellow-star' onclick='setRating(this)'></span>";
                res += "<span rate=2 chainId=" + e.chainId + " class='action-tooltip rating-yellow-star' onclick='setRating(this)'></span>";
                res += "<span rate=3 chainId=" + e.chainId + " class='action-tooltip rating-yellow-star' onclick='setRating(this)'></span>";
                res += "<span rate=4 chainId=" + e.chainId + " class='action-tooltip rating-yellow-star' onclick='setRating(this)'></span>";
                res += "<span rate=5 chainId=" + e.chainId + " class='action-tooltip rating-empty' onclick='setRating(this)'></span>";
                break;
            case 5:
                for (var i = 1; i <= 5; ++i) {
                    res += "<span rate=" + i + " chainId=" + e.chainId + " class='action-tooltip rating-yellow-star' onclick='setRating(this)'></span>";
                }
                break;
        }
       
        res = res + "</div></br>Баллы:<span id='rating-rate" + e.chainId + "'>"+rate+"</span>";
        return res;
    };

Возможно ли её упростить, укоротить, записать более компактно, использую jqerry?

AlexTrader 03.08.2017 15:07

В каждом кейсе создаётся по 5 спанов, отличающихся только аттрибутом rate (от 1 до 5) и class(либо action-tooltip rating-yellow-star, либо action-tooltip rating-empty)

Nexus 03.08.2017 15:09

AlexTrader, Вы не так давно задавали похожий вопрос.
Почему нельзя проанализировать код, понять что у Вас постоянно повторяется, а какие данные статичны и на основе полученных результатов написать алгоритм, который будет выглядеть в 10 раз компактнее и выполнять эту же работу, но в единственном цикле?

В jQuery нет методов, способных выполнить эту же работу.

AlexTrader 03.08.2017 15:15

Nexus,
Сложность в том, что элементы не полностью повторяются, два аттрибута разные...

Nexus 03.08.2017 15:23

Цитата:

Сообщение от AlexTrader (Сообщение 460539)
Nexus,
Сложность в том, что элементы не полностью повторяются, два аттрибута разные...

Тут почти тоже самое:
https://javascript.ru/forum/misc/699...tml#post460507
Разное значение принимает 1 атрибут и свойство.

ksa 03.08.2017 15:33

Цитата:

Сообщение от AlexTrader
Возможно ли её упростить, укоротить, записать более компактно, использую jqerry?

Да. :yes:

Как вариант, сделай массив объектов, где у свойств будут нужные значения. Т.о. останется просто собрать нужную строку с использованием нужного элемента массива...

ksa 03.08.2017 15:34

Цитата:

Сообщение от AlexTrader
два аттрибута разные

Значит в объекте будут только 2 свойства...

ksa 03.08.2017 15:38

Цитата:

Сообщение от AlexTrader
res += "<span rate=1 chainId=" + e.chainId + " class='action-tooltip rating-yellow-star' onclick='setRating(this)'></span>";
res += "<span rate=2 chainId=" + e.chainId + " class='action-tooltip rating-yellow-star' onclick='setRating(this)'></span>";
res += "<span rate=3 chainId=" + e.chainId + " class='action-tooltip rating-yellow-star' onclick='setRating(this)'></span>";
res += "<span rate=4 chainId=" + e.chainId + " class='action-tooltip rating-yellow-star' onclick='setRating(this)'></span>";

Такие сочетания вообще шедевр!

AlexTrader 03.08.2017 15:51

Сделал так:
app.ratingTooltipTpl = function (e) {
        var res = "<div id='set-rating" + e.chainId + "'>";
        var rate = e.rating;
        var spanArr = [];

        for (var i = 1; i <= 5; ++i) {
            spanArr.push("<span rate=" + i + " chainId=" + e.chainId + " class='action-tooltip rating-empty' onclick='setRating(this)'></span>");
        }

        switch (rate) {
            case 1:
                spanArr[0].replace("empty", "yellow-star");
                break;
            case 2:
                spanArr[0].replace("empty", "yellow-star");
                spanArr[1].replace("empty", "yellow-star");
                break;
            case 3:
                spanArr[0].replace("empty", "yellow-star");
                spanArr[1].replace("empty", "yellow-star");
                spanArr[2].replace("empty", "yellow-star");
                break;
            case 4:
                spanArr[0].replace("empty", "yellow-star");
                spanArr[1].replace("empty", "yellow-star");
                spanArr[2].replace("empty", "yellow-star");
                spanArr[3].replace("empty", "yellow-star");
                break;
            case 5:
                spanArr[0].replace("empty", "yellow-star");
                spanArr[1].replace("empty", "yellow-star");
                spanArr[2].replace("empty", "yellow-star");
                spanArr[3].replace("empty", "yellow-star");
                spanArr[4].replace("empty", "yellow-star");
                break;
        }

        var spans = spanArr.join();
        res += spans;
        res = res + "</div></br>Баллы:<span id='rating-rate" + e.chainId + "'>"+rate+"</span>";
        return res;
    };

Между спанами запятые выводятся...

AlexTrader 03.08.2017 15:52

Поправил
var spans = spanArr.join("");

AlexTrader 03.08.2017 15:53

Я понимаю, нет предела совершенству, но возможно ли ещё усовершенствовать метод?

ksa 03.08.2017 15:57

Цитата:

Сообщение от AlexTrader
Сделал так

Неужели ты не видишь циклы? :blink: Любое повторение с изменением одного параметра - уже цикл!

ksa 03.08.2017 15:57

Цитата:

Сообщение от AlexTrader
но возможно ли ещё усовершенствовать метод?

Разумеется! :D

j0hnik 03.08.2017 16:04

app.ratingTooltipTpl = function (e) {
        var res = "<div id='set-rating" + e.chainId + "'>";
        var rate = e.rating;
        var spanArr = [];

        for (var i = 1; i <= 5; ++i) {
            spanArr.push("<span rate=" + i + " chainId=" + e.chainId + " class='action-tooltip rating-empty' onclick='setRating(this)'></span>");
        }
        	var a = "empty", b = "yellow-star"
        switch (rate) {
            case 1:
                spanArr[0].replace(a, b);
                break;
            case 2:
                spanArr[0].replace(a, b);
                spanArr[1].replace(a, b);
                break;
            case 3:
                spanArr[0].replace(a, b);
                spanArr[1].replace(a, b);
                spanArr[2].replace(a, b);
                break;
            case 4:
                spanArr[0].replace(a, b);
                spanArr[1].replace(a, b);
                spanArr[2].replace(a, b);
                spanArr[3].replace(a, b);
                break;
            case 5:
                spanArr[0].replace(a, b);
                spanArr[1].replace(a, b);
                spanArr[2].replace(a, b);
                spanArr[3].replace(a, b);
                spanArr[4].replace(a, b);
                break;
        }

        var spans = spanArr.join();
        res += spans;
        res = res + "</div></br>Баллы:<span id='rating-rate" + e.chainId + "'>"+rate+"</span>";
        return res;
    };


смотри сколько буков я тебе сократил! :dance:

ksa 03.08.2017 16:06

Цитата:

Сообщение от j0hnik
смотри сколько буков я тебе сократил!

Мои 5коп...

app.ratingTooltipTpl = function (e) {
        var res = "<div id='set-rating" + e.chainId + "'>";
        var rate = e.rating;
        var spanArr = [];
		var val=" chainId=" + e.chainId + " class='action-tooltip rating-empty' onclick='setRating(this)'></span>";
        for (var i = 0; i < 5; ++i) {
            spanArr[i]="<span rate=" + (i+1) + val;
        }
		for (i=0; i<rate; i++) {
			spanArr[i].replace("empty", "yellow-star");
		}
        var spans = spanArr.join("");
        res += spans;
        res = res + "</div></br>Баллы:<span id='rating-rate" + e.chainId + "'>"+rate+"</span>";
        return res;
    };

Не тестил конечно...

AlexTrader 03.08.2017 16:07

смотри сколько буков я тебе сократил!

Круто конечно, но всё равно портянка...

AlexTrader 03.08.2017 16:13

Есть такой вариант:
app.ratingTooltipTpl = function (e) {
        var div = $("<div></div>").attr({ "id": "set-rating" + e.chainId });
        var starSpan = $("<span></span>").attr({
            "rate": 0,
            "chainId": e.chainId,
            "class": "action-tooltip rating-empty",
            "onclick": "setRating(this)"
        });
        var spanArr = [];
        for (var i = 1; i <= 5; ++i) {
            spanArr.push(starSpan.clone().attr("rate", i));
        }
        var spans = spanArr.join("");
        div.append(spans);


        var rateSpan = $("<span></span>").attr({ "id": "rating-rate" + e.chainId });
        div.append("</br>Баллы:");
        div.append(rateSpan);
        return div;
    };

Но вот это не работает:
var spans = spanArr.join("");
        div.append(spans);

И смены классов нет

ksa 03.08.2017 16:52

Или вообще так...

app.ratingTooltipTpl = function (e) {
	var res = "<div id='set-rating" + e.chainId + "'>";
	for (var i = 0; i < 5; ++i) {
		var cls='rating-'+(i<e.rating)? 'yellow-star': 'empty';
		res+="<span rate=" + (i+1) + " chainId=" + e.chainId + " class='action-tooltip "+cls+"' onclick='setRating(this)'></span>";
	};
	res +="</div></br>Баллы:<span id='rating-rate" + e.chainId + "'>"+e.rating+"</span>";
	return res;
};

AlexTrader 03.08.2017 17:05

ksa,
Немного подправил, спасибо, работает!
app.ratingTooltipTpl = function (e) {
        var res = "<div id='set-rating" + e.chainId + "' class='set-rating'>";
        for (var i = 0; i < 5; ++i) {
            var cls = 'rating-' + ((i < e.rating) ? 'yellow-star' : 'empty');
            res += "<span rate=" + (i + 1) + " chainId=" + e.chainId + " class='action-tooltip " + cls + "' onclick='setRating(this)'></span>";
        };
        res += "</div></br>Баллы:<span id='rating-rate" + e.chainId + "'>" + e.rating + "</span>";
        return res;
    };

AlexTrader 03.08.2017 17:15

ksa,
А такой вариант возможно доработать?
app.ratingTooltipTpl = function(e) {
        var div = $("<div></div>").attr({ "id": "set-rating" + e.chainId, "class": "set-rating" });
        var starSpan = $("<span></span>").attr({
            "rate": 0,
            "chainId": e.chainId,
            "class": "rating-empty",
            "onclick": "setRating(this)"
        });

        for (var i = 1; i <= 5; ++i) {
            var span = starSpan.clone();
            span.attr("rate", i);
            span.attr("class", "rating-" + ((i < e.rating) ? "yellow-star" : "empty"));
            div.append(span);
        }

        var rateSpan = $("<span></span>").attr({ "id": "rating-rate" + e.chainId });
        div.append("</br>Баллы:");
        div.append(rateSpan);
        return div;
    }

ksa 04.08.2017 08:19

Цитата:

Сообщение от AlexTrader
span.attr("class", "rating-" + ((i < e.rating) ? "yellow-star" : "empty"));

Для классов есть специальные методы...

span.addClass("rating-" + ((i < e.rating) ? "yellow-star" : "empty"));

Да и само наличие класса rating-empty не нужно... Понять, что это рейтинговый элемент можно и по материнскому классу set-rating.
Тогда код можно так написать

if (i < e.rating)  span.addClass("rating-yellow-star);


Часовой пояс GMT +3, время: 02:18.