Great Rash
Expert-
Posts
7,974 -
Joined
-
Last visited
-
Days Won
144
Content Type
Profiles
Forums
Calendar
Store
Everything posted by Great Rash
-
Вступление Что мы будем делать: бесконечную карусель картинок (infinite image carousel - это для тех, кто хочет погуглить на тему). Используем для этого небезызвестный фреймворк jQuery. Но мы не будем писать просто код, а напишем полноценный легко настраиваемый плагин. Вообще говоря, на сайте http://www.jquery.com/ есть туториал как писать плагины для jQuery, но для тех кто не знает английского, я опишу важные моменты. Т.к. у меня нет хостинга, то я не могу показать вам что получится у нас в итоге, но примерный результат вы можете посмотреть на этой странице http://jqueryfordesigners.com/demo/infinite-carousel.html. Конечно же мы не будем полностью клонировать эту карусель, а напишем свою, которая будет во многом лучше и удобней для конкретного применения. Итак, приступим... Базовая верстка Наша каруселька будет состоять из нескольких элементов, вложенных друг в друга. Обычно (если кто гуглил, то заметил) это <div>, в который вложен неупорядоченный список (<ul>). Но я не хочу привязываться к определенному HTML, поэтому остановимся на таком обязательном условии: на странице должен быть блок-контейнер, в него должен быть вложен блок-карусель, в который могут быть вложены любые элементы с display: block; или display: inline-block; Но для простоты будем работать с версткой как у всех (хотя это не важно): <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="ru"> <head> <title>jQuery Карусель</title> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> <style type="text/css"> .container { border: red 1px solid; } .carousel { margin: 0; padding: 0; list-style: none; } .carousel li { float: left; width: 88px; height: 88px; padding: 5px; background: lightblue; border: blue 1px solid; } </style> <!-- Тут подключаем фреймворк jQuery. Лучше конечно скачать его себе в проект, а не использовать ссылку на сторонний ресурс (как у меня). --> <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.min.js"></script> <!-- Подключаем наш плагин, который будет расположен по адресу js/myCarousel.js (ну или куда вы там его положите) --> <script type="text/javascript" src="js/myCarousel.js"></script> <script type="text/javascript"> $(document).ready(function() { // ...тут будет вызываться наш плагин }); </script> </head> <body> <div class="container"> <!-- Вместо <ul> может быть любой блочный элемент, в который могут быть вложены любые блочные элементы --> <ul class="carousel"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> </ul> </div> <!-- Кнопки навигации могут располагаться где угодно на странице --> <button class="prev"><</button> <button class="next">></button> </body> </html> Вот и вся тестовая страничка, над которой мы будем экспериментировать. Больше к HTML мы возвращаться не будем, начнем писать скрипт... Как пишутся плагины для jQuery Прежде всего, рекомендую вам пройти по этой ссылке - http://docs.jquery.com/Plugins/Authoring где написан подробный туториал по созданию плагинов для jQuery. Я не буду полностью переводить его, а остановлюсь лишь на моментах, которые важны для нашего проекта. Приступая Итак, чтобы написать плагин для jQuery нужно добавить новый метод к объекту jQuery.fn: // создаем новый метод объекта jQuery.fn jQuery.fn.myCarousel = function() { // Тут пишем код нашего плагина }; "Но где же знак доллара ($)?", спросите вы. Не волнуйтесь, он все еще тут. Однако, чтобы удостовериться, что наш плагин не пересекается с другими библиотеками, которые тоже используют знак доллара, лучше всего передать объект jQuery в самовыполняющуюся функцию (замыкание), которая свяжет его со знаком доллара так, что его нельзя будет переназначить: // создаем функцию-замыкание... (function($){ // создаем новый метод объекта jQuery.fn $.fn.myCarousel = function() { // Тут пишем код нашего плагина }; })(jQuery); // ...которую тут же вызываем, передавая ей в качестве аргумента объект jQuery Таким образом мы сможем использовать знак доллара внутри нашего плагина, не боясь, что он (доллар) может быть переназначен другим скриптом. Контекст Для тех кто не знает что такое контекст (<b>this</b>) рекомендую почитать эту статью. В области видимости (scope) плагина ключевое слово this ссылается на сам объект jQuery, по этому его нет необходимости оборачивать таким образом - $(this);, что является распростаненной ошибкой среди начинающих разработчиков плагинов. Смотрим код: (function($){ $.fn.myCarousel = function() { // нет необходимости писать $(this) т.к. // "this" уже ссылается на объект jQuery // запись $(this) будет означать то же самое, что и $($('#element')); this.fadeIn('normal', function() { // здесь же this будет ссылаться на конкретный DOM-элемент }); }; })(jQuery); Цепь вызовов Почти каждый метод фреймворка jQuery возвращает собственно сам объект jQuery. Это сделано для того, чтобы обеспечить возможность цепочки вызовов. Давайте рассмотрим такой код: $('div').children().css('background', 'red'); Методы .children() и .css() оба являются методами объекта jQuery, но в коде они вызываются последовательно (по цепочке), это возможно благодаря тому, что каждый метод возвращает нам объект jQuery. Это и называется цепь вызовов. Чтобы наш плагин обеспечивал эту возможность, нам нужно из ближайшей области видимости (immediate scope) вернуть ссылку на объект-конструктор, т.е на jQuery. Так же. чтобы наш плагин работал со всеми найденными элементами нам надо использовать метод .each(): (function($){ // создаем новый метод объекта jQuery.fn $.fn.myCarousel = function() { // возвращаем ссылку на объект jQuery return this.each(function() { // сохраняем контекст ($this будет ссылаться на объект jQuery) var $this = $(this); // ...далее идет код плагина }); }; })(jQuery); Опции и значения по умолчанию Для того чтобы плагин можно было легко настраивать можно сделать настройки по умолчанию, которые можно изменять или расширять при помощи метода .extend(). Таким образом нам не придется задавать кучу параметров для нашего плагина, вмето этого можно передать всего один, который будет объектным литералом (JSON): (function($){ /* * создаем новый метод объекта jQuery.fn, * в который передаем параметр options */ $.fn.myCarousel = function(options) { // дефолтные настройки var settings = { a: 1, b: 'text' }; // возвращаем ссылку на объект jQuery return this.each(function() { if (options) { // если в функцию передали опции /* * метод .extend() сливает два объекта, * заменяя совпадающие свойства, * которые есть в объекте settings * новыми свойствами из объекта options * и возвращает измененный settings */ $.extend(settings, options); } // сохраняем контекст ($this будет ссылаться на объект jQuery) var $this = $(this); alert(settings.a); alert(settings.; }); }; })(jQuery); // пример вызова плагина $(document).ready(function() { $('div').myCarousel({ a: 42, b: 'новый текст' }); }); В принципе это все что понадобится нам для создания нашего плагина, поэтому я не буду описывать остальные параграфы из туториала. Кому интересно прочитает о них самостоятельно. Начинаем писать плагин Итак, приступаем к написанию собственно нашего плагина-карусели. Для начала давайте определимся, что нам надо от нашей карусели: 1) она должна быть бесконечной, т.е. когда мы домотаем до последнего элемента все начнется по кругу; 2) кнопки управления могут находится в любом месте на странице (чтобы мы могли подстраивать её под любой дизайн); 3) мы должны сами выбирать по сколько элементов за раз будет проматываться; 4) мы болжны сами выбирать с какой скоростью будут перематываться элементы; 5) мы должны сами выбирать сколько элементов будет отображаться в обласи видимости, а сколько будет "за кадром"; 6) должна быть возможность автоматической перемотки если юзер не нажал на стрелки сам. Вооружившись знаниями о написании плагинов, приступим к реализации задуманного: (function($){ $.fn.myCarousel = function(options) { // дефолтные настройки var settings = { visible: 3, // видимых элементов - 3 rotateBy: 1, // мотать по одному элементу speed: 500, // скорость перемотки (в миллисекундах) btnNext: null, // кнопка перемотки к следующему элементу btnPrev: null, // кнопка перемотки к предыдущему элементу auto: null, // время задержки (в миллисекундах) при автоматической перемотке backSlide: false // будет ли карусель крутиться в обратную сторону при автоматической перемотке }; return this.each(function() { if (options) { $.extend(settings, options); } var $this = $(this); // сохраняем контекст }); }; })(jQuery); Тут надеюсь все понятно. Теперь нам необходимо определить, так сказать, "глобальные" переменные (конечно они не глобальные во всем документе, а "глобальные" для нашего плагина): (function($){ $.fn.myCarousel = function(options) { // дефолтные настройки var settings = { visible: 3, rotateBy: 1, speed: 500, btnNext: null, btnPrev: null, auto: null, backSlide: false }; return this.each(function() { if (options) { $.extend(settings, options); } // определяем "глобальные" переменные var $this = $(this); // сохраняем контекст var $carousel = $this.children(':first'); // находим первого потомка в нашем контейнере (.container), т.е. <ul> var itemWidth = $carousel.children().outerWidth(); // находим ширину одного элемента внутри нашего контейнера var itemsTotal = $carousel.children().length; // определяем сколько всего элементов у нашей карусели var running = false; // флаг, который хранит информацию о том проигрывается ли анимация на данный момент var intID = null; // ID интервала (нужен для сброса интервала) }); }; })(jQuery); Обратите внимание на то что я специально взял слово "глобальные" в кавычки, чтобы у вас не возникло путаницы. Эти переменные не являются глобальными на самом деле, т.е. они не видны за пределами функции. Возможно лучше было бы обозвать их "статическими", но мне больше понравился первый вариант. Далее нам необходимо присвоить такие стили для нашей карусели без которых она не будет работать. Юзер может забыть их присвоить, поэтому нам необходимо задавать эти стили скриптом: (function($){ $.fn.myCarousel = function(options) { // дефолтные настройки var settings = { visible: 3, rotateBy: 1, speed: 500, btnNext: null, btnPrev: null, auto: null, backSlide: false }; return this.each(function() { if (options) { $.extend(settings, options); } // определяем "глобальные" переменные var $this = $(this); var $carousel = $this.children(':first'); var itemWidth = $carousel.children().outerWidth(); var itemsTotal = $carousel.children().length; var running = false; var intID = null; // присваиваем необходимые стили для элементов карусели // сначала для контейнера $this.css({ 'position': 'relative', // необходимо для нормального отображения в ИЕ6(7) 'overflow': 'hidden', // прячем все, что не влезает в контейнер 'width': settings.visible * itemWidth + 'px' // ширину контейнера ставим равной ширине всех видимых элементов }); // потом для внутреннего элемента (в нашем случае <ul>) $carousel.css({ 'position': 'relative', // относительное позиционирование нужно для того, чтобы можно было использовать сдвиг влево 'width': 9999 + 'px', // ставим ширину побольше, чтобы точно влезли все элементы 'left': 0 // устанавливаем нулевой девый сдвиг }); }); }; })(jQuery); Теперь, после всех приготовлений, пришло время заняться написанием нашей главной функции - функции "скольжения", которая будет прокручивать карусель. Я не буду расписывать на словах как она работает, а лучше покажу схему, из которой вам будет больше понятен принцип работы бесконечной карусели: На картинке описана прокрутка к предыдущему элементу. Такая же последовательность действий у нас будет при прокрутке к следующему элементу. Остальное, надеюсь, будет понятно из кода: (function($){ $.fn.myCarousel = function(options) { // дефолтные настройки var settings = { visible: 3, rotateBy: 1, speed: 500, btnNext: null, btnPrev: null, auto: null, backSlide: false }; return this.each(function() { if (options) { $.extend(settings, options); } // определяем "глобальные" переменные var $this = $(this); var $carousel = $this.children(':first'); var itemWidth = $carousel.children().outerWidth(); var itemsTotal = $carousel.children().length; var running = false; var intID = null; // присваиваем необходимые стили для элементов карусели // сначала для контейнера $this.css({ 'position': 'relative', // необходимо для нормального отображения в ИЕ6(7) 'overflow': 'hidden', // прячем все, что не влезает в контейнер 'width': settings.visible * itemWidth + 'px' // ширину контейнера ставим равной ширине всех видимых элементов }); // потом для внутреннего элемента (в нашем случае <ul>) $carousel.css({ 'position': 'relative', // относительное позиционирование нужно для того, чтобы можно было использовать сдвиг влево 'width': 9999 + 'px', // ставим ширину побольше, чтобы точно влезли все элементы 'left': 0 // устанавливаем нулевой девый сдвиг }); // параметр dir(boolean) - false(сдедующий), true(предыдущий) function slide(dir) { var direction = !dir ? -1 : 1; // выбираем направление в зависимости от переданного параметра (влево или вправо) var leftIndent = 0; // левое смещение (для <ul>) if (!running) { // если анимация завершена (или еще не запущена) running = true; // ставим флажок, что анимация в процессе if (intID) { // если запущен интервал window.clearInterval(intID); // очищаем интервал } if (!dir) { // если мы мотаем к следующему элементу (так по умолчанию) /* * вставляем после последнего элемента карусели * клоны стольких элементов, сколько задано * в параметре rotateBy (по умолчанию задан один элемент) */ $carousel.children(':last').after($carousel.children().slice(0, settings.rotateBy).clone(true)); } else { // если мотаем к предыдущему элементу /* * вставляем перед первым элементом карусели * клоны стольких элементов, сколько задано * в параметре rotateBy (по умолчанию задан один элемент) */ $carousel.children(':first').before($carousel.children().slice(itemsTotal - settings.rotateBy, itemsTotal).clone(true)); /* * сдвигаем карусель (<ul>) влево на ширину элемента, * умноженную на количество элементов, заданных * в параметре rotateBy (по умолчанию задан один элемент) */ $carousel.css('left', -itemWidth * settings.rotateBy + 'px'); } /* * расчитываем левое смещение * текущее значение left + ширина одного элемента * количество проматываемых элементов * на направление перемещения (1 или -1) */ leftIndent = parseInt($carousel.css('left')) + (itemWidth * settings.rotateBy * direction); // запускаем анимацию $carousel.animate({'left': leftIndent}, {queue: false, duration: settings.speed, complete: function() { // когда анимация закончена if (!dir) { // если мы мотаем к следующему элементу (так по умолчанию) // удаляем столько первых элементов, сколько задано в rotateBy $carousel.children().slice(0, settings.rotateBy).remove(); // устанавливаем сдвиг в ноль $carousel.css('left', 0); } else { // если мотаем к предыдущему элементу // удаляем столько последних элементов, сколько задано в rotateBy $carousel.children().slice(itemsTotal, itemsTotal + settings.rotateBy).remove(); } if (settings.auto) { // если карусель должна проматываться автоматически // запускаем вызов функции через интервал времени (auto) intID = window.setInterval(function() { slide(settings.backslide); }, settings.auto); } running = false; // отмечаем, что анимация завершена }}); } return false; // возвращаем false для того, чтобы не было перехода по ссылке } // назначаем обработчик на событие click для кнопки next $(settings.btnNext).click(function() { return slide(false); }); // назначаем обработчик на событие click для кнопки previous $(settings.btnPrev).click(function() { return slide(true); }); if (settings.auto) { // если карусель должна проматываться автоматически // запускаем вызов функции через временной интервал intID = window.setInterval(function() { slide(settings.backslide); }, settings.auto); } }); }; })(jQuery); Вот и готов наш плагин Сохраните его в файле my_carousel.js, подключите на страницу, а затем, между тегами <head></head> напишите такой вызов: <script type="text/javascript"> $(document).ready(function() { $('.container').myCarousel({ btnNext: '.next', btnPrev: '.prev', visible: 4, rotateBy: 2 }); }); </script> Итак, опишем настройки для нашей карусели: btnNext - строка, выражение в формате jQuery (по умолчанию null) btnPrev - строка, выражение в формате jQuery visible - целое число, количество видимых элементов (по умолчанию 1) rotateBy - целое число, по сколько элементов мотать за раз (по умолчанию 1) speed - целое число, скорость прокрутки элементов в миллисекундах (чем больше тем медленней, по умолчанию 500 миллисекунд) auto - целое число, задержка автоматической прокрутки элементов в миллисекундах (если назначена, по умолчанию null) backSlide - булево значение true/false, направление прокрутки: false - к следующему элементу, true - к предыдущему элементу (по умолчанию false) И на последок полный код нашего плагина без комментариев. my_carousel.js (function($){ $.fn.myCarousel = function(options) { var settings = { visible: 3, rotateBy: 1, speed: 500, btnNext: null, btnPrev: null, auto: null, backSlide: false }; return this.each(function() { if (options) { $.extend(settings, options); } var $this = $(this); var $carousel = $this.children(':first'); var itemWidth = $carousel.children().outerWidth(); var itemsTotal = $carousel.children().length; var running = false; var intID = null; $this.css({ 'position': 'relative', 'overflow': 'hidden', 'width': settings.visible * itemWidth + 'px' }); $carousel.css({ 'position': 'relative', 'width': 9999 + 'px', 'left': 0 }); function slide(dir) { var direction = !dir ? -1 : 1; var leftIndent = 0; if (!running) { running = true; if (intID) { window.clearInterval(intID); } if (!dir) { $carousel.children(':last').after($carousel.children().slice(0, settings.rotateBy).clone(true)); } else { $carousel.children(':first').before($carousel.children().slice(itemsTotal - settings.rotateBy, itemsTotal).clone(true)); $carousel.css('left', -itemWidth * settings.rotateBy + 'px'); } leftIndent = parseInt($carousel.css('left')) + (itemWidth * settings.rotateBy * direction); $carousel.animate({'left': leftIndent}, {queue: false, duration: settings.speed, complete: function() { if (!dir) { $carousel.children().slice(0, settings.rotateBy).remove(); $carousel.css('left', 0); } else { $carousel.children().slice(itemsTotal, itemsTotal + settings.rotateBy).remove(); } if (settings.auto) { intID = window.setInterval(function() { slide(settings.backslide); }, settings.auto); } running = false; }}); } return false; } $(settings.btnNext).click(function() { return slide(false); }); $(settings.btnPrev).click(function() { return slide(true); }); if (settings.auto) { intID = window.setInterval(function() { slide(settings.backslide); }, settings.auto); } }); }; })(jQuery); Предложения, критику и прочее в приват. Всем спасибо за внимание.
- 1 reply
-
- 6
-
Может дело в том, что путь до файла стилей начинает считаться относительно фрейма, а документ, который подгружается во фрейм, лежит в другом месте. Проверьте фаербагом путь. Опять же записывать во фрейм что-то через innerHTML неправильно, правильно как-то так: var frame = document.getElementById('iframe') var _document = frame.contentDocument || frame.contentWindow.document; var _head = _document.createElement('head'); _document.appendChild(_head); _head.innerHTML = 'бла-бла-бла';
-
Рад был потешить ваше ЧСВ, Verder Если вы, уважаемый Протуберанец, не заметили, то я не являюсь модератором данного раздела форума, тут я пишу на правах обычного посетителя как и вы Ваш довод про "рябь" в глазах, несомненно, наиболее авторитетен и нам, сирым и убогим, конечно же далеко до вас. Возможно вы не заметили, но раздел, собственно, называется "Флейм", что не дает вам права нарушать правила форума, которые вы нарушили (в частности пункты 2, 8 и 12). Но, как я уже сказал, в этом разделе я обычный пользователь как и вы, и поэтому могу только попросить вас угомониться и не нервничать. Не умеете вы спорить...
-
Точно! Вот в чем дело! У ТС тема сисег не раскрыта! Тётька зачем-то пузо втянула... поди переела за ужином, а теперь стесняется...
-
Точно... Verder'а как обычно не туда занесло. Я тут заметил, что не нравится "ё" в основном Verder'у и Протуберанцу, на которых сами-знаете-кто повлиял... хе-хе...
-
Кстати, латиница тоже этим грешит, и почему-то никто не считает это ущербным: Латиница облажалась? Или просто гражданам России опостылел собственный язык?
-
А хоть бы и в туалете. Вон в метро каждый пятый читает. То что ресурс попсовый даже хорошо. Было бы глупо интересоваться подобным мнением среди писателей или лингвистов например...
-
Я думаю, публика на портале ответы@mail.ru довольно много читает, хотя бы те же блоги... Опять же, мы, пока ещё, самая читающая нация.
-
Да, он не один. Меня совершенно не раздражает наличие ё вместо е. Тем более не так уж и много слов где эта буква встречается. Не надо утрировать, ничего рябить не будет. P.S. Опрос показал, что большинство за букву Ё. Так что...
-
«css двухколоночный макет» в Google. ???
-
Ну не прям треш, но хуже латиницы, это да... Но из слов Verder'а (может и сами-знаете-кого тоже) следует, что кириллица сама по себе УГ. Вот с этим я не согласен, дело не в алфавите, а в том что многие шрифты "портированы", а оригинал, как известно, всегда лучше копии. Хотя лично меня тот же Arial не раздражает... Но, все таки, мы тут букву Ё обсуждаем, а не шрифты...
-
mishka2, посмотри для примера на шрифт Georgia в латинице и в кириллице - в латинице он явно лучше смотрится.
-
А типа код города не важен? Если уж на то пошло то так: <em>Москва: 8 /917/ <b>123-45-67</b></em> Параграф не нужен, т.к. все это наверняка будет в блоке, а уж самому <em> можно сказать display: block; P.S. И, как бы, код города для Москвы 495, и, как бы, привычнее, когда он в скобках, а не в слешах, и если уж это мобила, то лучше бы написать +7 вместо 8...
-
Какое-то это Lightview тормозное... Вот что я юзаю для своих задач - http://www.digitalia.be/software/slimbox2
-
Вот мне интересно, а если бы у тов. Навального не было акций Транснефти он бы радел за российский народ с таким же рвением? Еще мне интересно как же все-таки народ так вдруг самоорганизовался в 1991 году и вышел таки устраивать путч? На второй вопрос у меня есть ответ-предположение - нифига народ сам не собирался, а был организован определенными людми из правительства, которые на иностранные деньги организовали в стране переворот. И никогда в истории человечества народ сам не организовывался, как это ни печально... Так что пока не найдется человек сверху с деньгами (или люди с деньгами извне), которого не будет устраивать что-то в государственном устройстве нашей страны, ничего в нашей стране не изменится. Пока идейных дураков в России нет (кому захочется терять кучу бабла ради мира во всем мире) и за границей (в Америке, в Европе или еще где) тоже всех устраивает нынешнее положение дел. Так что пустой треп все это... P.S. Слово "путч" такое забавное... напоминает слово "пучить", что в общем не далеко от истины...
-
musulman, меня убивает периодическое появление одного и того же сайта в обсуждении на протяжении полугода как минимум Что это? Своеобразная раскрутка? Набивание переходов, чтоб подняться повыше в выдаче? Просто за пол года по этому сайту уже все, что только можно обсудили...
-
В фотоблоге делать ссылку "подробнее" вместо того, чтоб кликать по самой фотке - глупо.
-
Я тоже за то, чтобы законодательно закрепить написание буквы Ё во всех словах, где она встречается. Давайте еще и завитушку у и краткой уберем, она небось тоже "глаз режет"... глупость... Просто фишка в том, что Ё расположена на клаве совсем уж не удобно... во всем виновато заморское происхождение qwerty-клавиатуры. Вот и не очень удобно, печатая текст, набирать Ё. Но в официальной литературе буква Ё должна быть! Ненависть Verder'а к кириллице умиляет ничем этот алфавит не хуже и не лучше той же латиницы или китайских иероглифов, или арабской вязи... Все дело в том, что шрифты изначально создавались для латиницы, поэтому в кириллице они выглядят хуже. Если бы все было наоборот, то кириллица выглядела бы лучше, а латиница была бы УГ.
-
http://www.artlebedev.ru/tools/technogrette/js/include/
-
Предлагаю для клика заюзать библиотеку raphael.js т.к. без нее реализация довольно муторная: 1) надо отследить координаты мыши на странице 2) надо проверить находится ли курсор над <canvas> 3) надо получить координаты необходимого элемента из контекста (2DContext) 4) сверить находится ли курсор мыши в пределах необходимых координат 5) на клик по <canvas>, в зависимости от координат, соответственно менять location
-
http://forum.htmlbook.ru/index.php?showtopic=21647
-
Как же так? Если б вы знали про файловую систему "не мало" у вас не возникали бы вопросы типа: "А если у меня файл со стилями будет лежать не в корне и не в одной папке с файлом html?" или "А почему вне моей файловой системы не будет работать?"
-
А еще лучше завести себе виртуальную машину с ИЕ7. А еще лучше две - с ИЕ7 и с ИЕ6.
-
Где правильно писать условые комментарии?
Great Rash replied to Red Planet's question in HTML Coding
Согласен с arez, писать можно где угодно. Вплоть до создания элементов (или целых кусков страницы), которые будет "видеть" только ИЕ.