Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Bookmarklet для сайта ЦБ РФ (https://javascript.ru/forum/project/71088-bookmarklet-dlya-sajjta-cb-rf.html)

Nexus 25.10.2017 14:57

Bookmarklet для сайта ЦБ РФ
 
Нужно было реализовать букмарклет, который алертил бы стоимости килограмма золота в USD с точностью до сотых.
Я реализовал этот так:
javascript: (function() {
    if (location.href.split('://').pop().replace('/', '') != 'www.cbr.ru') return !1;
    var f = function(c) {
            return {
                ',': '.'
            }[c] || '';
        },
        e = /\D+?/g,
        p = $('#widget_metal .content table tr:eq(1) td:eq(1)').text().replace(e, f) * 1e3,
        r = {
            t: [],
            d: []
        };
    $('#widget_exchange .content table tr:lt(2)').each(function(i) {
        r[i ? 'd' : 't'] = $.makeArray($(this).find('>*:gt(0)').map(function() {
            return $(this).text().replace(e, f);
        }));
    });
    alert(r.t.map(function(s, i) {
        return s.replace(/(\d{2})(\d{2})(\d+)/, '$1.$2.$3: ') + (p / r.d[i]).toFixed(2);
    }).join('\n'));
})();

Можно ли получить более короткое решение?

Alexandroppolus 25.10.2017 15:48

не проверял
javascript: (function() {
    var f = e => $(e).text().replace(/,/g,'.').replace(/[^\d\.]/g,''),
    p = f($('#widget_metal .content table tr:eq(1) td:eq(1)')) * 1e3,
    r = {t: [], d: []};
    $('#widget_exchange .content table tr:lt(2)').each((i,e) => {
        r[i ? 'd' : 't'] = [].map.call($(e).find('>*:gt(0)'),f);
    });
    alert(r.t.map((s, i) => s.replace(/(\d\d)(\d\d)(\d+)/, '$1.$2.$3: ') + (p / r.d[i]).toFixed(2)).join('\n'));
})();


твою строку 2 я выкинул, потому что в bookmarklet это нафиг не надо.

laimas 25.10.2017 16:54

Nexus,
у ЦБ РФ теперь есть SOAP для получения курсов валют, драгметаллов и прочей информации, это лучше чем парсить текст.

Nexus 25.10.2017 17:09

laimas, в букмарклете обращаться к серверу ЦБ для получения этих данных?)
Обратиться к элементам страницы и получить нужные данные куда проще и быстрее.

Нужно было просто написать букмарклет, ни больше.
Это было тестовое задание перед собеседованием.

Alexandroppolus 25.10.2017 17:21

курс доллара (строка):
$('#widget_exchange tr:has(ins:contains("$")) .w_data_wrap')[0].lastChild.data


стоимость золота (строка):
$('#widget_metal tr:has(ins:contains("Au")) .w_data_wrap>span').text()

Nexus 25.10.2017 17:25

Alexandroppolus, :)
$('#widget_metal .content table tr:eq(1) td:eq(1)')
$('#widget_metal tr:has(ins:contains("Au")) .w_data_wrap>span')

laimas 25.10.2017 17:31

Цитата:

Сообщение от Nexus
в букмарклете обращаться к серверу ЦБ для получения этих данных?

Цитата:

Сообщение от Nexus
'www.cbr.ru'

Это на это.

Nexus 25.10.2017 17:35

Цитата:

Сообщение от laimas
Это на это.

Можно более развернуто?

laimas 25.10.2017 17:44

Цитата:

Сообщение от Nexus
Можно более развернуто?

Я вижу запрос к банку, разбор, вот и написал, что есть SOAP для этого. )

Nexus 25.10.2017 18:05

laimas, во второй строке была проверка на нахождение пользователя на указанной странице.

ruslan_mart 26.10.2017 10:59

Nexus, а почему бы не проверять так?

if(document.domain !== 'www.cbr.ru') return !1


И для чего нужна метка javascript? И зачем возвращать значение, если оно никуда не записывается?

Nexus 26.10.2017 11:52

Цитата:

Сообщение от ruslan_mart
Nexus, а почему бы не проверять так?

Я проверяю нахождение на конкретной (главной) странице, а не нахождение на какой-либо странице конкретного домена.
Цитата:

Сообщение от ruslan_mart
И для чего нужна метка javascript?

Это не метка.
Если убрать эту строку, то браузер просто попытается перейти по этому коду, как по адресу.
Иными словами строка "javascript" указывает браузеру, что дальнейшую кашу нужно воспроизвести, как js код.

Rasy 27.10.2017 00:41

Nexus,
В чем хитрость инициализации массива с параметром рядом с объектом на 6 строке?

Nexus 27.10.2017 09:23

Rasy,
return {',': '.'}[c] || '';

Это не инициализация массива рядом с объектом, это инициализация объекта и последующее обращение к его свойству, название которого записано в переменной "c" (char).
Строку можно переписать так:
return c==','?'.':'';

Или расписать так:
var obj={',':'.'};
return (c in obj)?obj[c]:'';

Rasy 27.10.2017 11:16

Nexus,
Понял. Это сеньерский уровень писать трудночитаемый будто минифицированный код:)
return !1

можно ведь
return false

Только странно, что используется jQuery

Nexus 27.10.2017 11:26

Rasy, это букмарклет.
Я старался писать минимальное кол-во кода.
return false;
на 3 символа длиннее)

Цитата:

Сообщение от Rasy
Только странно, что используется jQuery

На сайте jQ подключена, так что грех ею не воспользоваться.

PS. До Senior js мне как до Пекина раком.

ruslan_mart 28.10.2017 13:24

Rasy, сеньоры не заморачиваются по этому поводу, по итогу скрипт прогоняют через какой-нибудь сборщик/обфускатор. :)

Rasy 28.10.2017 20:38

ruslan_mart,
личный опыт?)


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