|
|
|
| Здравствуйте. У меня возникла проблема с кроссбраузерностью моего чата (недоделанного). .......
10 минут думал как мысль выразить... Проблема не в передаче данных в ифрейм, а в том, как после принятия данных себя ведёт этот ифрейм. В IE всё нормально работает, а в OPERе .... перестают в ифрейме двигаться полосы прокрутки. Вернее двигаться то они двигаются, но анимация их движения не происходит, а технически они и мышкой шевелятся и автоскроллинг работает. Я уже голову себе сломаю скоро. Вот ссылочка, посмотрите пожалуйста.
http://www.savinsk.ru/new/_chat/index.html | |
|
|
|
|
|
|
|
для: blackcement
(02.11.2010 в 14:16)
| | У Вас ВЕЗДЕ ненормально. Включая IE.
setTimeout'ов в коде должно быть 2.
И оба должны ВЫКЛЮЧАТЬСЯ по окончании цикла их работы.
А у Вас setTimeout - один.
И он не выключается.
Кроме того, у Вас происходит не ОБНОВЛЕНИЕ содержимого ифрейма, а ДОБАВЛЕНИЕ к содержимому. В итоге объём ПОВТОРЯЮЩИХСЯ данных в ифрейме нарастает в арифметической прогрессии.
И ещё раз (я здесь об этом уже писал) - надо использовать или ифрейм, или аякс.
Вместе - оно совершенно НИКОМУ не нужно.
И этот код здесь я уже видел.
Правда, по-моему, спрашивали Вы тогда про что-то другое... Нет? | |
|
|
|
|
|
|
|
для: АЯ
(02.11.2010 в 14:39)
| | Этот код я взал по ссылке http://www.codething.ru/ajax_js.php
У меня вообще setTimeout'ов вообще нету, у меня setIntervalы и их 2.
А зачем им выключаться? Один постоянно прокручивает ифрейм, а другой слизывает из SQL базы сообщения чата.
То, что сообщения повторяются я знаю, еще не сделал исключения.
А как без ифрейма чат прокручиваться будет? | |
|
|
|
|
|
|
|
для: blackcement
(02.11.2010 в 15:07)
| | 1. Ну и где там по ссылке http://www.codething.ru/ajax_js.php Вы увидели ифрейм?
Нету его там.
Обновляемая информация там помещается в <DIV>.
Тег <DIV> не имеет атрибута SRC, заполнить тег <DIV> без перезагрузки страницы можно лишь скриптом изменив его innerHTML на "новое содержание".
А где взять это "новое содержание"?
Правильно, взять его можно с сервера, используя Аякс.
2. Если на странице используется ифрейм, то изменить содержимое этого ифрейма без перезагрузки можно ПО ОПРЕДЕЛЕНИЮ. Ибо у ифрейма имеется атрибут SRC, куда можно прописать нужный Вам файл с сервера.
Понимаете?
Ифрейм для того и нужен, чтобы получать информацию с сервера без перезагрузки всей страницы.
Заполнять ифрейм новым содержимым, полученным с помощью аякса - это, блин, не знаю даже как и назвать. Ну это как имея в кармане работающий сотовый телефон с деньгами на счету, специально идти в ночь и в дождь на улицу, чтобы позвонить из телефона-автомата маме и предупредить её, что Вы сейчас будете ей звонить на тот же её номер, но по своему сотовому телефону :-)
Или ифрейм.SRC = 'путь-к-файлу' и никакого Аякса НЕ НАДО.
Или тег.innerHTML = 'ответ-полученный-с-помощью-Аякса' и никакого ифрейма НЕ НАДО.
|
3. Использовать невыключающиеся setTimeout'ы (или setInterval'ы) в данном случае НЕЛЬЗЯ, потому как у Вас имеется ПРЕРЫВАЕМЫЙ процесс.
А именно имеется процесс вызова сервера и получения информации из него.
Этот процесс ПРЕРЫВНЫЙ и НЕКОНТРОЛИРУЕМЫЙ Вами ПО ВРЕМЕНИ.
Никто не знает - какой промежуток времени пройдёт между отправкой запроса на сервер и моментом получения ответа от сервера. Это может занять доли секунды. А может и десяток секунд.
А у Вас через 6 секунд - новое обновление (новый запрос). На старый запрос ещё не получен ответ, а Вы уже шлёте новый запрос.. и ПОСТОЯНННО прокручивается ифрейм... вот же бред :-)
Понимаете, о чём я?
Представьте себе, что Вам поставлена задача быстро забивать гвозди молотком.
Вы настроили два автомата - один выдаёт новый гвоздь каждые 6 секунд.
Другой автомат заставляет молоток делать удар каждые полсекунды.
Сколько гвоздей Вы забьёте за минуту?
Не торопитесь отвечать - "десять".
Реально первый автомат выдаст Вам 10 гвоздей, а второй автомат заставит молоток ударить 120 раз.
Но вот сколько гвоздей Вы забъёте - неизвестно.
Ибо самый первый гвоздь может попасть на сучок, этот же первый гвоздь может погнуться, молотком при первом же ударе Вы можете попасть себе по пальцу... В итоге Вы не забъёте ни одного гвоздя, но оба автомата сработают "как часы" - на столе будет валяться 10 гвоздей и молоток 120 раз долбанёт Вас по пальцу.
Вот приблизительно ТАК работает Ваш код :-)
ДОЛЖНО БЫТЬ ТАК:
Событие ХХХ - ифрейм загрузился новым содержимым.
В этот момент времени включается ТАЙМЕР-1, который начинает отсчёт времени 6 секунд.
И в этот же момент времени включается ТАЙМЕР-2, который используется для плавной прокрутки ифрейма.
Прокрутка должна закончиться РАНЬШЕ, чем ифрейм будет обновлен (т.е. быстрее, чем за 6 секунд). И ТАЙМЕР-2 более не нужен. И его надо выключить.
А через 6 секунд ТАЙМЕР-1 должен дат команду на обновление ифрейма. И тоже должен отключиться.
Ибо здесь начнётся НЕКОНТРОЛИРУЕМЫЙ Вами ПО ВРЕМЕНИ процесс обновления ифрейма.
Как только обновление произойдёт, наступает опять событие ХХХ (см. сначала)
| Примечание. Описанная схема может применяться только в том случае, если время работы ТАЙМЕРА-2 будет ГАРАНТИРОВАННО меньше, чем 6 секунд. Иначе (если такой гарантии у Вас нет, т.е. Вы не знаете какой высоты будет у Вас содержимое ифрейма), в момент ХХХ надо включить ТАЙМЕР-2, дождаться окончания прокрутки, выключить ТАЙМЕР-2 и включить ТАЙМЕР-1.
Ферштейн?
ПРАВИЛЬНЫЙ итоговый код напишете сами?
Или помочь? | |
|
|
|
|
|
|
|
для: АЯ
(02.11.2010 в 15:34)
| | 1) В ссылке ифрейма нету я оттуда взял только принцып работы AJAX и JavaScript.
Я прекрасно понимаю, что там в ДИВ данные отсылают. Но я не знаю HTML объектов, которые поддерживают прокрутку и ХТМЛ теги, кроме ифрейма. Поэтому так и делаю.
2. Я прекрасно понимаю принцып работы ифрейма и зачем он нужен, но всё= спасибо. Почему именно его я использовал, я Выше описал. Несколько недель назад я сделал такой же чат. Только на трёх ифреймах. Первый - главное окно, во второй отпостовывальсь сообщения пользователя, а третий обновлялся каждые 6 секунд и выводил в себя последние сообщения, а потом добавлял их в главный ифрейм (создавался эффект плавного добавления). Всё бы хорошо, если не это "щёлканье" в IE. Но главное окно чата я взял ифреймом из тех же соображений , что выше описал.
3. Я об этом думал, и посчитал то, что ответ то всё равно ведь прийдёт... Я как-то не подумал о том, что загрузка нескольких строк из БД может занять более 6 секунд. Нуууу, да вообщето человек может ещё скачивать что-нибудь во время переписки. Но больше меня тревожило то, что порядок ответов сервера может быть не правильным. | |
|
|
|
|
|
|
|
для: blackcement
(02.11.2010 в 16:14)
| | >"я не знаю HTML объектов, которые поддерживают прокрутку и ХТМЛ теги, кроме ифрейма"
1. HTML-теги поддерживаются большинством HTML-тегов.
Исключения - поля ввода, опшены у селекта...
А вовнутрь, например, тега <DIV> Вы можете поместить любые прочие теги.
2. "Прокрутка" поддерживается практически всеми "блочными" тегами (которые по умолчанию имеют style.display = 'block'). Сиречь вполне легко обеспечить тот же <DIV> как бордюрами (как у ифрейма), так и скроллбарами по обоим направлениям (как у ифрейма). Соответственно, также, как и у ифрейма, у этого DIV'a будут свойства scrolHeight и scrollTop, кои Вам нужны для осуществления принудительной плавной прокрутки.
Так что - НИКАКИХ проблем нет.
"Скрипачифрейм не нужен."(с)
-----
>"Всё бы хорошо, если не это "щёлканье" в IE. Но главное окно чата я взял ифреймом из тех же соображений , что выше описал."
1. Нет проблем, если Вас сильно раздражает это "щелканье", используйте <DIV> со всеми теми свойствами, о коих я написал выше.
И вот тогда Вам действительно нужен будет AJAX, чтобы каждые 6 секунд получать содержание файла чата.
2. Только вот скрипт всё-равно надо изменить.
А именно, функцию, коя запускается по onreadystatechange, надо будет прописать грамотно.
Именно срабатывание этой функции и будет тем самым событием ХХХ, о котором написано выше.
Эта функция должна прописать полученный респонс-текст как innerHTML для <DIV> и запустить ТАЙМЕР-2, который плавно прокрутит содержимое <DIV> до самого низа.
Как только DIV "докрутится", ТАЙМЕР-2 следует отключить и надо включить ТАЙМЕР-1, на отсылку нового запроса к серверу.
Ну что, код написать, или сами сообразите? | |
|
|
|
|
|
|
|
для: АЯ
(02.11.2010 в 17:49)
| | Я понимаю, что Вы хотите мне объяснить. Дело в том, что мне пока тяжело представить такой код с динамически отключающимися таймерами, условиями которого будет достижение максимума бегунка хитрого DIVа(с которым я только познакомился) в который AJAX посылает данные.
Естественно Ваши первые замечания для меня не остались незамеченными, особенно от 02.11.2010 в 15:34 пункт 3 :)
Так как не очень опытный, я попытался решить эту проблему немного проще, чем сейчас Вы предлагаете. Код привожу ниже
<html>
<head>
<title>Чат</title>
<meta http-equiv="content-type" content="text/html;charset=utf-16">
<style>div.chat{
border:1px solid #c4bcb5;
height:300px;
width:100%;
overflow:scroll;
}</style>
<script type="text/javascript">
setTimeout("showContent('./updater.php?metka=0')", 6000)
setInterval("scroll()",6 )
function scroll() {
var div = document.getElementById('chat')
div.scrollTop = div.scrollTop+1;
}
function showContent(link) {
var cont = document.getElementById('chat');
var http = createRequestObject();
if( http )
{
http.open('get', link);
http.onreadystatechange = function ()
{
if(http.readyState == 4)
{
cont.innerHTML+= http.responseText;
setTimeout("showContent('./updater.php?metka=0')", 6000)
}
}
http.send(null);
}
else
{
document.location = link;
}
}
// создание ajax объекта
function createRequestObject()
{
try { return new XMLHttpRequest() }
catch(e)
{
try { return new ActiveXObject('Msxml2.XMLHTTP') }
catch(e)
{
try { return new ActiveXObject('Microsoft.XMLHTTP') }
catch(e) { return null; }
}
}
}
</script>
</head>
|
Таким образом я хотел сделать так, чтобы функция запускалась повторно через 6 секунд после выполнения своей "основной" работы (сигналом к окончания которой - добавление контента в DIV). Я уже через монитор чувствую, что Вы скажете: "Всё не правильно!!!", поэтому прошу помочь с кодом...
На счёт авто-прокрутки DIVа. Не могу понять что страшного в том, как у меня сделана прокрутка? Вот только теперь думаю: через каждые 6 миллисекунд ползунок спускается вниз, не случиться ли такая ситуация, что его его позиция примет огромное число и скрипт "встанет" (хотя должно обнулиться я думаю или стать максимально отрицательным), Я просто раньше программировал только на Delphi и C#, там если позиция ползунка скролла больше максимума, то она сбрасывается на максимум. | |
|
|
|
|
|
|
|
для: blackcement
(03.11.2010 в 10:49)
| | http://codecenter.awardspace.com/refrdiv.html
Вместо chat.php пропишите путь к своему файлу с содержимым чата.
-----
1. try--catch - "красивый", но в данном случае ненужный оператор. Будьте проще
2. Незачем "долбить" скролл, не переставая.
Есть ТРИ величины:
- общая высота содержимого дива scrollHeight
- клиентская высота дива (минус бордеры и минус горизонтальный скроллбар) clientHeight
- положение вертикального ползунка scrollTop
Когда scrollHeight == clientHeight + scrollTop - это означает что ползунок вертикального скролла ТОЧНО внизу.
Для всех, кроме OPERA. Для неё (если попроще) надо вводить поправку на ширину сколлбара (18 пикселей).
3. По уму, конечно, надо ещё и отрубать "плавный скролл вниз", когда клиент "хватается" за ползунок. | |
|
|
|
|
|
|
|
для: АЯ
(03.11.2010 в 14:16)
| | АЯ, ОГРОМНОЕ ЧЕЛОВЕЧЕСКОЕ СПАСИБО !
Всё понял, буду работать. | |
|
|
|
|
|
|
|
для: АЯ
(03.11.2010 в 14:16)
| | Снова здравствуйте. Опять возникли проблемы.
Почему-то через IE в ДИВе отображается только первая строка, а фактически ДИВ заполнен нормально. Проверяю это АЛЕРТом
http://savinsk.ru/new/index.php?p=_chat | |
|
|
|
|
|
|
|
для: blackcement
(04.11.2010 в 21:54)
| | У меня в iE видно всё.
Блок <script>...</script>, помещённый внутри заголовка (т.е. между <head> и </head>) - он ГАРАНТИРОВАННО выполнится.
С помещённым в другое место (внутри тегов <body>...</body> как у вас, или после </html>, или ещё где) могут возникнуть проблемы неисполнения.
И об этом именно Вам я здесь уже писал - http://www.softtime.ru/forum/read.php?id_forum=4&id_theme=76143
----
А вообще код у Вас странноватый.
В операторе replace () на месте первого операнда должна быть переменая, содержащая регулярное выражение.
Типа явно прописанного - /\n/g или неявно - new RegExp ('\n', 'g')
А у Вас - переменная pos типа Number
И вообще - появилось у Вас много бреда.
innerHTML дива вы не заменяете (=), а добавляете (+=), а затем от старого избавляетесь...
А кое-что из необходимого - исчезло.
В общем, логика, если она у Вас в коде и есть (я не стал плотно разбираться, ибо не понял смысла Ваших "загодумок") - она по-любому ущербная. | |
|
|
|
|
|
|
|
для: blackcement
(02.11.2010 в 15:07)
| | Пример прокрутки без фрейма. Задаете высоту ширину, ну и остальнео по вкусу
<html>
<head>
<style>
.over{
border:1px solid #E0EFFA;
height:49px;
overflow:auto;
width:316px;
}
</style>
</head>
<body>
Создаете <div class="over">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>7</li>
</ul>
</div>
</body>
</html> | |
|
|
|
|
|
|
|
для: captain-america
(02.11.2010 в 15:48)
| | Спасибо Вам, Captain-america. | |
|
|
|
|