Работа с автоматически сгенерированными программами в Dreamweaver MX и Fireworks MX
Причиной того, что программисты называют код, автоматически сгенерированный Dreamweaver MX и Fireworks MX, программами-заготовками (ugly code), является то, что эти программы обобщают все возможные сценарии работы пользователя. Естественно, размер программ при этом увеличивается.
Примером может служить такой вот код, обслуживающий обычную операцию замещения (rollover):
function
MM_findObj(n, d) {
//v4.01
var
p, i, x;
if
(!d) d
=
document;
if
((p
=
n.indexOf(
"?"
))
>
0
&& parent.frames.length) {
d
=
parent.frames[n.substring(p
+
1
)].document;
n
=
n.substring(
0
, p);
if
(!(x
=
d[n] && d.all) x
=
d.all[n];
for
(i
=
0
; !x && i
<
d.forms.length; i
+
+
)
x
=
d.forms[i][n];
for
(i
=
0
; !x && d.layers && i
<
d.layers.lendth; i
+
+
)
x
=
MM_findObj(n, d.layers[i].document);
if
(!x && d.GetElementById)
x
=
d.getElementBy!d(n);
return
x;
}
}
}
function
MM_swapImage() {
//v3.0
var
i, j
=
0
,
x, a
=
MM_swapImage.arguments;
document.MM_sr
=
new
Array;
for
(i
=
0
; i
<
(a.length
-
2
); i
+
=
3
)
if
((MM_findObj(a[i])) !
=
null
) {
document.MM_sr[j
+
+
]
=
x;
if
(Ix.oSrc)
x.oSrc
=
x.src;
x.src
=
a[i
+
2
];
}
}
Попросту говоря, функция MM_SwapImage () получает список аргументов, содержащих данные в форме адресов URL, имен файлов рисунков или пустых строк. Например, искомые данные при помещении курсора мыши над объектом будут выглядеть следующим образом:
onMouseOver
=
"MM_swapImage('shoes', '', 'images/shoes_f2.gif', 'hats','','images/hats_f2.gif',!)"
)
Проблема состоит в том, что в функции не используется последний оператор If. Вместо этого функция проходит в цикле по всем наборам данных и исследует в поисках объекта весь документ.
После этого адрес URL старой графики сохраняется, если используется функция swaplmageRestore (), а сам адрес URL изменяется и указывает уже на новый рисунок.
Все это немного напоминает использование атомной бомбы для жарки барбекю. Естественно, барбекю поджарится, но при этом будет израсходована масса излишней энергии.
В данном примере не только содержится избыточный код, но и несколько излишних циклов процессора, так как для поиска объекта используется рекурсивная функция (древоподобная функция, сохраняющая вызовы на каждой ветви обработки, пока поиск проводится на всех дочерних ветвях).
Само замещение можно представить всего одной строкой:
onMouseOver
=
"this.src='images/shoes_f2.gif'"
Где this – текущий объект, вызвавший событие onMyuseOver. В данном случае это – наш рисунок. Когда курсор мыши помещается над объектом, эта строка программы указывает свойству src (это свойство аналогично атрибуту SRC дескриптора.
Еще одной характеристикой программы-заготовки является вставка приложением Dreamweaver MX на страницу ненужных дескрипторов. Например:
<
td
>
<
font
face
=
"Arial, Helvetica, sans-serif"
>
<
img
src
=
"navbar_images/jct_corner_logo.gif"
width
=
"lll"
heigth
=
"52"
>
<
/
font
>
<
/
td
>
Обратите внимание, что в данном случае отсутствует текст, а в наличии имеется только рисунок. И хотя ошибок нет, избыточный код засоряет страницу и увеличивает время ее загрузки.
Еще один пример программы-заготовки создан для сервера (ColdFusion) и обслуживает команду вставки записи (insert Record):
<
cfif
IsDefined(
"FORM.MM_InsertRecord"
) AND FORM_MM_InsertRecord EQ
"forml"
>
<
cfquery
datasource
=
"jct"
>
INSERT INTO ProductType (ProductType, GraphicURL, ProductDescription) VALUES {
<
cfif
IsDefined(
"FORM.productType"
) AND #FORM.productType# NEQ
""
>
1
#FORM.product
-
Type#
<
cfelse
>
NULL
<
/
cfif
>
<
cfif
IsDefined(
"FORM.graphicURL"
) AND #FORM.graphicURL# NEQ
""
>
1
#FORM.graphicURL#
<
cfelse
>
NULL
<
/
cfif
>
<
cfif
IsDefined(
"FORM.productDescription"
) AND #FORM.productDescription# NEQ
""
>
1
#FORM.productDescription#
<
cfelse
>
NULL
<
/
cfif
>
}
<
/
cfquery
>
<
cflocation
url
=
"test2.cfm"
>
<
/
cfif
>
Этот фрагмент программы ищет параметр с именем MM_InsertRecord, передаваемый из формы forml. Если имя формы – forml, этот фрагмент создает запрос на вставку и проверяет все элементы формы не только на предмет их существования, но и не содержат ли они пустую строку. Если удовлетворены оба условия, значение из формы используется для запроса, в противном случае функция возвращает значение NULL.
После этого страница перенаправляет вас на новую страницу.
В чем же избыточность этого фрагмента? Форма является своей же страницей ответа. Такой механизм не является наилучшим.
Немногим более эффективный механизм может быть заложен в программе страницы ответа и выглядит следующим образом:
<
cfparam
name
=
"productType"
default
=
""
>
<
cfparam
name
=
"productDescription"
default
=
""
>
<
cfparam
name
=
"graphicURL"
default
=
""
>
<
cfquery
datasource
=
"jct"
>
INSERT INTO ProductType (ProductType, GraphicURL, ProductDescription) VALUES (#productType#,tproductDescription#, #graphicURL#)
<
/
cfquery
>
Дескрипторы cfparam являются удобным способом определения значений по умолчанию для того случая, когда элементы формы не существуют. В данном случае проверяется факт существования элементов; в случае отсутствия таковых они создаются и им присваиваются значения по умолчанию. Если не предоставить значения атрибутов по умолчанию, страница вызовет ошибку. Это аналогично проверке выполнения некоторого условия в каком-либо фрагменте программы.
После этого дескриптор с fquery вставляет значения в базу данных либо из элементов формы, либо из значений, установленных по умолчанию.
Таким образом, можно сделать вывод, что оптимизацией кода должны заниматься профессионалы.