Все ленты — последние статьи

Растянуть background на весь экран с помощью css, jquery, php

реклама

Нашей целью будет реализовать фон (background) сайта, который будет покрывать все рабочее пространство окна браузера. Мы будем делать это с помощью разных техник используя CSS3, чистый CSS, jQuery, PHP.

Растянуть background на css

Давайте определим, что именно мы хотим получить:

Полная заливка окна картинкой, без пробелов.

Растягивание фоновой картинки, насколько это нужно.

Соответствие пропорций картинки.

Картинка должна находиться в центре.

Это должно быть максимально кроссбраузерно.

И без всяких махинаций с flash.

CSS3 метод

Мы можем растянуть background на чистом css, благодаря свойству background-size которое присутствует в CSS3. Мы будем использовать html элемент, это лучше чем body, так как он всегда будет равен высоте окна браузера. Мы сделаем background фиксированным и поставим его в центре окна, после этого мы его растянем на весь экран с помощью свойства background-size.

 

html {
        background: url(images/bg.jpg) no-repeat center center fixed;
        -webkit-background-size: cover;
        -moz-background-size: cover;
        -o-background-size: cover;
        background-size: cover;
}

 

Кроссбраузерность:

Safari 3+

Chrome Whatever+

IE 9+

Opera 10+ (Opera 9.5 поддерживает background-size но не поддерживает ключевых слов)

Firefox 3.6+

Также есть вариант решения для IE, только необходимо тестировать. Некоторые вебмастера говорят, что могут возникнуть проблемы из ссылками и скроллингом.

 

filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='.myBackground.jpg', sizingMethod='scale');
-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='myBackground.jpg', sizingMethod='scale')";

 

Растянуть background на чистом CSS

Сделать background на весь экран с помощью чистого CSS кода, можно двумя методами. Не исключение что существуют и другие.

1 — Метод

Здесь мы будем использовать элемент img, который будет растянут на все окно, и будет выглядеть одинаково во всех браузерах. Мы установим min-height, который будет заполнять окно браузера по вертикали. Также установим width на 100%, который будет заполнять окно по горизонтали. Мы также установим min-width картинки, таким образом, фон никогда не будет меньше, нежели мы установим.

Особо хитрая часть кода, это использование медиа запроса, для предотвращения бага, когда окно браузера будет меньше, нежели картинка фона. А также, комбинированное использование отступа с процентным left. Это позволяет держать background в центре, несмотря ни на что.

Вот CSS код:

 

img.bg {
        /* Set rules to fill background */
        min-height: 100%;
        min-width: 1024px;
 
        /* Set up proportionate scaling */
        width: 100%;
        height: auto;
 
        /* Set up positioning */
        position: fixed;
        top: 0;
        left: 0;
}
 
@media screen and (max-width: 1024px) { /* Specific to this particular image */
        img.bg {
                left: 50%;
                margin-left: -512px;   /* 50% */
        }
}

 

Кроссбраузерность:

Любые версии популярных браузеров: Safari / Chrome / Opera / Firefox

IE 6: По крайней мере background остается фиксированным

IE 7/8: Множество работ не центрируются на малых размерах, но заполняет экран лучшим образом

IE 9: Работает

2 — Метод

Еще один простой способ реализовать это, вставить картинку на страницу. Она будет иметь фиксированную позицию и будет размещена в верхнем левом углу. Мы присвоим ей min-width и min-height 100%. Также нужно заранее подготовить картинку, в плане пропорциональности сторон.

 

<img src="images/bg.jpg" id="bg" alt="">

 

 

#bg {
        position:fixed;
        top:0;
        left:0; 
 
        /* Preserve aspet ratio */
        min-width:100%;
        min-height:100%;
}

 

Хотя, этот код не центрирует background image. Поэтому, сейчас мы это исправим… Мы можем фиксировать картинку с помощью взятия ее в div.

 

<div id="bg">
        <img src="images/bg.jpg" alt="">
</div>

 

 

#bg {
        position:fixed;
        top:-50%;
        left:-50%;
        width:200%;
        height:200%;
}
#bg img {
        position:absolute;
        top:0;
        left:0;
        right:0;
        bottom:0;
        margin:auto;
        min-width:50%;
        min-height:50%;
}

 

Кроссбраузерность:

Safari / Chrome / Firefox (не тестировалось на более древних версиях)

IE 8+

Opera (любые версии) и IE отображают одинаково (плохо позиционируют, не пойму почему)

Растянуть background с помощью jQuery

Эта идея появилась немного ранее (как альтернатива CSS методу). Если мы будем знать пропорции и размер картинки, мы сможем растянуть background на CSS. Если картинка меньше окна браузера, мы изменим width на 100% для картинки. Если больше, мы можем установить только height 100% и знать, что картинка заполнит все как по ширине, так и по высоте.

Мы можем получить доступ к нужным данным с помощью JavaScript. Как и все, я использую фреймверк jQuery.

 

<img src="images/bg.jpg" id="bg" alt="">

 

 

#bg { position: fixed; top: 0; left: 0; }
.bgwidth { width: 100%; }
.bgheight { height: 100%; }

 

 

$(window).load(function() {    
 
        var theWindow        = $(window),
            $bg              = $("#bg"),
            aspectRatio      = $bg.width() / $bg.height();
 
        function resizeBg() {
 
                if ( (theWindow.width() / theWindow.height()) < aspectRatio ) {
                    $bg
                        .removeClass()
                        .addClass('bgheight');
                } else {
                    $bg
                        .removeClass()
                        .addClass('bgwidth');
                }
 
        }
 
        theWindow.resize(function() {
                resizeBg();
        }).trigger("resize");
 
});

 

Здесь не реализовано центрирование, но вы с легкостью можете сделать это.

Кроссбраузерность:

IE7+

И все другие популярные браузеры

Растягиваем background с помощью PHP

Собственно, PHP мы можем использовать для одной цели: обработки изображения с помощью GD библиотеки. Ранее я рассказывал о том, как сделать скрипт превью картинок. В этом случае его можно использовать для изменения размера изображения на лету. Но возникает проблема, изображение будет генерироваться при каждом обращении к сайту. Для большого проекта это слишком ресурсоемко. Лучше будет сделать готовые заготовки изображений, соответственно самым популярным разрешениям экранов (1024 x 1280, 1280 x 800…), используя фотошоп это не сложно. В случае, если разрешение экрана будет другим, это единичные случаи, мы подключим скрипт автоматического изменения размера. Он подключается следующим образом:

 

$(function() {
  h = $(window).height();
  w = $(window).width();
  $(body).style('background','url(phpthumb.php?src=bg.jpg&w='+w+'&h='+h);
});

 

Наслаждайтесь!

Это все известные мне способы, как растянуть background на весь экран. Если вы делаете это иначе, будьте добры опишите это в комментариях. Буду рад узнать о новых вариантах растягивания background с помощью css и других техник. Творческих вам успехов!
 


Дальше: Счетчик скачиваний файла на PHP & MySQL

Установка phpmyadmin (Ubuntu) и Установка, изменение и сброс пароля root в MySQL

Когда ставим phpmyadmin в конце просит пароль MYSQL если он пустуй то ощибка, выставить пароль ниже в статье

 

Итак, ставим phpmyadmin:

sudo apt-get install phpmyadmin

Если у вас в репозитории свежий пакет phpmyadmin, то в процессе установки он спросит пароль для доступа к бд mysql (там он создает свои таблицы с настройками) и логин и пасс для своего постоянного использования.

Перезапускаем апач

sudo /etc/init.d/apache2 restart

проверяем:

===========

 

Сменить пароль mysql

cmd
mysql

mysql -u root или с паролем mysql -u root -p
mysql> use mysql;
mysql> UPDATE user SET Password = PASSWORD('mypassword') WHERE User = 'root';
mysql> FLUSH PRIVILEGES;

Построение дерева из БД на PHP №4

Недавно меня спросили, как в PHP быстро построить дерево на основе выборки из базы данных (MySQL). Пусть дерево в PHP должно храниться в виде вложенных массивов. Исходная таблица, содержит минимум три колонки — id (первичный ключ), parent_id (ключ родителя) и value (собственно данные). Буду считать, что id>0 и parent_id>0 (или parent_id=0 для корневых элементов). Может получиться даже не дерево, а целый лес, если есть несколько корневых элементов. Обычный подход к построению дерева — рекурсивная функция. Самое худшее, что делают программисты — для каждого уровня рекурсии функция делает запрос к БД, чтобы выбрать всех детей текущего элемента. Пожалуй, стоит написать небольшую «СУБД» для примеров:

class FakeDB
{
    public static $querys=0;
    public function fetchAll($q)
    {
        ++FakeDB::$querys;
        $rs=array (
            array('id'=>1, 'parent_id'=>0, 'value'=>'aaaa'),
            array('id'=>2, 'parent_id'=>0, 'value'=>'bbbb'),
            array('id'=>3, 'parent_id'=>1, 'value'=>'cccc'),
            array('id'=>4, 'parent_id'=>2, 'value'=>'dddd'),
            array('id'=>5, 'parent_id'=>2, 'value'=>'eeee'),
            array('id'=>6, 'parent_id'=>5, 'value'=>'ffff'),
            array('id'=>7, 'parent_id'=>6, 'value'=>'gggg'),
            array('id'=>8, 'parent_id'=>6, 'value'=>'hhhh')
        );
        if (preg_match('|WHERE\s+parent_id\s*=\s*(\d+)|i', $q, $m)) {
            foreach ($rs as $key=>$val) {
                if ($val['parent_id'] != $m[1]) {
                    unset($rs[$key]);
                }
            }
        }
        return $rs;
    }
}

«СУБД» не отличается умом и сообразительностью, но умеет делать вид, что немного понимает SQL (а мы делаем вид, что ей верим, ага). Она умеет «извлекать» данные из захардкоженной «таблицы», либо всё и сразу, либо по условию «where parent_id=nnn», данные отсортированы по parent_id, а затем по id. И еще она умеет считать количество запросов за сеанс. Этого достаточно, чтобы успешно делать вид, что используются SQL запросы и, что характерно, в рамках примеров получать правильные «выборки».
Все последующие примеры используют этот класс, поэтому он должен быть подключен или добавлен к их коду, чтобы они работали (я опустил этот момент для краткости).

Итак, рекурсивное построение дерева — это что-то вроде:

function RecursiveTree1($parent)
{
    $out = array();
    $db = new FakeDB();
    $rs = $db->fetchAll("SELECT * FROM my_table WHERE parent_id=$parent");
    foreach ($rs as $row) {
        $chidls = RecursiveTree1($row['id']);
        if ($chidls) {
            $row['childs'] = $chidls;
        }
        $out[]=$row;
    }
    return $out;
}
print_r(RecursiveTree1(0));
echo "querys=", FakeDB::$querys;

Девять запросов на таблицу из 8 строк, и все такое.

Можно извлечь все данные сразу, одним запросом и попробовать обработать его уже на PHP. Вот немного модифицированная версия:

$db=new FakeDB();
$rs = $db->fetchAll("SELECT * FROM my_table");
$rs2 = array();
foreach ($rs as $row) {
    $rs2[$row['parent_id']][] = $row;
}
 
function RecursiveTree2(&$rs,$parent)
{
    $out = array();
    if (!isset($rs[$parent])) {
        return $out;
    }
    foreach ($rs[$parent] as $row) {
        $chidls = RecursiveTree2($rs, $row['id']);
        if ($chidls) $row['childs'] = $chidls;
        $out[] = $row;
    }
    return $out;
}
print_r(RecursiveTree2($rs2 ,0));
echo "querys=", FakeDB::$querys;

Запрос один, массивов несколько, для простоты и удобства я произвел преобразование исходной выборки в двумерный массив, сгруппировав по родителю.

А можно ли обойтись без рекурсии? Разумеется можно, потому что любую рекурсию можно развернуть в цикл, только радости от этого мало. Вопрос надо поставить по-другому. А можно ли построить дерево произвольной вложенности за один проход по исходным данным? Чтобы просто и быстро, без рекурсий и вложенных циклов? Это потребует некоторой организации исходных данных. Исходные данные должны быть отсортированы по уровню вложенности. Это очевидное требование для гарантии того, что, спускаясь линейно сверху вниз по выборке, нам никогда не попадется ребенок раньше своего родителя (в этом случае его просто еще некуда будет прицепить в массиве). Если предположить, что дети создаются всегда позже своих родителей и имеют id всегда больше parent_id (это бывает справедливо, когда деревья создаются человеком, ручками в визуальном интерфейсе, и потом элементы не перемещаются в другие ветки), то достаточно упорядочить элементы по parent_id.

Единственная проблема заключается в том, что в дереве (многомерном массиве с произвольными вложенностями) найти элемент с заданным id, чтобы прицепить к нему очередного ребенка, не так легко как бы хотелось. Например, попался элемент с parent_id=6, как теперь понять, что его папочка (в случае таблицы из примеров) имеет путь в дереве: $x[1]['childs'][1]['childs'][0]? Логично было бы иметь вспомогательный массив, где ключом будет id каждого элемента, а значением нечто, что укажет его положение конечном в дереве. Но как хранить пути?

На самом деле все немного проще. Достаточно вспомнить, что на любую переменную всегда можно сделать ссылку. Именно она (ссылка) и должна храниться во вспомогательном массиве. С этого момента о дереве и путях можно не думать. Все становится действительно линейно. Для большей выразительности я даже не буду использовать функцию:

$db = new FakeDB();
$rs = $db->fetchAll("SELECT * FROM my_table");
$tree = array(0=>array('id'=>0, 'parent_id'=>0, 'value'=>'root'));
$temp = array(0=>&$tree[0]);
 
foreach ($rs as $val) {
    $parent = &$temp[ $val['parent_id'] ];
    if (!isset($parent['childs'])) {
        $parent['childs'] = array();
    }
    $parent['childs'][$val['id']] = $val;
    $temp[$val['id']] = &$parent['childs'][$val['id']];
}
unset($rs, $temp, $val, $parent);
print_r($tree[0]['childs']);
echo "querys=", FakeDB::$querys;

Последний вопрос, который лично у меня остался — а зачем вообще строить такое дерево, если потом нет никакой удобной возможности, его обойти? Если для его обхода потребуется очередная рекурсивная процедура? Вопрос для меня открыт.

 

15 комментариев: Построение дерева из БД на PHP

  1.  
  2. dwork говорит:

    вот как я рисую дерево

    SELECT ID, ParentID, Title FROM Tree;

    while($row = mysql_fetch_assoc($res))
    $tree[$row[ParentID]][$row[ID]] = $row[Title];}
     
    function ShowTree($tree, $pid=0)
    {
      echo ;
      foreach( $tree as $id => $root)
      {
        if($pid!=$id)continue;
        if(count($root))
        {
          foreach($root as $key => $title)
          {
            echo {$title};
            if(count($tree[$key]))ShowTree($tree,$key);
          }
        }
      }
      echo ;
    }

  3. Саня Чуев говорит:

    Моё решение:

    function array_tree ($array, $id = 'id', $parent_id = 'parent_id', $children = 'children') {

    $tree = [[$children => []]];

    $references = [&$tree[0]];

    foreach ($array as $item) {

    if (isset ($references[$item[$id]])) {

    $item[$children] = $references[$item[$id]][$children];

    }

    $references[$item[$parent_id]][$children][] = $item;

    $references[$item[$id]] =& $references[$item[$parent_id]][$children][count($references[$item[$parent_id]][$children]) — 1];

    }

    return $tree[0][$children];

    }

Понравилось? Поделись!

Простейшее дерево каталогов на MySQL и PHP №3

 

Дерево каталогов на MySQL и PHPСтолкнулся с проблемой построения дерева каталогов на MySQL и PHP. Долго искать не пришлось, поиск сразу подсказал пару хороших статей. Но при их разборе выяснилось что они «слегка» устарели и код из них вообще не захотел работать. Более того они были сильно запутаны. Немного подумав я решил написать свое дерево. О нем то я и напишу сегодня.

С чего начнем?

Ну начнем мы с Базы данных, в таблице у нас будет 3 поля:

  • id_tree — id каталога
  • id_family — id родительского каталога
  • name_tree — имя каталога

Дамп:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CREATE TABLE IF NOT EXISTS `tree` (
  `id_tree` INT(5) NOT NULL AUTO_INCREMENT,
  `id_family` INT(5) NOT NULL DEFAULT '0',
  `name_tree` VARCHAR(255) NOT NULL,
  PRIMARY KEY (`id_tree`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=10 ;

INSERT INTO `tree` (`id_tree`, `id_family`, `name_tree`) VALUES
(1, 0, 'Folder 1'),
(2, 0, 'Folder 2'),
(3, 0, 'Folder 3'),
(4, 2, 'Folder level 2'),
(5, 2, 'Folder level 2'),
(6, 4, 'Folder level 3'),
(7, 4, 'Folder level 3'),
(8, 0, 'Folder 4'),
(9, 0, 'Folder 5');

Итак, а теперь наши php файлы, начнем с конфига conf.php

1
2
3
4
5
6
7
8
9
10
<?php
define ('DB_HOST', 'localhost');
define ('DB_LOGIN', '***');
define ('DB_PASSWORD', '***');
define ('DB_NAME', '***');
$mysql_connect = mysql_connect(DB_HOST, DB_LOGIN, DB_PASSWORD) or die("MySQL Error: " . mysql_error());
mysql_connect(DB_HOST, DB_LOGIN, DB_PASSWORD) or die ("MySQL Error: " . mysql_error());
mysql_query("set names utf8") or die ("<br>Invalid query: " . mysql_error());
mysql_select_db(DB_NAME) or die ("<br>Invalid query: " . mysql_error());
?>

Теперь файл с выводом дерева tree.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
include_once('conf.php');
include_once('function.php');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
  <link rel="stylesheet" href="/style.css" />
  <title>testing directory tree</title>
</head>
<body>
<div class="page">
  <div class="tree">
  <?php
  view_tree();
  ?>
  </div>
</div>

</body>
</html>

Все очень удобно и вывод дерева каталогов мы делаем выводом 1 функции, но для начала подключаем файл с конфигом и функциями.

Ну и самое интересное у нас в файле function.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
  function view_tree() {
    $query = mysql_query("SELECT * FROM `tree`") or die("Извините, произошла ошибка");
    while ($row = mysql_fetch_row($query)) {
      if ($row[1] == '0') {
        $one_lvl[] = array ($row[0], $row[1], $row[2]);
      } else {
        $next_lvl[] = array ($row[0], $row[1], $row[2]);
      }
    }
    print '<ul class="tree_lvl_1">';
    foreach ($one_lvl as $key){
      print '<li><a href="/?'.$key[0].'">'.$key[2].'</a>';
    view_tree_next_level($key[0], $next_lvl);
      print '</li>';
    }
    print '</ul>';
  }


  function view_tree_next_level($family, $next_lvl) {
    foreach ($next_lvl as $key) {
      if ($key[1]==$family) {
        print '<ul class="tree_lvl_2"><li><a href="/?'.$key[0].'">'.$key[2].'</a>';
        view_tree_next_level($key[0], $next_lvl);
        print '</li></ul>';
      }
    }
  }
?>

Итак разберем работу этих функций.

view_tree

Первое что мы делаем это обращаемся к базе данных за данными. А вот далее на 5 строке мы делаем отбор на 2 массива, в $one_lvl мы отбираем все корневые каталоги ( с них мы начнем вывод дерева ) а в $next_lvl мы кладем все остальные каталоги.
В 11 строке мы просто делаем вывод ul для создания списка, далее в 12 мы приходимся по массиву, выводим корневой каталог и вызываем функцию куда передаем id корневого каталога и массив $next_lvl.

А теперь разберем вторую функцию которая отвечает за вложенные каталоги.

view_tree_next_level

На самом деле все просто, мы проходим по массиву в поисках записей у которых id_family совпадает с id_tree. Далее мы выводим эту запись и вызываем эту же функцию для вывода вложенных каталогов в уже вложенный…

Ну и на этом вроде все… Ах да, немного украсим

style.css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
body, html {
  margin:0px;
  padding:0px;
  width:100%;
  height:100%;
  background-color:#c9c9c9;
  font-family:Verdana;
  font-size:12pt;
}

.tree {
  margin:10px 10px 10px 10px;
  width:40%;
  display:inline-block;
  float:left;
}

.tree_lvl_1 {
  padding-left:20px;
  list-style-image:url("desing/1299993783_folder.gif");
}

.tree_lvl_1 a {
  COLOR: #000; TEXT-DECORATION: none;
}
.tree_lvl_1 a:link {
  COLOR: #000; TEXT-DECORATION: none;
}
.tree_lvl_1 a:hover {
  COLOR: #0a0aa1; TEXT-DECORATION: none;
}
.tree_lvl_1 a:unknown {
  COLOR: #000; TEXT-DECORATION: none;
}

.tree_lvl_2 {
  padding-left:24px;
  margin-left:-12px;
  margin-top:-3px;
  list-style-image:url("desing/folder_2.gif");
  border-left:1px solid #000;
}

Теперь действительно все, пользуйтесь ;)

Иерархическое дерево на php №2

Достаточно часто есть необходимость рекурсивно обойти таблицу данных и построить рекурсивное(или иерархическое) дерево на php.
Рассмотрим простейший пример вызова рекурсивной функции и построения иерархического дерева.
Создаем таблицу и дампим данные

CREATE TABLE IF NOT EXISTS `tree` (
`id` int(100) NOT NULL AUTO_INCREMENT,
`parent_id` int(100) NOT NULL,
`title` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=UTF-8 AUTO_INCREMENT=11 ;
 
--
-- Дамп данных таблицы `tree`
--
 
INSERT INTO `tree` (`id`, `parent_id`, `title`) VALUES
(1, 0, 'первый'),
(2, 0, 'второй'),
(3, 0, 'третий'),
(4, 2, 'во втором'),
(5, 2, 'во втором1'),
(6, 2, 'во втором2'),
(7, 2, 'во втором3'),
(8, 3, 'подпункт'),
(9, 6, 'подпункт2'),
(10, 6, 'подпункт3');

 

Делаем один единственный запрос.

$result=mysql_query("SELECT id, parent_id, title FROM tree");
$cats = array();
while($cat = mysql_fetch_assoc($result))
$cats[$cat['parent_id']][] = $cat;
 
function build_tree($cats,$parent_id){
if(is_array($cats) and count($cats[$parent_id])>0){
$tree = '<ul>';
foreach($cats[$parent_id] as $cat){
$tree .= '<li>'.$cat['title'];
$tree .= build_tree($cats,$cat['id']);
$tree .= '</li>';
}
$tree .= '</ul>';
}
else return null;
return $tree;
}
echo build_tree($cats,0); // :)))