Модераторы: Sardar, Aliance
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Подгрузка данных без перезагрузки страницы 
:(
    Опции темы
diam
Дата 25.5.2005, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 348
Регистрация: 23.1.2005
Где: Екатеринбург

Репутация: 1
Всего: 16



OFF: предлагаю в эту тему складывать все варианты подгрузки данных на страницу без её перезагрузки.

Иногда появляется необходимость взаимодействия страницы с сервером, передача серверу определённых параметров, получение от него ответа, при этом задача стоит так, что нужно обновить только часть данных и без перезагрузки основной страницы.

Как я себе представляю подгрузку данных. Подгрузить данные в виде картинок, текста и т.п., в общем, не требующего при этом передачи серверу параметров - не представляет из себя никакой сложности. Сложность появляется тогда, когда нужно подгрузить данные на основе каких-либо критериев. Например, у вас есть БД, в которой в виде таблицы лежит информация по улицам, домам, квартирам (т.е., три связанных списка, от улицы зависят дома, которые на ней расположены, от домов - квартиры, которые находятся в этом доме). Передавать всю эту информацию на страницу может быть затруднительным, если, например, в этой таблице больше 100 000 записей. Тут нам может помочь следующий принцип: сначала передаём список улиц, потом, в зависимости от выбранной улицы, передаём список домов, потом, в зависимости от дома - список квартир. Соответственно, для получения списка домов на сервер нужно передать выбранную квартиру, а для списка квартир - выбранные дом и улицу.

Как можно решить подобные задачи? На мой взгляд, нужно с сервера нужно получать JavaScript'овые файлы, содержимое которых зависит от переданных параметров. Ведь если мы сможем получать JavaScript'овые файлы с зависимым от параметров содержимым - то мы можем получать что угодно: списки, новые функции, делать вызовы старых функций и т.п. - не говоря уже про получение статического контента.

Одно из возможных решений - использование метода appendChild, который будет добавлять в наш документ скрипт.
Особенности:
1. Данные пердаются методом GET, что накладывает размер на передаваемые параметры (4 кб по спецификации HTTP)
2. Можно передавать только текстовые параметры, нельзя передать бинарные (файлы, к примеру).

Ниже приведён код с комментариями. Обсуждение здесь.
Код

// Создадим конструктор объектов для подгрузки JS файлов.
function clUploadData ( thesrc ) {
        // При инициализации объекта указываем, откуда данные будут аплоадиться
        this.src = thesrc || "/upload/";
        this.src += "?";

        // Тип замещаемого объекта будет "text/javascript"
        this.type = "text/javascript";

        // oldScript - элемент типа "text/javascript", который
        // при каждом аплоаде будет замещаться новым
        this.oldScript = document.createElement("SCRIPT");
        this.oldScript.type = this.type;

        // callId - число, которое при каждом аплоаде будет
        // изменяться (и будет уникальным, естественно)
        this.callId = 0;

        document.body.appendChild(this.oldScript);

        this.upload = function ( theparams ) {
                // параметры передаются в виде словаря
                // { ключ : значение , ... }.
                // В качестве ключа не должны использоваться
                // русские буквы и спец. символы.
                var params = theparams || {};

                // А теперь, собственно, разбираем словарь по кускам
                var tParams = "";
                for ( var key in params ) {
                        var value = params[key];
                        // Ну а теперь, хит сезона :)
                        // Заменяем в словаре все символы, которые не могут быть
                        // переданы в строке запроса ("+", "&", "=", "\", "#", ";", "\n")
                        // на %xx, где xx - число в шестнадцатеричной форме
                        // Достигается методом encodeURIComponent.
                        value = value.replace("+",encodeURIComponent("+"));
                        value = value.replace("&",encodeURIComponent("&"));
                        value = value.replace("=",encodeURIComponent("="));
                        value = value.replace("#",encodeURIComponent("#"));
                        value = value.replace(";",encodeURIComponent(";"));
                        value = value.replace("\\n",encodeURIComponent("\\n"));
                        value = value.replace("\\\\",encodeURIComponent("\\\\"));
                        tParams += String(key) + "=" + value + "&";
                }

                // теперь снова создаём элемент типа "text/javascript",
                // который и заменит oldScript
                var newScript = document.createElement("SCRIPT");
                newScript.type = this.type;

                // теперь ещё одна фишка от Alexey(eburg).
                // Элемент, который обеспечивает нам уникальность запроса
                // и, соответственно, некешируемость браузером подгружаемого
                // скрипта, callId.
                // Для того, что бы он действительно стал уникальным, добавим
                // Math.random(). Зачем, спросите Вы? Ответ прост. Пользователь
                // вполне может нажать в браузере F5, его страница обновится,
                // callId снова установится в 0, и браузер перестанет аплоадить
                // данные, потому что запросы будут закэшированы (за искл., Gecko).
                this.callId += 1 + Math.random();

                // Готовим "адрес" скрипта
                newScript.src  = this.src + "callid=" + String(this.callId) + '&' + tParams;

                // Замещаем элемент oldScript на newScript
                document.body.replaceChild(newScript,this.oldScript);

                // Ну, и соответственно, прописываем вместо oldScript новый :)
                this.oldScript = newScript;
        }
}


Теперь подведу итоги, кратко.

1. Конструктор.
Код

function clUploadData ( thesrc ) {
        this.src = thesrc || "/upload/";
        this.src += "?";
        this.type = "text/javascript";
        this.oldScript = document.createElement("SCRIPT");
        this.oldScript.type = this.type;
        this.callId = 0;
        document.body.appendChild(this.oldScript);
        this.upload = function ( theparams ) {
                var params = theparams || {};
                var tParams = "";
                for ( var key in params ) {
                        var value = params[key];
                        value = value.replace("+",encodeURIComponent("+"));
                        value = value.replace("&",encodeURIComponent("&"));
                        value = value.replace("=",encodeURIComponent("="));
                        value = value.replace("#",encodeURIComponent("#"));
                        value = value.replace(";",encodeURIComponent(";"));
                        value = value.replace("\\n",encodeURIComponent("\\n"));
                        value = value.replace("\\\\",encodeURIComponent("\\\\"));
                        tParams += String(key) + "=" + value + "&";
                }
                var newScript = document.createElement("SCRIPT");
                newScript.type = this.type;
                this.callId += 1 + Math.random();
                newScript.src  = this.src + "callid=" + String(this.callId) + '&' + tParams;
                document.body.replaceChild(newScript,this.oldScript);
                this.oldScript = newScript;
        }
}


2. Кусок HTML кода с примером использования сего метода
Код

<body>
<script>
var uO = new clUploadData(); // uploadObject
</script>

<form>
<input type="text" name="key" size="30" value="">
<input type="button" value="Загрузить" onClick="uO.upload({'key':this.form.elements['key'].value})">
</form>
</body>


3. Ну, и наконец, кусок кода на PSP, обрабатывающий запрос и выдающий скрипт*.
К сожалению, подсветки под python не сделали (ех, какой большой минус), буду пользоваться подсветкой cpp.
Код

<%
#############################################################
from pyPgSQL import PgSQL

# type is "text/javascript"
req.content_type = "text/javascript"

# FieldStorage dictionary
fsdict = util.FieldStorage(req)

# Сам код
if fsdict.has_key('key'):
        keyvalue = keyvalue.replace("\\", "\\\\")
        keyvalue = fsdict['key'].replace("'","\\'")
        keyvalue = keyvalue.replace("\n", "\\n")
%>
alert('<%= keyvalue %>');
<%
else:
        pass
%>
alert('Не передано ничего!');


* Этот же код можно написать на чём угодно, включая php. Но я пишу на psp, так что эту часть доделывайте сами smile


Пользуйтесь на здоровье. smile
PM MAIL   Вверх
02077461
Дата 27.9.2005, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 183
Регистрация: 13.7.2005

Репутация: нет
Всего: 0



А чем не устраивает создать фрейм и через него с помощью одного скрипта делать все необходимые транзакции??
Лично мне логичнее представлять, что на странице есть некая статическая разметка и объект (скажем таблица) который требует изменения...
Взять например сайт http://www.translate.ru/text.asp?lang=ru: меня он бесит!!! Там более 60 кб ТОЛЬКО ТЕКСТА, который никому не нужен.
Применение фреймов также полезно, если используются статические страницы, которые могут быть кешированы на проксе например.
Добавлено @ 10:47
подписаться забыл...
PM   Вверх
Sardar
Дата 3.10.2005, 12:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 16
Всего: 317



02077461 у фрейма есть два негативных момента: он щёлкает в ИЕ и он ведёт себя по разному в разных браузерах и даже в разных режимах работы(quirks, standart compilance).

Второй момент, не всегда сервер может выдать страницу, слышал когда нибудь о вебсервисах? Например опрашиваем у вебсервиса погоду или курс валют, Яндекс.xml, общение только на XML(XML RPC, SOAP etc), данные ты тоже в XML получаешь. Вот тут и появляеться AJAX технология, правда она имеет мало общего с JSON приведённом в этом топике smile

В любом случае передавать инфу - это меньше трафа чем эту же инфу с разметкой.


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Здесь публикуют скрипты, которые уже проверены в обсуждениях других тем (при этом полезно поставить ссылки на все смежные обсуждения) или переносятся кем-либо из модераторов по просьбе участников, если видно, что в результате обсуждения темы был написан полезный или интересный скрипт. Третий возможный вариант - участник форума публикует скрипт, заведомо известный как полезный и эффективный, для, возможно, небольшой доработки и обсуждения.
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Наши скрипты | Следующая тема »


 




[ Время генерации скрипта: 0.1092 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.