« Поставить закладку » « Сделать стартовой »

« Форумы » « Блоги » « Статьи » « Новости » « Файлы » « Realcoding IRC » « Site map » « Поиск »


Главная Главная
Анонсы Анонсы
Форумы Форумы
Каталог Каталог
Поиск Поиск
Опросы Опросы
Книжный магазин Книжный магазин
Реклама на сайте
Публикации Публикации
Партнеры Партнеры
Карта Карта сайта
Рассылки Рассылки
RSS экспорт
Настройки Настройки
О нас пишут О нас пишут
Контакты Контакты
Гостевая книга Гостевая книга

Создание сайта за 3999 руб.!

ПнВтСрЧтПтСбВс
        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
    Популярное
ООП и JavaScript

Описание функций C (Си) / C++ - stat

Программист Delphi. Обзоры зарплат

Классы разрешений для личности

Генерирование JSON из XML для использования с Ajax

Изменение политики безопасности

Играем с CMOS, или Проснись и пой, компьютер мой

Microsoft SQL Server 2005. Обзор продукта

Глава 12. В глубине меню

Функция CreatePen




    Архив файлов



    Сообщества



    Документация

Статьи:: Интернет технологии :: Html :: Кроссбраузерный DHTML


отправить ссылку другу версия для печати  Обсудить на форуме

Кроссбраузерный DHTML





Начинающие веб-программисты рано или поздно сталкиваются с тем, что их скрипт, любовно написанный (или позаимствованный) и прекрасно работающий на домашнем компьютере с MSIE 5.5, почему-то не работает у соседа или клиента на его Opera, Mozilla или Netscape.

Цель настоящей статьи - рассмотреть имеющиеся различия в DHTML-объектах и функциях у нынешних браузеров. Предполагается, что читатель уже более-менее знаком с программированием по крайней мере под один из браузеров.

Оглавление

Определение браузера

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

isDOM=document.getElementById //DOM1 browser (MSIE 5+, Netscape 6, Opera 5+)
isMSIE=document.all && document.all.item //Microsoft Internet Explorer 4+
isNetscape4=document.layers //Netscape 4.*
isOpera=window.opera //Opera
isOpera5=isOpera && isDOM //Opera 5+
isMSIE5=isDOM && isMSIE //MSIE 5+
isMozilla=isNetscape6=isDOM && !isMSIE && !isOpera //Mozilla или Netscape 6.*

Последняя строчка спорна, т. к. не обязательно все, что не Опера и не MSIE - Mozilla. Однако если появятся браузеры, которые не совместимы ни с MSIE, ни с Opera, то с чем же им еще быть совместимыми, как не с Mozilla (Netscape 6)? Больше не с кем. Для особо ответственных случаев, когда надо наверняка отбросить все неизвестные браузеры, можно воспользоваться тем, что все современные Mozillы содержат в navigator.appName строчку "Netscape", т.е.

isMozilla=isNetscape6=isDOM && (navigator.appName=="Netscape")

Окна и документы

В разных браузерах по-разному вызываются такие свойства, как размеры окна, размеры документа, показатели прокрутки и т.д.

Размеры рабочей области окна

  • MSIE 4+ - document.body.clientWidth, clientHeight
  • Netscape, Mozilla, Opera - innerWidth, innerHeight

Координаты верхнего левого угла окна

  • MSIE 4+ - screenLeft, screenTop
  • Netscape, Mozilla, Opera - screenX, screenY>

Размеры содержимого документа

  • MSIE 4+ - document.body.scrollWidth, scrollHeight
  • Netscape, Mozilla - document.width, height
  • Opera - document.body.style.pixelWidth, pixelHeight

Прокрутка (scrolling)

  • MSIE 4+ - document.body.scrollLeft, scrollTop
  • Netscape, Mozilla, Opera - pageXOffset, pageYOffset

В MSIE в документе должен присутствовать тег <body></body>, иначе document.body не будет определено.

Формы

Доступ к формам

В MSIE такой код прекрасно работает:

<form name=myform>
<input name=mytext>
</form>
......
myform.mytext.value="hello"

Но в 4-ом Netscape этот код выдает ошибку. Там нельзя так обращаться к формам. Необходимо писать document.myform.mytext.value="hello" - это будет работать и там, и там. Чтобы избежать возможных конфликтов имени формы с другими объектами document лучше писать document.forms.myform.mytext.value или document.forms["myform"].elements["mytext"].value. Последняя запись рекомендуется в случаях, когда имя формы или ее элемента могут содержать недопустимые для имени переменной в JavaScript символы.

Формы и Mozilla

В Mozilla лучше не обращаться к элементам страницы (особенно формам) до наступления события onload.

<select> и Netscape

В Netscape у объекта select нет свойства value. Для выбора нужного option пользуйтесь проверкой select.options[n].value и установкой соответствующего select.selectedIndex. Пользоваться select.options[n].selected=true/false не рекомендуется из-за проблем с Opera (см. далее).

<select> и Opera

В Opera старых версий (напр. 5.10, в отличие от, к примеру, 5.12) нельзя выбрать опцию select через select.options[n].selected=true. Вместо этого нужно писать select.selectedIndex=n.

Картинки

Доступ с картинкам, т. е. объектам, создаваемым тегом <img>, осуществляется через коллекцию document./images/[]. Но у Netscape 4 есть особенность в вызове картинки, если она вставлена в слой (см. ниже).

Слои

Если в MSIE 4+ и Mozilla (он же Netscape 6) слоем может быть любой элемент страницы, то в Netscape 4 и Opera 5 это обычно контейнер <div></div> с определенным стилями absolute или relative расположением. Некоторые рекомендуют использовать в Netscape 4 тег <layer>, т. к. он лучше понимается Нетскейпом. Поэтому те случаи, когда <div> и <layer> в 4-ом Netscape ведут себя по-разному, возможно, я рассмотрю в одной из будущих статей. Но эти случаи достаточно редки и специфичны и связаны с глюками в форматировании содержимого слоев.

В Netscape 4 не используйте в именах классов (class=) и идентификаторов (id=) символ подчеркивания "_", в противном случае Netscape не увидит этого элемента.

Доступ к слою

Доступ к слоям по-разному осуществляется в разных браузерах. А именно:

  • MSIE 4+ - document.all[layerName]
  • Netscape 4 - document.layers[layerName]
  • DOM1 (MSIE 5+, Mozilla, Opera 5) - document.getElementById(layerName)

Можно порекомендовать такую функцию:

function layer(layerName){
//DOM1
if(document.getElementById) return document.getElementById(layerName)
//MSIE4
if(document.all) return document.all[layerName]
//Netscape 4
if(document.layers) return document.layers[layerName]
//неподдерживаемый браузер
return null
}

С доступом к слоям в Netscape 4 имеется один аспект. От связан с вложенными (nested) слоями, т. е. со слоями, которые описаны внутри контейнеров другого слоя. Пример (предполагается, что в CSS для тегов <div> задано допустимое свойство position):

<div id="mylayer"><div id="cool">xxx</div></div>

Если в MSIE 4+ можно вызвать слой "cool" через document.all["cool"], то в Netscape 4 document.layers["cool"] вернет undefined. Для вызова вложенного слоя придется написать такую конструкцию:

document.layers["mylayer"].document.layers["cool"]

То же самое касается и адресации других объектов, находящихся внутри слоя - картинок, форм, ссылок и т.д.

Стало быть, нашу функцию можно модернизировать таким образом:

//рекурсивный поиск по слоям
function findLayer(what, where){
if(!where) return
var i,l,parent
var len=where.length
for(i=0;i<len;i++){
parent=where[i].document.layers
l=parent[what]
if(l) return l
l=findLayer(what, parent)
}
return false
}

function layer(layerName, parentLayerName){
if(document.getElementById) return document.getElementById(layerName)
if(document.all) return document.all[layerName]
if(document.layers){
if(parentLayerName){
return findLayer(layerName, eval(parentLayerName))
}else{
return findLayer(layerName, document.layers)
}
}
}

Теперь мы можем обратиться к нашему слою "cool" так: layer("cool","mylayer") или вообще layer("cool"), но последний вариант будет более "тормозным", т. к. компьютеру придется обходить всё дерево слоев до искомого. Похожее соображение приводит к тому, что логично единожды вызвать слой - var mylayer=layer("xxx"), а потом использовать переменную mylayer для дальнейшей работы со слоем.

С картинками, вставленными в слой, в Netscape 4 дело обстоит так же. Картинки в слое не входят в коллекцию document./images/[] корневого документа, они принадлежат коллекции document./images/[] этого слоя. Пример - у нас есть слой "layer", в нем есть картинка "image". Чтоб поменять у этой картинки src, пишем:

document.layers["layer"].document./images/["image"].src="file.jpg"

Доступ к CSS-свойствам слоя

Доступ к CSS-свойствам слоя (расположение, видимость и т.д.) также по-разному осуществляется в разных браузерах. В MSIE 4 и DOM1-браузерах доступ к свойству осуществляется через объект .style. Пример (используется уже определенная нами функция вызова слоя):

// спрятать слой в MSIE4 и DOM1-браузерах
layer("mylayer").style.visibility="hidden"

В Netscape 4 у слоя нет поля style, доступ к свойствам осуществляется непосредственно:

// спрятать слой в Netscape 4
layer("mylayer").visibility="hide"

Можно заметить, что даже значение, которое нужно присвоить свойству .visibility, разное у разных браузеров. Хотя более новые версии 4-ого Netscape поддерживают не только "show"/"hide", но и "visible"/"hidden", как и MSIE.

Для доступа к стилям можно порекомендовать такую функцию:

function layerStyle(layerObject){
if(layerObject.style) return layerObject.style //доступ через style
return layerObject //доступ без style
}

Вместе с которой наш пример сократится до layerStyle(layer("mylayer")).visibility=isNetscape4?"hide":"hidden"

Надо, правда, отметить, что приведенный мной пример выглядит несколько громоздким. Это связано с тем, что он, не обладая большой практической пользой, призван лишь проиллюстрировать работу со слоями в разных браузерах. Но вы можете познакомиться с более аккуратно написанной мною же объектно-ориентированной библиотекой DHTML-функций KLayers.

Различия в CSS-свойствах

Хочу повторить, что доступ к CSS-свойствам по-разному осуществляется в разных браузерах.

Видимость слоя (visibility)

  • MSIE, Opera, Mozilla - .visibility="visible"/"hidden" (видимый/спрятанный)
  • Netscape 4 - .visibility="show"/"hide"

Цвет фона слоя

  • MSIE, Mozilla, Opera 6 - .backgroundColor="ЦВЕТ" (напр. "red","#ffee15")
  • Netscape 4 - .bgColor="ЦВЕТ"
  • Opera 5 - .background="ЦВЕТ" (работает только в том случае, если изначально через CSS для слоя был указан какой-либо фоновый цвет)

Фоновое изображение у слоя

  • MSIE, Mozilla, Opera 6 - .backgroundImage="url(url картинки)"
  • Netscape 4 - .background.src="url картинки"

Обрезка слоя (clip)

Позволяет сделать только часть слоя видимой. Может применяться для эффектов "распахивания", "выползания" или "скроллинга".

  • MSIE, Mozilla - .clip="rect(top,right,bottom,left)"
  • Netscape 4 - .clip.top="top", .clip.right="right" и т.д. (top, right, bottom, left - размеры в пикселах, т.е., к примеру, 120px)
  • Opera - не поддерживается

Для реализации прокручиваемого текста в новых браузерах (MSIE, Mozilla, Opera) удобно применять css-свойство overflow: hidden. Можно создать блок с overflow: hidden и фиксированными размерами, а внутрь его вложить другой блок, который и будем прокручивать. Для прокрутки достаточно менять ему .style.left и top (или .style.pixelLeft, pixelTop в Opera). В Netscape 4, само собой разумеется, для прокрутки слоя придется пользоваться свойством clip.

Не CSS-свойства

У слоев есть свойства, которые не определяются CSS. Это, к примеру, получившиеся габариты слоя, которые зависят от количества текста, помещенного в нем. Обращаться к этим свойствам надо минуя .style, т. е. просто layer.свойство.

Текущие координаты верхнего левого угла слоя на странице

  • MSIE, Opera, Mozilla - .offsetLeft, offsetTop (только для чтения)
  • Netscape 4 - .pageX, pageY (можно изменять, двигая слой абсолютно, т. е. относительно окна, а не родительских элементов, если такие есть)

Пример:

// Y-координата верха слоя
function getLayerTop(layer){
if(isMSIE || isOpera5 || isMozilla){
return layer.offsetTop
}else if(isNetscape4){
return layer.pageY
}
}

В DOM1-браузерах (MSIE, Opera, Mozilla) в случае вложенных слоев, т. е. когда слой вложен в другой слой, координаты .offsetLeft и .offsetTop отсчитываются относительно родительского слоя. Для получения ссылки на родительский элемент существует свойство .offsetParent. Можно пройтись по цепочке offsetParentов, суммируя их координаты, пока не дойдем до самого верхнего родителя - document.body.

Текущие размеры содержимого слоя

  • MSIE, Mozilla - .offsetWidth, offsetHeight
  • Netscape 4 - .document.width, height
  • Opera - .style.pixelWidth, pixelHeight

Изменение содержимого слоя

Запись в слой

  • MSIE, Mozilla - .innerHTML=текст
  • Netscape 4 - .document.open()
    .document.write(текст)
    .document.close()

  • Opera - невозможно

В MSIE 4 не следует вызывать .innerHTML до наступления onload страницы.

В Netscape 4 есть глюк с записью русских букв в слой. Они превращаются либо в символы кодировки western, либо в знаки вопроса ("?????"). Решение этой проблемы может быть достигнуто через использование загрузки в слой другого документа (см. далее). В слой загружается документ с корректно выставленным charset, а потом в него печатается через document.write нужный текст.

Подгрузка другого документа в слой

В Netscape 4 слои имеют атрибут и свойство src, а также метод .load(url). Это позволяет записывать в слой содержимое любого документа.

В MSIE и Mozilla вместо этого есть тег <iframe>, который позволяет достичь похожих результатов. Однако целью данной статьи не является подробное рассмотрение этого решения. Скажу лишь, что этот <iframe> делается невидимым с помощью CSS, в него подгружается искомый документ и, после его загрузки, содержимое <iframe> записывается в нужный слой через .innerHTML.

В Opera будут проблемы, т. к. в ней нельзя ни загружать ничего в слой, ни писать в него.

Динамическое создание слоев через document.write в Netscape 4

В Netscape 4 будет ошибкой создавать слои (или просто теги со стилевым атрибутом style) таким образом:

document.write("<div id='ddd' style='position: absolute'>...</div>")

Почему-то Netscape 4 не переваривает указание стиля для печатаемого через document.write тега. Рекомендуется вынести стили во внешний отдельный тег <style>:

document.write("<style> #ddd { position: absolute } </style>")
document.write("<div id='ddd'>...</div>")

Также можно воспользоваться указанием на class, а не id тега.

Мышь

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

Координаты мыши

Часто бывает нужно узнать текущие координаты курсора мыши на странице, вне зависимости от того, на каком из элементов документа она находится. Создадим функцию, которая будет при событии перемещения мыши помещать в глобальные переменные mousex и mousey текущие координаты курсора относительно документа.

Вот как это делается в различных браузерах:

  • Netscape 4: //Отлавливать событие MOUSEMOVE
    document.captureEvents(Event.MOUSEMOVE)
    document.onmousemove=function(e){
    mousex = e.pageX
    mousey = e.pageY
    return true
    }

  • Mozilla - так же, как и в Netscape 4, но отлавливание события MOUSEMOVE не нужно, т. е. первая строчка не нужна: document.onmousemove=function(e){
    mousex = e.pageX
    mousey = e.pageY
    return true
    }

  • Opera: document.onmousemove=function(){
    mousex=event.clientX
    mousey=event.clientY
    return true
    }

  • MSIE 4+ - так же, как и в Opera, но в нем координаты отсчитываются не относительно документа, а относительно рабочей области окна, т. е. к координатам надо прибавить показания скроллера: document.onmousemove=function(){
    mousex=event.clientX+document.body.scrollLeft
    mousey=event.clientY+document.body.scrollTop
    return true
    }

Соединяя функции для разных браузеров воедино, получаем:

mousex = 0
mousey = 0
if(isNetscape4) document.captureEvents(Event.MOUSEMOVE)
if(isMSIE){
document.onmousemove=function(){
mousex=event.clientX+document.body.scrollLeft
mousey=event.clientY+document.body.scrollTop
return true
}
}else if(isOpera){
document.onmousemove=function(){
mousex=event.clientX
mousey=event.clientY
return true
}
}else if(isNetscape4 || isMozilla){
document.onmousemove=function(e){
mousex = e.pageX
mousey = e.pageY
return true
}
}

Само собой, не забудьте вначале определить браузер.

В Opera событие перемещения мыши будет отлавливаться только тогда, когда оно будет происходить над содержимым документа. т. е. если, к примеру, документ короткий и занимает лишь половину окна браузера, то событие будет отмечаться только на верхней половине окна.

Автор: Сергей Круглов




Рубрика: Html




ASP.NET и немного поисковой оптимизации.

Советы

С тех пор, как появилась Альтависта, большинство посетителей стали приходить на сайты из поисковых машин. И головной боли стало больше. Теперь мало написать сайт, нужно сделать его совместимым с поисковыми ботами. Одна из тех задач, которую приходится решать — быстрая переиндексация обновлений на сайте. Поисковые роботы чаще посещают те сайты, которые чаще меняются.


Подробнее... | Рубрика: Советы | Добавлено: 30.07.2008

Protocol buffers: библиотека обмена данными для C++, Java, Python от Google.

Программирование для Web на C

Наконец-то я могу поделиться тем, чему уже давно радуюсь сам: Google открывает исходники Protocol Buffers! Что это и почему надо радоваться? Это простой и удобный способ обмена данными. Можно сказать, альтернатива XML, но гораздо менее амбициозная и (поэтому) более быстрая и компактная. Далее - перевод отрывка анонса в блоге Open Source at Google и пример использования.


Подробнее... | Рубрика: Программирование для Web на C | Добавлено: 30.07.2008

Описание VivaVisualCode.

VivaCore

В данной статье рассмотрена программа VivaVisualCode, демонстрирующая использование библиотеки VivaCore. Программа VivaVisualCode графически отображает дерево разбора для вводимого исходного кода на языке Си++.


Подробнее... | Рубрика: VivaCore | Добавлено: 29.07.2008

Остальные статьи:

JQuery: Пара сотен плагинов в одной заметке
Касание сетки
Разработка элементов управления ASP.NET на примере навигационной панели
Сохранения параметров приложения в .Net
Custom cursors в .Net
Бегун убегает от хозяина
"Битрикс" выпустил седьмую версию CMS
Выбираем систему управления сайтом
Рынок CMS в Европе или впечатления с CeBIT 2008
32 подводных камня OpenMP при программировании на Си++
Проeкт - шифровка
А что если..? (операторы if...else в C#)
Измерение скорости работы скрипта
О том как разработчики пьют кофе
Работаем с LINQ to XML
XmlSerializer - Assembly Leak без спроса


Цитата дня (все,добавить):



    Рубрикатор

Программирование

C/С++
Обучение
Windows API
XAML
Моделирование
Паттерны
Visual Basic 7 .NET
WxWidgets
Функции WinApi
Функции С++
Разработка под Mac OS
Eiffel
Visual Studio 2008
UI дизайн
Алгоритмы
Конкурсные статьи
Turbo Pascal
Visual Studio
CASE-средства
Visual Studio 2005
Без VCL
Delphi
Тех. документация
Тестирование
Software Testing
ООП
TCP/IP
Google Android
Windows Installer
.NET Framework
Драйвера
C# C Sharp
Справка
Проектирование
Информ. системы
Visual Basic
Assembler
Оптимизация кода
Gtk+
Компоненты
Реинжиниринг
Управление проектами
Extreeme programming
Lotus Notes
Алгебраическое проектирование

Интернет технологии

PHP
Perl
ASP
WAP
Cookies
SSI
CGI
Web Servers
VB Script
DNS
CSS
XML
Html
Java Script
Java2ME
Firewall
Flash
.htaccess
Apache
VRML
Протоколы
Поисковые системы
Технология JAVA
Учебник по PHP
Учебник по JavaScript
Учебник по XML
Java Q&A
AJAX
DHTML
XHTML
Dreamweaver
Web 2.0
Python
Вебмастеру
Cisco
Ruby on Rails
Silverlight

Базы данных

Access
InterBase
MySQL
Oracle
ADO .NET
Основы SQL
Учебник по Access 2002
MS
Microsoft FoxPro
Доступ к данным
XML в MS SQL Server 2000
ODBC и MyODBC
Обучение
Caché
DB2
PostgresSQL
Sybase
Теория
Хранилища данных
Безопасность
Реляционные данные
MySQL и mSQL

Остальное:

Разное
Обзоры книг
Безопасность
Графика и дизайн
Юмор
Linux
Фракталы
Microsoft Axapta
Многоядерность
Сети
Microsoft Office
Работа
MS-DOS
Криптография
Графика и игроделание
Новости SDK
Системы защиты
Учебник по AutoCad
CVS
Windows XP
Windows Server 2003
Windows Vista
Windows 7
Мероприятия

    Кто на сайте
Вы не зарегистрированы.
Имя:

Пароль:

Запомнить

Регистрация позволит Вам пользоваться дополнительными сервисами.
Сейчас на сайте:
Гостей: 95
Пользователей: 0