Если нельзя, но очень хочется, то нужно обязательно и ничего в мире не стоит того, чтобы делать из этого проблему!


Интересна Java? Кликай по ссылке и изучай!
Если тебе полезно что-то из того, чем я делюсь в своем блоге - можешь поделиться своими деньгами со мной.
с пожеланием
столько времени читатели провели на блоге - 
сейчас онлайн - 
Показаны сообщения с ярлыком javascript. Показать все сообщения
Показаны сообщения с ярлыком javascript. Показать все сообщения

четверг, 11 июля 2013 г.

JavaScript гид по сайту

Люблю джаваскрипт за то, что c ним порой чувствуешь себя магом и волшебником. Не так давно в голове возникла идея - а что, если на сайт, который изначально не гибок в этом плане (без аджакса и джаваскриптовой цветомузыки) навешать немного джаваскрипта. Скажу сразу, речь идет об LMS Moodle (для тех, кто не в курсе - это CMS для тренингов). Так вот была у нас одна проблемка с ним - много че может делать, только вот ничего не понятно как это сделать - часто пользователи нас спрашивают "а как то?", "а как это?", причем, порой, даже сам забываешь где там кликнуть надо... Люблю я его за это - квестообразующий :) - не соскучишься с ним. Но это мне так интересно, а другим пользователям? Нужно максимально упрощать!

Идея пришла во время серфинга на другом сайте. Там был простенький гид, кликни там, кликни сям, а тут вот это, а тут ты можешь сделать это. И я подумал - хочу! Стал искать решения. Их есть с десяток. Но я хотел решения, которое будет чисто джаваскриптовым - без правки HTML. И оно нашлось! Сразу показываю результат, каким он получился у меня.


Есть такая библиотека с использованием JQuery, называется Guiders-JS. Настраивается достаточно не сложно. Вот код, который я вставил в боковую панельку чтобы линк Training Guide ожил.

<ul>
    <li>...</li>
    <li>...</li>
    <li>...</li>
    <li>...</li>
    <li><span id="training-guide"><a href="#">Training guide</a></span></li>
</ul>

<p id="training-guide-script">
    <script src="https://host.com/js/guiders-1.3.0/jquery-1.5.1.min.js" type="text/javascript"></script>
    <script src="https://host.com/js/guiders-1.3.0/guiders-1.3.0.js" type="text/javascript"></script>
    <link rel="stylesheet" href="https://host.com/js/guiders-1.3.0/guiders-1.3.0.css" type="text/css" />
    <script src="https://host.com/js/guiders-1.3.0/training-guiders.js" type="text/javascript"></script>
</p>
Все просто. Создается линк никуда не ссылающийся (на него потом навешается обработчик с помощью jQuery). Подключается библиотека jQuery и Guiders-JS, подключается стиль и мой скрипт, в котором описаны окошки гида. Там же и навешивается обработчик на клик и делаются еще кой че.
$(document).ready(function () {
    if ($("#module-1224").size() == 0) {       // проверяем, если мы не на главной страничике (содержащей див
                                               // с айди module-1224), то запускать гид бессмысленно
        $('#training-guide').parent().hide();  // потому мы скрываем возможность вызвать гида
        return;
    }

    $('#training-guide').click(function () {  // при клике на линк  
        guiders.show("start");                       // открываем гид (первый диалог)
    });

    guiders.createGuider({      // создается первый диалог
        buttons: [              // с кнопкой next
            {name: "Next"}
        ],

        title: "**** ******* Guide", // это его заголовок
        description: "Hi! This is **** ****** training course guide. Hope it will help.", // с сообщением

        id: "start",           // это его айдиха
        next: "guide2",         // это айдиха того, куда переходим

        overlay: true,          // задний фон за диалогом будет затеняться
        xButton: true,          // у диалога будет кнопка X в правом верхнем углу
        closeOnEscape: false,   // по нажатию на Esc будет закрыто окно
        width: 350              // ширина диалога
    }).show();

    guiders.createGuider({      // создаем следующий шаг
        attachTo: "#inst16",    // он прикрепляется к диву с этой айдишкой
        position: 10,           // прицепляется в позиции 10. С каждой стороны к диву можно прицепиться: 
                                // с одного краю, с другого и по центру - всего 12 позиций. По часовой 
                                // стрелке от 1 до 12.
                                // 
                                // вот кусочек исходного кода библиотеки:
                                //    guiders._offsetNameMapping = {
                                //        "topLeft": 11,
                                //        "top": 12,
                                //        "topRight": 1,
                                //        "rightTop": 2,
                                //        "right": 3,
                                //        "rightBottom": 4,
                                //        "bottomRight": 5,
                                //        "bottom": 6,
                                //        "bottomLeft": 7,
                                //        "leftBottom": 8,
                                //        "left": 9,
                                //        "leftTop": 10
                                //     "};

        overlay: true,          // опять же фон будет размыт и в тени
        highlight: "#inst16",   // но сам див будет подсвечен

        buttons: [ {name: 'Next', onclick: guiders.next} ], //" на кнопку next навешивается обработчик - следующий диалог                      

        title: "",
        description: "You you can find useful links here.", // другое сообщение

        id: "guide2",          // айдиха текущего диалога
        next: "guide3",        // куда идем на следующий диалог

        autoFocus: true,       // если вдруг див ушел за пределы экрана, подсветить его проскролив страничку
        xButton: true,
        closeOnEscape: false,
        width: 350
    });

    function topic_toggle_new(number, isOpen) {  // это самописная функция которая разворачивает/сворачивает 
                                                 // модуля тренинга на Moodle, вызывая его js код
        var open = $("#toggle-" + number + " .toggle_closed");
        open = (open.size() > 0) ? open[0] : null;

        var close = $("#toggle-" + number + " .toggle_open");
        close = (close.size() > 0) ? close[0] : null;

        if (isOpen) {
            element = (open == null) ? null : open;
        } else {
            element = (close == null) ? null : close;
        }

        if (element != null) {
            toggle_topic(element, number);
        }
    }

    guiders.createGuider({         // создаем третий шаг
        attachTo: "#inst370",
        position: 10,

        highlight: "#inst370",
        overlay: true,

        buttons: [
            {name: "Next", onclick: function () {  // вот тут на next навешиваем больше чем одну 
                                                   // функцию - создли анонимную функцию и в ней 
                                                   // прописали весь сценарий  
                topic_toggle_new(1, false);
                topic_toggle_new(2, false);
                topic_toggle_new(3, false);
                topic_toggle_new(4, false);
                topic_toggle_new(5, false);
                topic_toggle_new(6, false);
                topic_toggle_new(7, false);
                topic_toggle_new(8, false);
                topic_toggle_new(9, false);
                topic_toggle_new(10, false);
                guiders.next();
            }}
        ],

        title: "",
        description: "For each code review you'll get 3 XP. More code " +
            "review you do - more XP you get. Collect XP and " +
            "distinguish yourself!",

        id: "guide3",
        next: "guide4",

        autoFocus: true,
        xButton: true,
        closeOnEscape: false,

        width: 350
    });

    // ну и так далее. На последнем шаге добавляется кнопка Close вот так
    // buttons: [{name: "Close", onclick: guiders.hideAll }]
    // ... 
});
Что замечательно, так это то, что я могу по линку https://host.com/training-page.html#guider=start открыть страничку с гидом.
Enjoy! И спасибо разработчикам Guiders-JS!!

четверг, 15 марта 2012 г.

Как с помощью xpath вытянуть внутренности html странички?

Есть музычка, которую я постоянно слушаю, когда работаю. Об этом писал раньше. Так вот на сайте периодически (хоть и редко) меняются урлы серверов. Когда-то в далеком-далеком прошлом я все-пре-все сохранил в один плейлист, который долго мне служил. Но время прошло и теперь там ни один сервер не грузится. Помню в прошлом на создание этого плейлиста методом открывания каждой из пары десятков ссылок ушло пол часа. На этот раз я решил тех же пол часа инвестировать в эксперименты с xpath.

Итак нам понадобится плагин FirePath для Firefox. После установки этого плагина (и перезагрузке firefox) в окне debug появится вкладка FirePath. Отправимся на исходную страничку и наберем в FirePath следующий код:
//.[contains(text(),'AAC')]/..//a[contains(@href,'.pls')]/@href
После нажатия Enter получим что-то похоже на


Дальше скопируем все ссылки. Сделать это напрямую из FirePath не получилось, а потому пришлось немного извратом заняться. Что сделал? Сохранил исходную страничку на рабочий стол. Открыл в редакторе и вконец ее добавил следующий код.
<script src="http://dfn.dl.sourceforge.net/project/js-xpath/js-xpath/1.0.0/xpath.js" type="text/javascript">
</script>
<script type="text/javascript">
    window.onload = function() {
        // я немного переписал xpath выражение, потому как с помощью xpath.js оригинальный вариант не работал. 
        var xpath = "//.[contains(text(),'Download')]/.[contains(@href,'.pls')]/@href";
        var elements = document.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null);

        function toString(iterator){
            var result = '';
            var item;
            while (item = iterator.iterateNext()){
                result += (item.nodeType == 1 ? item.innerHTML.replace(/</g, "<").replace(/>/g, ">") : item.nodeValue);
            }
            return result;            
        }      
        
        document.clear(); // W3C DOM очень не рекомендует использовать этот метод, но я рискнул
        document.write(toString(elements));        
    }
</script>
Текст примера и xpath.js взят с http://js-xpath.sourceforge.net/xpath-example.html

После стоило всего лишь перегрузить страничку и получить список линков, которые я вставил в текстовый файл и назвал его m3u, а когда тот открыл в winamp то был приятно удивлен - он все сам попарсил и загрузил каждый pls.


Очень приятно осознавать, что невозможного не бывает. Эксперименты заняли немного больше чем планировал - 50 минут. Но я кое в чем прокачался. Поди знай, где этот опыт пригодится.

Я попробовал обобщить код загрузки до такого.
<html>
<body>
<iframe id="iframe" src="http://blablabla.com"></iframe>
<script src="http://dfn.dl.sourceforge.net/project/js-xpath/js-xpath/1.0.0/xpath.js" type="text/javascript">
</script>
<script type="text/javascript">
    window.onload = function() {
        // я немного переписал xpath выражение, потому как с помощью xpath.js оригинальный вариант не работал. 
        var xpath = "//.[contains(text(),'Download')]/.[contains(@href,'.pls')]/@href";
          
        var iframe = document.getElementById("iframe").contentWindow.document;
        var elements = document.evaluate(xpath, iframe, null, XPathResult.ANY_TYPE, null);

        function toString(iterator){
            var result = '';
            var item;
            while (item = iterator.iterateNext()){
                result += (item.nodeType == 1 ? item.innerHTML.replace(/</g, "<").replace(/>/g, ">") : item.nodeValue) + "</br>";
            }
            return result;            
        }      
        
        document.clear(); // W3C DOM очень не рекомендует использовать этот метод, но я рискнул
        document.write(toString(elements));        
    }
</script>
</body>
</html>
Но в месте где я пытался получить document iframe я получал ошибку связанную судя по всему с авторскими правами. Это я понял когда наткнулся на комментарий "хватит пытаться взломать авторский контент" при гуглинге "iframe get document error". По этой причине я не стал выкладывать никаких оригинальных исходников, а всю информацию про сайт, с которого я доставал линки, скрыл. Код (html) в примерах - выдуман мной. А пост написан в целях демонстрации нового инструментария.

Есть у тебя есть информация, как обойти "iframe get document error" поделись в комментах. Я же не стал больше инвестировать в это времени, быть может когда-то в будущем... Поставленная задача была решена, но все же любопытно...

вторник, 7 сентября 2010 г.

Подборка #20

Есть и другие подборки: #1, #2, #3, #4, #5, #6, #7, #8, #9, #10, #11, #12, #13, #14, #15, #16, #17, #18, #19, #20, #21, #22, #23, #24, #25, #26, #27, #28, #29, #30, #31, #32, #33, #34, #35, #36, #37, #38, #39, #40

Вчера, стоя в большой очереди в туалет засекал время, сколько требуется каждому участнику на то, чтобы облегчиться. Эмпирическую закономерность удалось вывести почти сразу: стоя в очереди в туалет подсчитываем и суммируем удвоенное количество девочек и количество мальчиков, а после делим на количество туалетов (если очередь одна, иначе делаем подсчет только для своей очереди/туалета). То, что получится в результате - время ожидания. Основано эта закономерность на том, что девочки в среднем ходят в туалет за 2 минуты, а мальчики за 1 минуту (бывают уникумы успевающие за 30 секунд). Второе правило - самый видный туалет имеет самую длинную очередь, всегда есть рядом туалет, очередь которого в два раза короче. Ищи, но перед тем займи очередь где стал впервые. Кстати в стоимость пива кто-то включает стоимость туалета? А во время ожидания покупки пива, время ожидания освобождения туалета?...

..если нажать в Far в командной строке Shift-Enter, то консольное приложение запустится в отдельном окне - так можно освободить Far для других манипуляций... Читать дальше...

четверг, 18 февраля 2010 г.

Информеры, или как сылаться на свой сайт

Не так давно навешал на свой блог пару счетчиков. Некоторые счетчики предоставлялись с ссылками ведущими с моего сайта. Чтобы лишних линков С сайта не было, я попробовал эти теги удалить. Часть счетчиков осталась рабочей, а часть перестала работать. "Как так?" подумал я. Теперь я это знаю.
Читаем дальше...

Как скопировать из JavaScript-кода текст в буфер обмена?

Как-то раз я заметил одну приятную фишку: под textarea находился линк, копирующий ее содержимое в буфер обмена Windows. Выглядит фишка где-то так

Очень удобно" - подумал я. Следующая мысль была "нифига себе JavaScript и такое умеет?". (читаем дальше)