Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

HTML+CSS+JavaScript

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: AJAX и JavaScript вывод в iframe
 
 автор: blackcement   (02.11.2010 в 14:16)   письмо автору
 
 

Здравствуйте. У меня возникла проблема с кроссбраузерностью моего чата (недоделанного). .......
10 минут думал как мысль выразить... Проблема не в передаче данных в ифрейм, а в том, как после принятия данных себя ведёт этот ифрейм. В IE всё нормально работает, а в OPERе .... перестают в ифрейме двигаться полосы прокрутки. Вернее двигаться то они двигаются, но анимация их движения не происходит, а технически они и мышкой шевелятся и автоскроллинг работает. Я уже голову себе сломаю скоро. Вот ссылочка, посмотрите пожалуйста.
http://www.savinsk.ru/new/_chat/index.html

  Ответить  
 
 автор: АЯ   (02.11.2010 в 14:39)   письмо автору
 
   для: blackcement   (02.11.2010 в 14:16)
 

У Вас ВЕЗДЕ ненормально. Включая IE.

setTimeout'ов в коде должно быть 2.
И оба должны ВЫКЛЮЧАТЬСЯ по окончании цикла их работы.

А у Вас setTimeout - один.
И он не выключается.

Кроме того, у Вас происходит не ОБНОВЛЕНИЕ содержимого ифрейма, а ДОБАВЛЕНИЕ к содержимому. В итоге объём ПОВТОРЯЮЩИХСЯ данных в ифрейме нарастает в арифметической прогрессии.

И ещё раз (я здесь об этом уже писал) - надо использовать или ифрейм, или аякс.
Вместе - оно совершенно НИКОМУ не нужно.

И этот код здесь я уже видел.
Правда, по-моему, спрашивали Вы тогда про что-то другое... Нет?

  Ответить  
 
 автор: blackcement   (02.11.2010 в 15:07)   письмо автору
 
   для: АЯ   (02.11.2010 в 14:39)
 

Этот код я взал по ссылке http://www.codething.ru/ajax_js.php

У меня вообще setTimeout'ов вообще нету, у меня setIntervalы и их 2.
А зачем им выключаться? Один постоянно прокручивает ифрейм, а другой слизывает из SQL базы сообщения чата.

То, что сообщения повторяются я знаю, еще не сделал исключения.

А как без ифрейма чат прокручиваться будет?

  Ответить  
 
 автор: АЯ   (02.11.2010 в 15:34)   письмо автору
 
   для: 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.
Ферштейн?

ПРАВИЛЬНЫЙ итоговый код напишете сами?
Или помочь?

  Ответить  
 
 автор: blackcement   (02.11.2010 в 16:14)   письмо автору
 
   для: АЯ   (02.11.2010 в 15:34)
 

1) В ссылке ифрейма нету я оттуда взял только принцып работы AJAX и JavaScript.
Я прекрасно понимаю, что там в ДИВ данные отсылают. Но я не знаю HTML объектов, которые поддерживают прокрутку и ХТМЛ теги, кроме ифрейма. Поэтому так и делаю.

2. Я прекрасно понимаю принцып работы ифрейма и зачем он нужен, но всё= спасибо. Почему именно его я использовал, я Выше описал. Несколько недель назад я сделал такой же чат. Только на трёх ифреймах. Первый - главное окно, во второй отпостовывальсь сообщения пользователя, а третий обновлялся каждые 6 секунд и выводил в себя последние сообщения, а потом добавлял их в главный ифрейм (создавался эффект плавного добавления). Всё бы хорошо, если не это "щёлканье" в IE. Но главное окно чата я взял ифреймом из тех же соображений , что выше описал.

3. Я об этом думал, и посчитал то, что ответ то всё равно ведь прийдёт... Я как-то не подумал о том, что загрузка нескольких строк из БД может занять более 6 секунд. Нуууу, да вообщето человек может ещё скачивать что-нибудь во время переписки. Но больше меня тревожило то, что порядок ответов сервера может быть не правильным.

  Ответить  
 
 автор: АЯ   (02.11.2010 в 17:49)   письмо автору
 
   для: 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, на отсылку нового запроса к серверу.

Ну что, код написать, или сами сообразите?

  Ответить  
 
 автор: blackcement   (03.11.2010 в 10:49)   письмо автору
 
   для: АЯ   (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#, там если позиция ползунка скролла больше максимума, то она сбрасывается на максимум.

  Ответить  
 
 автор: АЯ   (03.11.2010 в 14:16)   письмо автору
 
   для: 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. По уму, конечно, надо ещё и отрубать "плавный скролл вниз", когда клиент "хватается" за ползунок.

  Ответить  
 
 автор: blackcement   (03.11.2010 в 18:33)   письмо автору
 
   для: АЯ   (03.11.2010 в 14:16)
 

АЯ, ОГРОМНОЕ ЧЕЛОВЕЧЕСКОЕ СПАСИБО !
Всё понял, буду работать.

  Ответить  
 
 автор: blackcement   (04.11.2010 в 21:54)   письмо автору
 
   для: АЯ   (03.11.2010 в 14:16)
 

Снова здравствуйте. Опять возникли проблемы.
Почему-то через IE в ДИВе отображается только первая строка, а фактически ДИВ заполнен нормально. Проверяю это АЛЕРТом
http://savinsk.ru/new/index.php?p=_chat

  Ответить  
 
 автор: АЯ   (05.11.2010 в 03:57)   письмо автору
 
   для: 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 дива вы не заменяете (=), а добавляете (+=), а затем от старого избавляетесь...
А кое-что из необходимого - исчезло.

В общем, логика, если она у Вас в коде и есть (я не стал плотно разбираться, ибо не понял смысла Ваших "загодумок") - она по-любому ущербная.

  Ответить  
 
 автор: captain-america   (02.11.2010 в 15:48)   письмо автору
 
   для: 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>

  Ответить  
 
 автор: blackcement   (02.11.2010 в 17:20)   письмо автору
 
   для: captain-america   (02.11.2010 в 15:48)
 

Спасибо Вам, Captain-america.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования