В бой идет старик


HTML код старого спойлера выглядит так:

<!--dle_spoiler-->
<div class="title_spoiler">
	<img id="image-spa9f2ecb68fe8e529104c93fad10c96d5" style="vertical-align: middle;border: none;" alt="" src="/templates/Default/dleimages/spoiler-plus.gif" />&nbsp;
	<a href="javascript:ShowOrHide('spa9f2ecb68fe8e529104c93fad10c96d5')"><!--spoiler_title-->Показать / Скрыть текст<!--spoiler_title_end--></a>
</div>
<div id="spa9f2ecb68fe8e529104c93fad10c96d5" class="text_spoiler" style="display:none;">
	<!--spoiler_text-->Текст внутри спойлера<!--spoiler_text_end-->
</div>
<!--/dle_spoiler-->

Мне он не нравиться, а вам? Взять атрибуты id и style у <img /> или href у <a>.

Теперь посмотрим на страую javascript функцию:

function ShowOrHide(a){
	var b=$("#"+a),

	a=document.getElementById("image-"+a)?document.getElementById("image-"+a):null,

	c=1E3*(b.height()/200);

	3E3<c&&(c=3E3);250>c&&(c=250);

	"none"==b.css("display")?(b.show("blind",{},c),

	a&&(a.src=dle_root+"templates/"+dle_skin+"/dleimages/spoiler-minus.gif")):(2E3<c&&(c=2E3),b.hide("blind",{},c),
	a&&(a.src=dle_root+"templates/"+dle_skin+"/dleimages/spoiler-plus.gif"))
}

А этот код красив и функционален на сегодняшний день? Нет!

Новая версия. Сравните ее с существующей!


HTML выглядит так:

<!--dle_spoiler-->
<div data-type="spoiler">
	<a>Показать / Скрыть текст</a>
	<div data-type="text">
		<!--spoiler_text-->Текст внутри спойлера<!--spoiler_text_end-->
	</div>
</div>
<!--/dle_spoiler-->

jQuery функция так:

$('[data-type=spoiler] a').click(function(){
	$(this).toggleClass('opened').next('[data-type=text]').slideToggle(200);return false;
});

CSS сравнивать нет смысла ибо в старом коде нет ничего критичного, а в новом - ничего особенного. Обусловлено это тем, что для примера использован стандартный, простейший, внешний вид.

Внедрение нового


1. Открыть /engine/classes/parse.class.php, найти строку:

$source = preg_replace( "#\[/spoiler\]#i", "<!--spoiler_text_end--></div><!--/dle_spoiler-->", $source );

и заменить ее на:

$source = preg_replace( "#\[/spoiler\]#i", "<!--spoiler_text_end--></div></div><!--/dle_spoiler-->", $source );

далее найти строку:

$txt = str_replace( "<!--spoiler_text_end--></div><!--/dle_spoiler-->", '[/spoiler]', $txt );

и заменить на:

$txt = str_replace( "<!--spoiler_text_end--></div></div><!--/dle_spoiler-->", '[/spoiler]', $txt );

далее ищем функцию:

	function build_spoiler($title = "") {
		global $lang;
		
		$title = trim( $title );
		
		$title = stripslashes( $title );
		$title = str_replace( "&amp;amp;", "&amp;", $title );
		$title = preg_replace( "/javascript:/i", "javascript&#58; ", $title );
		
		$id_spoiler = "sp".md5( microtime().uniqid( mt_rand(), TRUE ) );
		
		if( ! $title ) {
			
			return "<!--dle_spoiler--><div class=\"title_spoiler\"><img id=\"image-" . $id_spoiler . "\" style=\"vertical-align: middle;border: none;\" alt=\"\" src=\"{THEME}/dleimages/spoiler-plus.gif\" />&nbsp;<a href=\"javascript:ShowOrHide('" . $id_spoiler . "')\"><!--spoiler_title-->" . $lang['spoiler_title'] . "<!--spoiler_title_end--></a></div><div id=\"" . $id_spoiler . "\" class=\"text_spoiler\" style=\"display:none;\"><!--spoiler_text-->";
		
		} else {
			
			return "<!--dle_spoiler $title --><div class=\"title_spoiler\"><img id=\"image-" . $id_spoiler . "\" style=\"vertical-align: middle;border: none;\" alt=\"\" src=\"{THEME}/dleimages/spoiler-plus.gif\" />&nbsp;<a href=\"javascript:ShowOrHide('" . $id_spoiler . "')\"><!--spoiler_title-->" . $title . "<!--spoiler_title_end--></a></div><div id=\"" . $id_spoiler . "\" class=\"text_spoiler\" style=\"display:none;\"><!--spoiler_text-->";
		
		}
	
	}

и заменяем ее на новую:

	function build_spoiler($title) {
		global $lang;

		$title = trim(stripslashes($title));

		if (!$title) return "<!--dle_spoiler--><div data-type=\"spoiler\"><a><!--spoiler_title-->". $lang['spoiler_title'] ."<!--spoiler_title_end--></a><div data-type=\"text\"><!--spoiler_text-->";
		else return "<!--dle_spoiler $title --><div data-type=\"spoiler\"><a><!--spoiler_title-->". $title ."<!--spoiler_title_end--></a><div data-type=\"text\"><!--spoiler_text-->";	
	}

2. В необходимый файл стилей добавить:

Проверьте наличие изображений spoiler-plus.gif и spoiler-minus.gif в директории dleimages. Если они отсутствуют, то их необходимо загрузить. Если же есть, но в другой папке, то в приведенном ниже CSS не забудьте изменить пути.

[data-type=spoiler] {
	position:relative;
}
[data-type=spoiler] a {
	display:block;
	line-height:20px;
	padding-left:20px;
}
[data-type=spoiler] a:before {
	content:'';
	position:absolute;
	top:5px;
	left:5px;
	width:9px;
	height:10px;
	background:url(../dleimages/spoiler-plus.gif);
}
[data-type=spoiler] .opened:before {
	background:url(../dleimages/spoiler-minus.gif);
}
[data-type=text] {
	display:none;
}

Старые стили можно удалить. Находятся они, обычно, в engine.css. Имена классов, которые больше не нужны: .text_spoiler и .title_spoiler

3. Открыть /engine/classes/js/dle_js.js, найти функцию:

function ShowOrHide(a){var b=$("#"+a),a=document.getElementById("image-"+a)?document.getElementById("image-"+a):null,c=1E3*(b.height()/200);3E3<c&&(c=3E3);250>c&&(c=250);"none"==b.css("display")?(b.show("blind",{},c),a&&(a.src=dle_root+"templates/"+dle_skin+"/dleimages/spoiler-minus.gif")):(2E3<c&&(c=2E3),b.hide("blind",{},c),a&&(a.src=dle_root+"templates/"+dle_skin+"/dleimages/spoiler-plus.gif"))}

и заменить ее на:

$('[data-type=spoiler] a').click(function(){$(this).toggleClass('opened').next('[data-type=text]').slideToggle(200);return false;});

Резюме: минусы и плюсы.


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

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

Ну а плюсы очевидны, как по мне:
- в два с половиной раза меньше кода
- более гибкая возможность для стилизации

Демонстрацию работы можно посмотреть по ссылкам:


- Форма входа в админцентр DataLife Engine: http://firstvector.org/broken/dev/28
- Создание приложения из сайта на iOS и Windows 8: http://firstvector.org/broken/dev/43