Избранное

9 июня 2010, 10:18

Сравнение таблиц в двух БД (и больше) Избранное

Когда дохера работы, начинаешь страдать такой ерундой :)
Раз в несколько месяцев приходится сравнивать БД, и каждый раз в ручную. Один даже раз софт сутки искал, но он ужасен, весь. Немного пострадав, минут 30, получился такой код:
  • собираем всё в масcив;
  • выводим всё красиво в табличках;
  • подключаем jQ и делаем удобную «обёрточку»;
  • ...
  • Profit
<?php
  $user  = "root";
  $userp = "";
  mysql_connect("localhost", $user, $userp) or die(mysql_error());
	$table2compare = array("test1", "test2");
	$comparedtables = array(); $i = 0;
  foreach ($table2compare as $tablename){
  	$comparedtables["title"][$i] = $tablename;
    $db = mysql_query("SHOW TABLES IN $tablename");
    while($dbt = mysql_fetch_array( $db )){
      $table = mysql_query("SHOW COLUMNS FROM $dbt[0] FROM $tablename ");
      while($tbf = mysql_fetch_array( $table ))
      	$comparedtables["tables"][$dbt[0]][$i][] = $tbf;
    }
    $i++;
  }
	echo "<table><tr>";
	for ($j = 0; $j < $i; $j++) 
		echo "<td>".$comparedtables["title"][$j]."</td>";
	echo "</tr>";
	foreach ($comparedtables["tables"] as $table => $fields) {
		echo "<tr>";
		for ($j = 0; $j < $i; $j++) {
			if ($j > 0) $eq = $fields[$j] == $fields[0]; else $eq = true;
			echo "<td valign='top' ".(!$eq ? "style='background: #fcc;'" : "").">";
			if (empty($fields[$j])) continue;
			echo "<span>$table</span><br><table rules=all frame=box cellpadding='2'>
            <tr>
            	<td>Field</td>
            	<td>Type</td>
            	<td>Null</td>
            	<td>Key</td>
            	<td>Default</td>
            	<td>Extra</td>
            </tr>";
  		foreach ($fields[$j] as $field)
	      echo "<tr>
	      				<td>$field[0]</td>
	      				<td>$field[1]</td>
	      				<td>$field[2]</td>
	        			<td>$field[3]</td>
	        			<td>$field[4]</td>
	        			<td>$field[5]</td>
	        		</tr>";
      echo "</table></td>";
    }
    echo "</tr>";
  }
  
  echo "</table>";
  mysql_close();
?>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
<script type="text/javascript">
	$(function(){
	  $("table table").hide();
	  $("table span").click(function(){
	  	$(this).next().next().toggle();
	  }).css({"cursor":"pointer"});
	});
</script>

8 декабря 2009, 15:44

Хохохо, miniJquery 0.0.1.3a Избранное

Как и обещал
  • декрементные циклы
  • лёгкая оптимизация
  • добавить простейшую рекурсию, для более вложенных запросов (запросы через запятую — селектор отдельной функцией);
  • добавить методы / выкинуть второй параметр ( chains );
  • расширить функционал изменением стилей;
Ограничения (поддерживает только двухуровневый запрос):
  • .класс
  • тэг.класс
  • #конетйнер .класс
  • #конетйнер тэг.класс
  • #конетйнер тэг
  • допустимый запрос, допустимый запрос
  • всё остальное идёт боком ;)
Планы на будующее:
  • расширение функционала селектора tinyCSSSelector (inputs, сложные многоуровневые)
  • Подключение других селекторов (yass, sizzle)
  • добавить новых функций разных (самые часто используемые мной в джиквери)
  • добавить простейшие обработчики событий (click, mouse)
  • добавить поддержку частных(custom) функций
  • сделать each
  • добавить простейшую анимацию (по определённым свойствам)
  • кеширование о_О



1 декабря 2009, 9:14

HabraAlert 0.2 Избранное

Возникло много багов и пожеланий, поэтому переделал:
  • Исправил CSS ошибки, добавил pointer: cursor;
  • Разделил CSS для ИЕ и остальных;
  • Исправил багу с позиционированием в ИЕ6;
  • Избавился от js.ошибки NS_ERROR_DOM_NOT_FOUND_ERR
  • Сделал возможности загрузки скрипта как в head так и в body;


23 ноября 2009, 15:59

Установка и настройка eAccelerator на linuxе :) (install and configure) Избранное

Давно ничего системненького не писал, но недавно пришлось несколько раз устанавливать акселератор, и каждый раз приходилось гуглить, вот решил шпору себе накатать ;)

Установка.
  • логинимся через пути на свой сервак (должен быть root)
  • сидя в хомяке (cd ~) создаём папку tmp (mkdir tmp) и переходим в неё (cd tmp)
  • дальше нужно скачать последний акселератор (wget httр://lastea.link/)
  • распаковываем его (tar xjvf eaccelerator-0 тут нажать tab)
  • выполняем phpize (если phpize: command not found, делаем apt-get install php5-dev, и опять phpize)
  • конфигурим (./configure)
  • компилим (make)
  • инсталим к php (sudo make install)
  • находим php.ini и дописываем вконец
    extension="eaccelerator.so"
    // размер кеша, обычно достаточно 32, если сайтов много то 64
    eaccelerator.shm_size="64"
    // путь к папке кеша, доступ к которой должен быть 777
    eaccelerator.cache_dir="/var/cache/eaccelerator"
    eaccelerator.enable="1"
    eaccelerator.optimizer="1"
    eaccelerator.check_mtime="1"
    eaccelerator.debug="0"
    eaccelerator.filter=""
    eaccelerator.shm_max="256"
    eaccelerator.shm_ttl="3600"
    eaccelerator.shm_prune_period="1800"
    eaccelerator.shm_only="0"
    eaccelerator.compress="1"
    eaccelerator.compress_level="9"
    // путь к папке, где будет лежать control.php что шёл с архивом еА
    eaccelerator.allowed_admin_path="/home/http/cache"
  • рестартуем апачик (sudo /etc/init.d/apache2 restart)
  • смотрим запустилось ли :), если нет, значит на php выделено мало памяти, выделяем (echo «134217728» > /proc/sys/kernel/shmmax)
Вот и всё! Удачной оптимизации ;)

19 ноября 2009, 9:14

Hard Javascript: Chain Fucntions (jQuery style) -> Функции цепочками Избранное

Давно хотел разобраться с функциями через точечку, то есть с теми, что по цепочке, как в любимом jQuery. В самом коде jQuery можно сломать голову, потому искал просветления в инете, и довольно безрезультатно, пока не наткнулся на маленькую либу $fx для анимации, и на меня сошло озарение.

Всё довольно просто и через замыкание функции в конце:
$ = function(v) {
	if (v.nodeType && v.nodeType == 1) var f = v;
	else if (typeof v == "number") {
		var f = {"result":v};
	} else return null;
  f.plus = function (nmbr) {
  		nmbr = nmbr || this.result;
  		this.result += nmbr;
      return this;
  };
  f.minus = function (nmbr) {
  		nmbr = nmbr || this.result;
  		this.result -= nmbr;
      return this;
  };
  f.multiply = function (nmbr) {
  		nmbr = nmbr || this.result;
  		this.result *= nmbr;
      return this;
  };
  f.divide = function (nmbr) {
  		nmbr = nmbr || this.result;
  		this.result  /= nmbr;
      return this;
  };	    
  return f;
}
Вкратце, проверяем первый аргумент:
  • если функция (объект, без разницы в JS), присваиваем к главной функции с подлепрамифункциями(нодами)
  • если число, то создаём объект с параметром result
  • дальше следует замыкание через «return f»;
Что бы получить результат, пишем всё вот так:
$(10).plus(5).minus(7).divide(2).multiply(3).result


25 августа 2009, 11:10

CSS: Плавающие блоки с разной высотой, с выравниванием в ряду по самому высокому Избранное

Иногда когда делаем блоки с float:left, приходится сталкиваться с блоками разной высоты, и они при переходе на новую строчку, начинают строится после самого высокого, что ужастно... И приходится или ставить после определённого количества br clear=’all’ или указывать фиксированую высоту, что не всегда приемлемо.

Этот вопрос можно решить всего-лишь сэмулировав display:inline-block для старых ИЕ и для старых фоксов, ниже 3
.gallery-item {
    border-top:1px solid #AAAAAA;
    width: 147px;
    *width:147px;
    display: -moz-inline-stack; /* для FF ниже 3  */
    display:inline-block;
    font-size:91%;
    margin: 0 24px 20px 0;
    min-height:178px;
    vertical-align:text-top;
    border:1px solid #797873;

    /* уголки, ля-ля-ля */
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;

    padding: 5px 5px 0;
    color: #4b4c4c;
    zoom:1; /* обычный layout fix для ИЕ6 */
    *display:inline; /* для ИЕ 6, 7 */

}


13 августа 2009, 11:06

CSS: самый простой футер, приклееный вниз (Crossbrowser bottom fixed footer) Избранное

Давно использую данный «текникс», а на хабре говорят что про него никто не слышал. Странно, вооот. Поэтому встречайте ;)

Нужен простенький CSS. Мы зададим высоту html, body и враппера 100%, маргин у враппера сделаем -4строки, а футеру сделаем высоту +4строки соот. и получим нужный результат:
* {margin: 0;}
html, body {height: 100%;}
.wrapper {
    min-height: 100%;
    /* luv IE shit */
    height: auto !important;
    height: 100%;
    margin: 0 auto -4em;
}
.footer, .push {height: 4em;}
Вместо строк, можем использовать пиксельные величины, также не забываем о паддингах и бордерах, он тоже играют на высоту/длину!
И HTML
<body>
    <div class="wrapper">
        <p>Your website content here.</p>
        <div class="push"></div>
    </div>
    <div class="footer">
        <p>Copyright/contacts put here</p>
    </div>
</body>


ЗЫ: див под именем push, нужен для глючных браузеров, лайк Опера, что бы текст футера не налазил на контент.
ЗЗЫ: заставить оперу понимать то, что хавает даже ИЕ6, можно скриптом. Или убить доктайп, или сместить боди на 1px, что реализовано в примере ;)

27 июля 2009, 23:59

Hard JavaScript: декораторы (decorators) Избранное

Декоратор — образно говоря, это нечто, что оборачивает другое нечто %))) Вот например есть функция и мы можем создать для неё декоратор, который будет запускать какую-то другую функцию в начале или в конце выполнения «родителя». Для чего-же?: вариантов миллион ;) Например для проверки данных, если этой проверки ранние не было, или для логгирования, дебагинга, или для изменения общего поведения ;)


Перейдём к делу %) Создадим помощник, который будет нам помогать делать чудеса.
Function.prototype.method = function(methodName, f) {
  if (typeof f != "undefined")
    this.prototype[methodName] = f;
  return this.prototype[methodName];
}
Что-что? Спросите вы! Образно говоря, мы легко добавляем новый (если существует, возвращаем старый) метод (функцию) в прототип заданной функции о_О Прототип?? Хе-хе! Прототип — это свойства и методы функции, класса, массива, любого объекта, которые существуют по умолчанию. :D Да, они ограничены (прелести в прототипе), и их есть стандартный набор, потому мы можем их добавлять переназначать или удалять ;)


Приступим к декораторам ;)
// Теперь мы можем достать как ближайшую "украшенную" ф-цию, так и самую первую в цепочке
Function.method("restore", function(fullRestore){
  var ret = this.old || this;
  while (fullRestore && ret.old) {
    ret = ret.old;
  }
  return ret;
})
// специально для декорирования методов, востановления имён
Function.method("decorateMethod", function(methodName, decorator){
  var f = this.method(methodName);
  if (!f)
    return null;
  f.name = methodName;
  f = f.decorate(decorator);
  return this.method(methodName, f);
})
Function.method("decorate", function(decorator){
  // Сохраняем исходную функцию
  var oldFunc = this;
  // Важно! теперь возможно нормальное пере-использование одного и того же декоратора.
  // Теперь мы его никак не трогаем и не изменяем, а создаём и возвращаем новую ф-цию.
  // Однако теперь декоратор первым аргументом всегда будет получать некий объект,
  // в котором -- original: oldFunc (оригинал) и decoratorInstance: f (настоящий декоратор)
  var f = function(){
    return decorator.apply(this, 
    [{original: oldFunc, decoratorInstance: f}].concat([].slice.apply(arguments)))
  }
  // Сохраняем оригинал ф-ции - в decoratorInstance f
  f.old = oldFunc;
  // Восстанавливаем прототип и конструктор ф-ции.
  // Это необходимо для сохранения ф-ции как конструктора.
  f.prototype = this.prototype;
  f.prototype.constructor = f;
  // Восстанавливаем имя ф-ции. Откуда оно вообще берётся? Можно задать вручную.
  // Или см. выше, новый метод decorateMethod: в нём это задаётся.
  f.name = oldFunc.name;
  // возвращаем декоратор
  return f;
})
Всем понравилось, теперь пример
// Простая функция-декоратор		
function docwrite() {
	var types = arguments; // передаём типы
	return function(dScope) {
		// получаем аргументы родителя (воруем)
		var original = arguments[0].original; // или можно dScope.original
		var arguments = Array.prototype.slice.call(arguments, 1);
		var params = arguments;
		// выводим наш текст, который мы алертим
		document.write(params[0]);
		
		// незабываем позвать родителя, а то не красиво ;)
		return original.apply(this, arguments);
		// в результате видем ещё и алерт
	}
}
// надеваем декоратор на алерт
alert = alert.decorate(docwrite());
Дальше в body пишем
<script type="text/javascript">
  alert("y0");
</script>



Теперь бонусы
// Кикнуть декоратор можно так ;)
Function.method("recover", function() {
  return this.old || this;
})
// Повесить обработку "до"
Object.method('before', function(methodName, f){
  var method = listenerInit.call(this, methodName);
  if (method)
    method.listenersBefore.push(f);
})
// Повесить обработку "после"
Object.method('after', function(methodName, f){
  var method = listenerInit.call(this, methodName);
  if (method)
    method.listenersAfter.push(f);
})
// что бы повесить декоратор "до" и "после", нам нужен вот такой обработчик (слушатель)
function listenerInit(methodName) {
  var method = this[methodName];
  if (typeof method != "function")
    return false;
  
  // продекорировано, или ещё нет?
  if (!method.listenable) {
    this[methodName] = method.decorate(function(){
      var decorator = arguments.callee;
      decorator.listenable = true;
      
      var list = decorator.listenersBefore;
      for (var i = 0, l = list.length; i < l; i++) {
        if (typeof list[i] == "function" && list[i].apply(this, arguments) === false)
          return;
      }
      
      var ret = decorator.old.apply(this, arguments);
      list = decorator.listenersAfter;
      for (var i = 0, l = list.length; i < l; i++)
        list[i].apply(this, arguments);
        
      return ret;
    });
    method = this[methodName];
  }
  
  method.listenersBefore = method.listenersBefore instanceof Array ? method.listenersBefore : [];
  method.listenersAfter = method.listenersAfter instanceof Array ? method.listenersAfter : [];
  
  return method;
}


16 мая 2009, 15:17

PHP File Manager Избранное

Иногда, после того, как скрипт на сервере создаст какой-то файл, или распакует архив, мы не можем получить доступ по фтп к этому же файлу, а нам нужно срочно его обновить! Да ещё нету доступа к си-панели, или любой другой панели хостинга.

На помощь приходит любой PHPFileManager. Если поискать через google, то их можно найти очень-очень много, но многие из них убоги по функционалу, а другие уж очень громоздкие.

Меня интересовали только три критерия:
  • функциональность
  • Доступ к командной строке, средствами php
  • весь менеджер в одном файле
После хорошо десятка менеджеров, выбор пал на скрипт с таким же названием PHPFileManager %) Тем более он free!!

Работать с ним легко и просто, скачиваете архив, один его файлик замысловато переименовываете и бросаете где-то на хостинг по фтп ;) а дальше карты в руки!



ЗЫ: простой хинт, что бы изменить права на все файлы и папки в каталоге, используйте для chmod флаг -R, например
 chmod -R 777 templates/* 

14 апреля 2009, 10:30

Универсальный IE6 png fix Избранное

Перерыл пол интернета в поисках этого «пнгфикса», вариаций более-менее достойных было с 10, но на сложной вёрстке они убивали дизайн полностью, и фиксили не до конца, кроме одного!

Представляю, это DD_belatedPNG (сейчас версия 0.0.7альфа но он уже может всё!) и как они говорят, это «Medicine for your IE6/PNG headache!»



Что же он может:

  • фиксить все png, как просто картинки (<img>) так и динамически вставляемые;
  • фиксить все фоновые png (как одиночные так и повторяющиеся) для любых тегов, при этом нормально обрабатывается background-position and background-repeat;
  • фиксить инпут в виде картинки (<INPUT type=«image»/>);
  • Автоматически добавляет позишон:релейтив (для ИЕ6 очень важно);
  • не использует картинки (blank1px.gif) для фиксов и технологию ДиректИкса (filter:progid:DXImageTransform.Microsoft.AlphaImageLoader), то есть нужен только джаваскрипт! Использует технологию MS, что называется VML (//Vector Markup Language//);
  • после фикса, у всех элементов сохраняется кликабельность;
  • не нужно уродовать css с помощью **behavior: url**
  • + он фиксит :hover для ИЕ6!


Есть одно но! К тегам <TR> и <TD> лучше не применять ;) да и вообще кому нужна вёрстка на таблицах ;)

Рецепт:
Скачайте Джаваскрипт, положите в корень сайта например и подключаете
<!--[if IE 6]>
<script src="DD_belatedPNG.js"></script>
<script>
  /* EXAMPLE */
  DD_belatedPNG.fix('.png_bg');
  
  /* string argument can be any CSS selector */
  /* .png_bg example is unnecessary */
  /* change it to what suits you! */
</script>
<![endif]-->


Подключаете только для ИЕ6, и только для нужных элементов! Оптимизирован для ИЕ6! Может выбирать как по классам, так и по айди, так и просто по тегам, кому как удобно! Например я использовал такое подключение %) DD_belatedPNG.fix(img, div, li, a);, так как дизайн был полностью из пнгшек!

зы: DD_belatedPNG is free software under the MIT License.
ззы: Кто не хочет нагружать страницу каким-либо джаваскриптом, для того есть ещё один метод, и называется он



25 марта 2009, 13:29

Тире, минус, перенос %) Избранное

Просто для себя, очень часто нужно скопировать %)
Итак, девять различных чёрточек:
ЗнакHTMLНазваниеНазначение и употребление
- - дефисоминус вместо всех остальных чёрточек при отсутствии технической возможности
&#x2010; дефис для разделения частей слова: «светло‐серый», «по‐моему», «кое‐кто» и т. п.
&minus; минус математические выражения: 2 − 3 = −1
&#x2012; цифровая чёрточка номера телефонов и другие цифровые коды
­ &shy; символ переноса в (длинных) словах в тех местах, где можно сделать перенос
&#x2043; чёрточный буллит маркер списка
&ndash; короткое тире западная типографика
&mdash; длинное тире русская типографика
&#x2015; горизонтальная черта диалоги (в западной типографике)

И, для сравнения, в одной строке: - ‐ − ‒ ­ ⁃ — — ―

12 марта 2009, 5:08

Конвертация кириличной строки (Cyrillic UTF8) в транслит Избранное

Это обновлённый вариант
function Transliterate($string){
  $cyr=array(
     "Щ", "Ш", "Ч","Ц", "Ю", "Я", "Ж","А","Б","В",
     "Г","Д","Е","Ё","З","И","Й","К","Л","М","Н",
     "О","П","Р","С","Т","У","Ф","Х","Ь","Ы","Ъ",
     "Э","Є", "Ї","І",
     "щ", "ш", "ч","ц", "ю", "я", "ж","а","б","в",
     "г","д","е","ё","з","и","й","к","л","м","н",
     "о","п","р","с","т","у","ф","х","ь","ы","ъ",
     "э","є", "ї","і"
  );
  $lat=array(
     "Shch","Sh","Ch","C","Yu","Ya","J","A","B","V",
     "G","D","e","e","Z","I","y","K","L","M","N",
     "O","P","R","S","T","U","F","H","", 
     "Y","" ,"E","E","Yi","I",
     "shch","sh","ch","c","Yu","Ya","j","a","b","v",
     "g","d","e","e","z","i","y","k","l","m","n",
     "o","p","r","s","t","u","f","h",
     "", "y","" ,"e","e","yi","i"
  );
  for($i=0; $i<count($cyr); $i++)  {
     $c_cyr = $cyr[$i];
     $c_lat = $lat[$i];
     $string = str_replace($c_cyr, $c_lat, $string);
  }
  $string = 
  	preg_replace(
  		"/([qwrtpsdfghklzxcvbnmQWRTPSDFGHKLZXCVBNM]+)[jJ]e/", 
  		"\${1}e", $string);
  $string = 
  	preg_replace(
  		"/([qwrtpsdfghklzxcvbnmQWRTPSDFGHKLZXCVBNM]+)[jJ]/", 
  		"\${1}'", $string);
  $string = preg_replace("/([eyuioaEYUIOA]+)[Kk]h/", "\${1}h", $string);
  $string = preg_replace("/^kh/", "h", $string);
  $string = preg_replace("/^Kh/", "H", $string);
  return $string;
}
function encodestring($string){
  $string = 
  	str_replace(array(" ",""","&","<",">"), 
  		array(" "), $string);
  $string = preg_replace("/[_\s\.,?!\[\](){}]+/", "_", $string);
  $string = preg_replace("/-{2,}/", "--", $string);
  $string = preg_replace("/_-+_/", "--", $string);
  $string = preg_replace("/[_\-]+$/", "", $string);
  $string = Transliterate($string);
  $string = ToLower($string);
  $string = preg_replace("/j{2,}/", "j", $string);
  $string = preg_replace("/[^0-9a-z_\-]+/", "", $string);
  return $string;
}

Старый вариант, рабоатет на пхп < 5.1.2
// функция для разложения строки в массив 
// аналог стандартной str_split, но для работы с UTF-8
// проверено на многих языках
function str_split_utf8($str) {
    $split = 1;
    $array = array();
    for ($i=0; $i < strlen($str); ){
        $value = ord($str[$i]);
        if($value > 127){
            if ($value >= 192 && $value <= 223)      $split = 2;
            elseif ($value >= 224 && $value <= 239)  $split = 3;
            elseif ($value >= 240 && $value <= 247)  $split = 4;
        } else $split = 1;
        $key = NULL;
        for ( $j = 0; $j < $split; $j++, $i++ ) $key .= $str[$i];
        array_push( $array, $key );
    }
    return $array;
} 
function encodestring($st)  {
	// Сначала заменяем "односимвольные" фонемы.

	$st_cyr = str_split_utf8("абвгґдеёзиійклмнопрстуфхыэ"+
	"АБВГҐДЕЁЗИІЙКЛМНОПРСТУФХЫЭ ");
	$st_lat = str_split_utf8("abvggdeeziyyklmnoprstufhie"+
	"ABVGGDEEZIYYKLMNOPRSTUFHIE_");
	foreach ($st_lat as $key => $value) {
		$st_lat[$st_cyr[$key]] = $value; 
		unset($st_lat[$key]);
	}
	$st = strtr($st, $st_lat); 
	
	// Далее заменяем "многосивольные" фонемы, и фонемы без аналогов.

	$st_mf = array(
		           "ж"=>"zh", "ц"=>"ts", "ч"=>"ch", 
		           "ш"=>"sh", "щ"=>"shch","ю"=>"yu", 
		           "я"=>"ya", "Ж"=>"ZH", "Ц"=>"TS", 
		           "Ч"=>"CH", "Ш"=>"SH", "Щ"=>"SHCH",
		           "Ю"=>"YU", "Я"=>"YA", "ї"=>"yi", 
		           "Ї"=>"Yi", "є"=>"ie", "Є"=>"Ye", 
		           "ь"=>"","ъ"=>"","Ь"=>"","Ъ"=>"");
	$st = strtr($st, $st_mf); 
	
	// Добиваем синтаксический мусор 
	return ereg_replace("[^A-Za-z0-9\.\–\(\)_]", "", $st); 
}
// пример:
echo encodestring("мухаха!@#$%^&*_+!№;%:?*[]{}-=,<>+(ололоЪь).");
// в результате получим:
// muhaha_(ololo).  

24 августа 2008, 1:01

CSS: transparency in all browsers Избранное

.make_me_transparent_baby{
	filter:alpha(opacity=50); /* IE, all IE*/
	-moz-opacity:0.5; /* old gecko */
	-khtml-opacity: 0.5; /* old safari */
	opacity: 0.5; /* all normal browsers */
}

8 июля 2008, 11:18

JavaScript: print_r (array and object dump) Избранное

function print_r(theObj, str){
  if(theObj.constructor == Array || theObj.constructor == Object){
    str += ("<ul>");
    for(var p in theObj){
      if(theObj[p].constructor == Array||theObj[p].constructor == Object){
	str += ("<li>["+p+"] => "+typeof(theObj)+"</li>");
        str += ("<ul>");
        str = print_r(theObj[p], str);
        str += ("</ul>"); 
      } else {
	str += ("<li>["+p+"] => "+theObj[p]+"</li>");
      }
    }
    str += ("</ul>");
    return str;
  }
}

27 июня 2008, 17:18

100% загрузка функции Javascript (без onload), после загрузки всей страницы Избранное

Javascript: Run some function after full page load
function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') { window.onload = func;} 
  else {window.onload = function() { if (oldonload) {oldonload();}func();}}
}
addLoadEvent(function() {
  //Выполняем произвольную JS "команду" :)
  document.getElementById("footer").style.bottom = 0;
});