В moodle есть такое понятие как block. Узенькая полосочка, в 180 пикселей шириной, слева и справа от основного контента. Много инфы там не разместишь. А хочется...
Переколбашивать дизайн и менять ширину влом, да и не спасет это сильно... Ну сколько выручу? Еще 40 пикселей? Мало!
Появилась идея подшаманить на javascript с jquery. Коль уж блок - это div и есть возможность править средствами moodle его контент (как html), то я могу туда вставить свой js код а в нем уже добавить кнопочку развернуть/сернуть.
Только все не так просто оказалось... Столкнулся я с несколькими проблемами. Имя им: cross-browser, position-absolute, iframe-refresh и resize-window. По очереди. Для начала я заметил, что если поставить диву блока стиль position:fixed - то я смогу изменять размеры и позицию дива, так, чтобы он разворачивался и сворачивался
Пол часа работыи слава jQuery все было готово. Но тут я решил запустить Chrome и понял, что работа только начинается... В хроме оно вообще не так работало....Хак не прокатил...
Пришлось заморачиваться с position:absolute. Диву блока простая установка стиля position:absolute не нравилась - он вел себя как-то странно (не абсолютно). Пришлось вместе со стилем менять диву еще и родителя с какого-то там parent'a на body.
То есть я нажимаю expand и перещелкиваю родителя на body, ставлю position:absolute, меняю left/top/width/htight и опаля - все как я хотел. Потом, при нажатии на collapse я делаю все наоборот.
И тут оказалось, что appendChild клеит див в конец боковой панели блоков - нарушается сортировка. ЭЭЭххх. Пришлось при expand, до изменения у блока parent на body, создавать еще див-закладку, по которой потом можно будет вернуть див-блок на место. Плюс этот невидимый див-закладка будет держать физически место, дабы все последующие блоки в панели не сдвигались...
В общем наигрался я с left/top/width/height... И когда все выглядело одинаково в обоих браузерах вылезла еще одна трабла - оказывается если менять родителя диву, то в Firefox и Chrome (но не IE) содержимое того iframe, который расположен в диве, перегружается. Эй! Так дело не пойдет - оно кроме того, что лагает (время на загрузку календаря), так еще и сбрасывает пользователя в начальный режим календаря. Не гуд!!
Идея пришла после душа - надо сразу как загрузится страничка (еще до нажатия expand) сделать reparent на body + position:absolute, а потом, при expand/collapse, играться только с left/top/width/height....
Снова немного танцев у left/top/width/height и все получилось....
Последним (я надеюсь) демоном был resize-window. Дело в том, что если делать expand блока, а потом поменять размеры окна браузера, после чего сделать collapse (или наоборот collapse->resize->expand), то див-блок вернется не на свое место.
Еще немного танцев с left/top/width/height и все получилось....
Думаю задача более общая и кому-то могут пригодистя эти мои наработки. Функция при легкой доработке сможет развернуть/свернуть (влево+вниз) любой див на котрый ткнешь. А потому выложу тут код.
Код, который я вставляю в html view блока.
Может кому-то пригодится....
Переколбашивать дизайн и менять ширину влом, да и не спасет это сильно... Ну сколько выручу? Еще 40 пикселей? Мало!
Появилась идея подшаманить на javascript с jquery. Коль уж блок - это div и есть возможность править средствами moodle его контент (как html), то я могу туда вставить свой js код а в нем уже добавить кнопочку развернуть/сернуть.
Только все не так просто оказалось... Столкнулся я с несколькими проблемами. Имя им: cross-browser, position-absolute, iframe-refresh и resize-window. По очереди. Для начала я заметил, что если поставить диву блока стиль position:fixed - то я смогу изменять размеры и позицию дива, так, чтобы он разворачивался и сворачивался
Пол часа работыи слава jQuery все было готово. Но тут я решил запустить Chrome и понял, что работа только начинается... В хроме оно вообще не так работало....Хак не прокатил...
Пришлось заморачиваться с position:absolute. Диву блока простая установка стиля position:absolute не нравилась - он вел себя как-то странно (не абсолютно). Пришлось вместе со стилем менять диву еще и родителя с какого-то там parent'a на body.
То есть я нажимаю expand и перещелкиваю родителя на body, ставлю position:absolute, меняю left/top/width/htight и опаля - все как я хотел. Потом, при нажатии на collapse я делаю все наоборот.
И тут оказалось, что appendChild клеит див в конец боковой панели блоков - нарушается сортировка. ЭЭЭххх. Пришлось при expand, до изменения у блока parent на body, создавать еще див-закладку, по которой потом можно будет вернуть див-блок на место. Плюс этот невидимый див-закладка будет держать физически место, дабы все последующие блоки в панели не сдвигались...
В общем наигрался я с left/top/width/height... И когда все выглядело одинаково в обоих браузерах вылезла еще одна трабла - оказывается если менять родителя диву, то в Firefox и Chrome (но не IE) содержимое того iframe, который расположен в диве, перегружается. Эй! Так дело не пойдет - оно кроме того, что лагает (время на загрузку календаря), так еще и сбрасывает пользователя в начальный режим календаря. Не гуд!!
Идея пришла после душа - надо сразу как загрузится страничка (еще до нажатия expand) сделать reparent на body + position:absolute, а потом, при expand/collapse, играться только с left/top/width/height....
Снова немного танцев у left/top/width/height и все получилось....
Последним (я надеюсь) демоном был resize-window. Дело в том, что если делать expand блока, а потом поменять размеры окна браузера, после чего сделать collapse (или наоборот collapse->resize->expand), то див-блок вернется не на свое место.
Еще немного танцев с left/top/width/height и все получилось....
Думаю задача более общая и кому-то могут пригодистя эти мои наработки. Функция при легкой доработке сможет развернуть/свернуть (влево+вниз) любой див на котрый ткнешь. А потому выложу тут код.
Код, который я вставляю в html view блока.
<p id="calendar-container"> <script src="/moodle/js/jquery-1.7.2.js" type="text/javascript"></script> <script src="/moodle/js/block-resize.js" type="text/javascript"></script> <script type="text/javascript">// <![CDATA[ // урл ифрейма/ширина/высота развернутого дива/текущий див/див блока/подпись к линку setupBlock('http://google.calendar.com/blabla', 700, 500, 'calendar-container', 'inst406', 'calendar'); // ]]></script></p>А вот и сам скрипт.
if (typeof(setupBlock) == 'undefined') { function setupBlock(iframeSrc, expandWidth, expandHeight, containerId, blockId, title) { var collapsedWidth = 190; var collapsedHeight = 360; var deltaWidth = 10; var deltaHeight = 53; // айдишки, элементы... // все строю относительно blockId, который уникален. Это надо для работы с двумя и больше блоками в режиме collapse/expand var container = $('#' + containerId); var iframeId = 'iframe_' + blockId; var iframe = $('#' + iframeId); var block = $('#' + blockId); var blockMarker = null; // если случилось так, что метод вызовут два раза, мы тут тихонько выйдем if (iframe.length != 0) { return; } // метод ресайза ифрейма - оказывается его надо ресайзить по особенному var resizeIframe = function(width, height) { var element = document.getElementById(iframeId); element.width = width; element.height = height; } // добавляем динамически ифрейм и кнопочку container.append('<iframe id="' + iframeId + '" src="' + iframeSrc + '" style="border: 0;" scrolling="no" frameborder="0"></iframe>'); container.append('</br><a href="#"><span id="resize_' + iframeId + '">expand ' + title + '</span></a>'); container.css({'margin-bottom':0}); // это ничего не значит resizeIframe(collapsedWidth-deltaWidth, collapsedHeight-deltaHeight); // ресайзим ифрейм // порция новеньких... var resizeLink = $('#resize_' + iframeId); var iframe = $('#' + iframeId); // когда все загрузится $(document).ready(function() { var collapsed = true; // изначально все свернуто resizeLink.click(function() { // но клик на линк меняет состояние на противоположное if (collapsed) { expand(); } else { collapse(); } }); // тут сохраняем исходные размеры/координаты (абсолютные) блока var oldWidth = block.width(); var oldHeight = block.height(); var oldLeft = block.offset().left; var oldTop = block.offset().top; // два метода для подсчета left когда свернуто/развернуто var getLeftRestored = function() { return getLeftCollapsed() - expandWidth + oldWidth; }; var getLeftCollapsed = function() { return blockMarker.offset().left; }; // был див где-то там в дереве, а мы его пересадим к корню body, // а на месте дива оставим закладку var absoluting = function() { // если закладки нет, создаем ее сразу после дива-блока if (blockMarker == null) { var blockMarkerId = 'marker_' + blockId; block.after('<div id="' + blockMarkerId + '"></div>'); blockMarker = $("#" + blockMarkerId); } // закладка должнна занимать то же место, что сейчас занимает блок-див blockMarker.css({ left: oldWidth, top: oldTop, width: oldWidth, height: oldHeight, 'margin-left': block.css('margin-left'), 'margin-right': block.css('margin-right'), 'margin-top': block.css('margin-top'), 'margin-bottom': block.css('margin-bottom'), 'padding-left': block.css('padding-left'), 'padding-right': block.css('padding-right'), 'padding-top': block.css('padding-top'), 'padding-bottom': block.css('padding-bottom'), visibility : 'none', // невидим display : 'block', // но занимает место }); document.body.appendChild(block[0]); // переключаемся на body // абсолютим блок, ставим поверх всех и устанавливаем его новые координаты/позициию block.css({ position: 'absolute', 'z-index': 100, left: oldLeft, top: oldTop, width: oldWidth, height: oldHeight, }); }; absoluting(); // do it // это я делал для того, чтобы во время // трансформации линк collapse/expand не работал var resizing = false; var collapse = function() { // выходим, если мы уже ресайзимся или развернуты if (collapsed || resizing) { return; } resizing = true; // поехали resizeLink.text('expand ' + title); // меняем тайтл линка // изменяем размерчики/позицию блока block.css({ left: getLeftCollapsed(), width: oldWidth, height: oldHeight, }); resizeIframe(collapsedWidth-deltaWidth, collapsedHeight-deltaHeight); // ресайзим ифрейм // закончили resizing = false; collapsed = true; }; var expand = function() { // выходим, если мы уже ресайзимся или свернуты if (!collapsed || resizing) { return; } resizing = true; // поехали resizeLink.text('collapse ' + title); // меняем тайтл линка // изменяем размерчики/позицию блока block.css({ left: getLeftRestored(), width: expandWidth, height: expandHeight, }); // ресайзим ифрейм/ magic numbers - насколько у меня блок больше по размерам от iframe что в нем resizeIframe(expandWidth-deltaWidth, expandHeight-deltaHeight); // закончили resizing = false; collapsed = false; }; // а это модуль ремайза онка браузера // и когда пройдет ресайз $(window).resize(function() { // пересчитаем позицию дива, хорошо что только по left :) block.css({ left: (collapsed)?getLeftCollapsed():getLeftRestored(), }); }); }); } }
Может кому-то пригодится....
Комментариев нет:
Отправить комментарий