Предыстория
Собственно меня давно просят сделать поиск для сайта. Там конечно очень мало чего искать, но как задел на ближайшее будущее. В планах добавление новых единиц для поиска. Этот туманный и не изученный мной альбион SQL отпугивал своей загадочностью. Но не в файлах же хранить данные. Стоп, а почему бы и нет? Поиск производить с помощью JavaScript. Я подумал о том, что можно в скрипт подгружать данные для поиска и т.д. Заразила меня эта идея, и, когда я приступил к написанию, подумал: «А зачем так усложнять? Пусть всё будет на странице, а пункты не подходящие по характеристикам будут просто скрываться». Заодно и страница поисковикам видна со всеми результатами. Пользователю доступны все данные сразу, и остаётся только выбирать автономно от сервера. Страницу можно сжать и в кэш положить на веки вечные.
История
HTML
Создал новый HTML файл и начал свои эксперименты. Добавил select:
<select id="style" onchange="filter_changed()">
<option value="">Стиль:</option>
<option>неоклассицизм</option>
<option>постмодерн</option>
<option>псевдомодерн</option>
<option>неоготика</option>
</select>
Добавил div с данными:
<div class="home whiteframe">
<a class="url" href="kirpich.example.com/#rust">
<img class="image" src="kirpich.example.com/thmb/rust/rust_vid-1.jpg"/>
</a>
<div class="name">
<a class="url" href="kirpich.example.com/#rust">
«Руст»
</a>
</div>
<div class="style">неоклассицизм</div>
<div class="wall_material">керамический кирпич, утепленный минеральной ватой</div>
<div class="square">165.5</div>
<div class="living_space">86</div>
<div class="floors">2</div>
</div>
Выбирать что есть. Из чего тоже есть. Теперь осталось сделать чем.
JavaScript
Создал JS файл.
И так первое что нам нужно сделать — это обработать все пункты. Это просто:
function filter_changed(){
var list = document.getElementsByClassName("home");
for (var i=0;i<list.length;i++)
hide(list[i], is_filtred(list[i]));
}
Теперь надо определить подходит ли этот пункт под заданные характеристики.
function is_filtred(node){
if (no_text(node, "style")) return true;
}
function no_text(node, filter){
var style_filter = get(document.getElementById(filter),["value"]);
var home_style = get(node.getElementsByClassName(filter),[0,"textContent"]);
if (style_filter && (!home_style || (home_style.indexOf(style_filter)<0)))
return true;
}
Если мы не находим заданной характеристики то элемент скрывается.
function hide(node, h){
node.style.display = h?"none":"block";
}
Так. С этим справились. Но есть ещё величины, которые списком не задашь. Для них делаем фильтр.
function is_filtred(node){
if (no_text(node, "style")) return true;
if (compare(node, "square")) return true;
}
function compare(node, filter, comparer){
var square_filter = get(document.getElementById(filter),["value"]);
var home_square = get(node.getElementsByClassName(filter),[0,"textContent"]);
if (square_filter && !home_square)
return true;
else if (square_filter && home_square){
square_filter = parseFloat(square_filter)
home_square = parseFloat(home_square)
if ((!comparer||comparer==">")?square_filter > home_square:comparer=="<"?square_filter < home_square:comparer=="="?square_filter!=home_square:false)
return true;
}
}
Ну вот вроде и все. Ах да. Что ж за get такой?
function get(node, keys){
for (var i=0; (i<keys.length) && node; i++)
node = node[keys[i]];
return node
}
Он предотвращает ошибку, если вдруг элемент или его свойство не найдены.
CSS
Так как в HTML у нас представлены голые данные, а нам надо дать пользователю понимание, на что он смотрит, добавляем в CSS такие строки.
.name::before{
content: "Название: ";
color: gray;
}
.style::before{
content: "Стиль: ";
color: gray;
}
.wall_material::before{
content: "Материал стен: ";
color: gray;
}
.square::before{
content: "Общая площадь: ";
color: gray;
}
.square::after, .living_space::after{
content: " кв. м.";
color: gray;
}
.floors::before{
content: "Этажи: ";
color: gray;
}
.living_space::before{
content: "Жилая площадь: ";
color: gray;
}
Поскольку эти данные вторичны, мы даем действительно значащему контенту выйти на первый план, задав серый цвет этому тексту.
Заключение
Просто и надеюсь быстро. Не для миллионных списков, но с небольшим количеством данных, думаю, справится. Ну и плюс для меня — наполнение можно переложить на чужие плечи, ибо это просто.
Продолжение: Пусть css ищет или база данных в HTML 2