<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>m1chu.eu - another devblog &#187; JavaScript</title>
	<atom:link href="http://m1chu.eu/category/webmastering/client-side/javascript-client-side-webmastering/feed/" rel="self" type="application/rss+xml" />
	<link>http://m1chu.eu</link>
	<description>we live, as we dream... alone - another devblog</description>
	<lastBuildDate>Sun, 14 Nov 2010 11:07:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>HTML 5: obsługa elementów AUDIO i VIDEO</title>
		<link>http://m1chu.eu/2010/03/19/html5-obsluga-elementow-audio-i-video/</link>
		<comments>http://m1chu.eu/2010/03/19/html5-obsluga-elementow-audio-i-video/#comments</comments>
		<pubDate>Fri, 19 Mar 2010 21:14:33 +0000</pubDate>
		<dc:creator>m1chu</dc:creator>
				<category><![CDATA[(x)HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Webhosting]]></category>
		<category><![CDATA[audio]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[elementy]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[html 5]]></category>
		<category><![CDATA[natywnie]]></category>
		<category><![CDATA[object]]></category>
		<category><![CDATA[opera]]></category>
		<category><![CDATA[safari]]></category>
		<category><![CDATA[tagi]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://m1chu.eu/?p=1752</guid>
		<description><![CDATA[Serwisów oferujących przeglądanie zasobów multimedialnych nie brakuje w sieci. Do niedawna jednak wszystkie oparte były o wykorzystanie możliwości znaczników object lub niepoprawnego embed. Problem w tym, że rozwiązania te opierały się o wtyczki firm trzecich, takie jak QuickTime, czy Flash. HTML 5 standaryzuje osadzanie plików muzycznych i filmów. Kwestia dźwiękowa: element AUDIO Jedna z najbardziej, [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><img class="iborder" src="http://images.m1chu.eu/index.php?res=MTlfMDNfMTBfaHRtbDVfYXVkaW9fdmlkZW87aHRtbDVfYXVkaW9fdmlkZW9fcG9zdF9oZWFkZXIucG5n" alt="HTML5: obsługa elementów AUDIO i VIDEO" style="height: 119px;" /></p>
<p>Serwisów oferujących przeglądanie zasobów multimedialnych nie brakuje w sieci. Do niedawna jednak wszystkie oparte były o wykorzystanie możliwości znaczników <code><a href="http://m1chu.eu/2008/12/14/jak-poprawnie-osadzic-flasha-w-kodzie-xhtml-strony/"  title="Jak poprawnie osadzić Flasha w kodzie (x)HTML strony?">object</a></code> lub niepoprawnego <code>embed</code>. Problem w tym, że rozwiązania te opierały się o wtyczki firm trzecich, takie jak QuickTime, czy Flash. HTML 5 standaryzuje osadzanie plików muzycznych i filmów.</p>
<p><span id="more-1752"></span></p>
<h2>Kwestia dźwiękowa: element AUDIO</h2>
<p>Jedna z najbardziej, od dawna oczekiwanych możliwości w HTML 5. Pozwala na natywne odtwarzanie utworów muzycznych w przeglądarce. Określana znacznikiem <code><a target="_blank" href="http://utnij.eu/html5_audio/"  title="Specyfikacja: audio">audio</a></code>.</p>
<p>Wg. specyfikacji może przyjmować pięć atrybutów:</p>
<ul>
<li><code><a target="_blank" href="http://utnij.eu/html5_video_autoplay/"  title="Specyfikacja: autoplay">autoplay</a></code> &#8211; określa czy odtwarzać automatycznie dźwięk, gdy zostanie on załadowany,</li>
<li><code><a target="_blank" href="http://utnij.eu/html5_video_controls/"  title="Specyfikacja: controls">controls</a></code> &#8211; określa czy wyświetlić odtwarzacz w standardowym układzie,</li>
<li><code><a target="_blank" href="http://utnij.eu/html5_video_loop/"  title="Specyfikacja: loop">loop</a></code> &#8211; określa czy powtarzać odtwarzanie,</li>
<li><code><a target="_blank" href="http://utnij.eu/html5_video_preload/"  title="Specyfikacja: preload">preload</a></code> &#8211; wyznacza, czy załadować zasobów w trakcie ładowania strony,</li>
<li><code><a target="_blank" href="http://utnij.eu/html5_src/"  title="Specyfikacja: src">src</a></code> &#8211; adres URL do pierwotnego, ładowanego źródła.</li>
</ul>
<p>Korzystając z powyższych informacji możemy otrzymać następujący przykład:</p>
<pre class="brush: xml; title: ;">&lt;!-- domyślny układ, startuje automatycznie, jedno źródło --&gt;
&lt;audio src=&quot;test.ogg&quot; controls autoplay&gt;&lt;/audio&gt;</pre>
<p>W praktyce pojawi się jednak problem, związany z implementacją różnych wersji kodeków w przeglądarkach (np. Vorbis, Advanced Audio Coding, MPEG-1 Audio Layer 3). Z tego powodu, trzeba aktualnie definiować dodatkowe zasoby w tagu <code><a target="_blank" href="http://utnij.eu/html5_source/"  title="Specyfikacja: source">source</a></code>. Obsługuje on atrybuty:</p>
<ul>
<li><code><a target="_blank" href="http://utnij.eu/html5_media/"  title="Specyfikacja: media">media</a></code> &#8211; zdefiniowanie typu zasobu. Domyślnie odpowiada wszystkim typom mediów,</li>
<li><code><a target="_blank" href="http://utnij.eu/html5_src/"  title="Specyfikacja: src">src</a></code> &#8211; adres URL do pierwotnego, ładowanego źródła,</li>
<li><code><a target="_blank" href="http://utnij.eu/html5_type/"  title="Specyfikacja: type">type</a></code> &#8211; definiuje typ zasobu, pozwalając na określenie przeglądarce, czy może odtworzyć go, bez konieczności pobierania. Musi być pod postacią prawidłowego <a target="_blank" href="http://utnij.eu/valid-mime-type/"  title="Specyfikacja: typy MIME">typu MIME</a>. Opcjonalnie, wewnątrz niego można zdefiniować parametr <code>codecs</code>, określający jak zakodowany jest zasób.</li>
</ul>
<pre class="brush: xml; title: ;">&lt;!-- domyślny układ, startuje automatycznie, wiele źródeł --&gt;
&lt;audio controls autoplay&gt;
	&lt;!-- Firefox ge 3.5, Chrome ge 3 beta, Opera ge 10.5 --&gt;
	&lt;source src=&quot;test.ogg&quot; type=&quot;audio/ogg; codecs=vorbis&quot;&gt;
	&lt;!-- Safari ge 4, Chrome ge 3 beta --&gt;
	&lt;source src=&quot;test.mp3&quot;&gt;
	&lt;!-- Opera ge 10.5, Firefox ge 3.5 --&gt;
	&lt;source src=&quot;test.wav&quot;&gt;
&lt;/audio&gt;</pre>
<p>Na wypadek niekompatybilnej przeglądarki można wewnątrz elementu <code>audio</code> wstawić alternatywną wiadomość, bądź <a href="http://m1chu.eu/2008/12/14/jak-poprawnie-osadzic-flasha-w-kodzie-xhtml-strony/"  title="Jak poprawnie osadzić Flasha w kodzie (x)HTML strony?">plik Flash</a> z autorskim odtwarzaczem.</p>
<pre class="brush: xml; title: ;">&lt;!-- domyślny układ, startuje automatycznie, wiele źródeł --&gt;
&lt;audio controls autoplay&gt;
	&lt;!-- Firefox ge 3.5, Chrome ge 3 beta, Opera ge 10.5 --&gt;
	&lt;source src=&quot;test.ogg&quot; type=&quot;audio/ogg; codecs=vorbis&quot;&gt;
	&lt;!-- Safari ge 4, Chrome ge 3 beta --&gt;
	&lt;source src=&quot;test.mp3&quot;&gt;
	&lt;!-- Opera ge 10.5, Firefox ge 3.5 --&gt;
	&lt;source src=&quot;test.wav&quot;&gt;
	&lt;!-- alternatywny wynik --&gt;
	Twoja przeglądarka nie obsługuje HTML 5.
&lt;/audio&gt;</pre>
<p>W rozwiązaniu powyższego problemu pomóc może także użycie możliwości JavaScriptu i metod/atrybutów/zdarzeń dostępnych w API. Pozwalają one na manipulację na obsługiwanych plikach. Niestety skorzystanie z możliwości obiektu <code>Audio</code> nie będzie możliwe w jakiejkolwiek wersji IE.</p>
<ul>
<li><code><a target="_blank" href="http://utnij.eu/html5_buffered/"  title="Specyfikacja: buffered">buffered</a></code> &#8211; określa ilość oraz początkowy i końcowy czas zbuforowanego zasobu,</li>
<li><code><a target="_blank" href="http://utnij.eu/html5_canplaytype/"  title="Specyfikacja: canPlayType()">canPlayType(typ_MIME)</a></code> &#8211; zwraca informacje na temat tego, czy dany typ obsługiwany jest przez klienta. Możliwe wyniki to: <em>no</em>, <em>maybe</em>, <em>probably</em>,</li>
<li><code><a target="_blank" href="http://utnij.eu/html5_currenttime/"  title="Specyfikacja: currentTime">currentTime</a></code> &#8211; pozwala na ustawienie lub pobranie aktualnego czasu odtwarzania,</li>
<li><code><a target="_blank" href="http://utnij.eu/html5_duration/"  title="Specyfikacja: duration">duration</a></code> &#8211; wyświetla czas trwania utworu. W wypadku nie załadowania go, zwraca <strong>NaN</strong> (Not a Number),</li>
<li><code><a target="_blank" href="http://utnij.eu/html5_ended/"  title="Specyfikacja: ended">ended</a></code> &#8211; zwraca prawdę, jeżeli zakończono odtwarzanie (w przód),</li>
<li><code><a target="_blank" href="http://utnij.eu/html5_loop/"  title="Specyfikacja: loop">loop</a></code> &#8211; wartość logiczna, pozwalająca na zapętlanie dźwięku,</li>
<li><code><a target="_blank" href="http://utnij.eu/html5_muted/"  title="Specyfikacja: muted">muted</a></code> &#8211; zwraca lub ustawia, czy kanały audio są wyciszone,</li>
<li><code><a target="_blank" href="http://utnij.eu/html5_pause/"  title="Specyfikacja: pause()">pause()</a></code> &#8211; pauzuje odtwarzanie,</li>
<li><code><a target="_blank" href="http://utnij.eu/html5_paused/"  title="Specyfikacja: paused">paused</a></code> &#8211; przetrzymuje informacje o tym, czy element jest spauzowany,</li>
<li><code><a target="_blank" href="http://utnij.eu/html5_play/"  title="Specyfikacja: play()">play()</a></code> &#8211; wznawia odtwarzanie,</li>
<li><code><a target="_blank" href="http://utnij.eu/html5_played/"  title="Specyfikacja: played">played</a></code> &#8211; przetrzymuje informacje o odtwarzanym elemencie,</li>
<li><code><a target="_blank" href="http://utnij.eu/html5_volume/"  title="Specyfikacja: volume">volume</a></code> &#8211; zwraca lub ustawia głośność dźwięku w zakresie od 0.0&#8230;0.1.</li>
</ul>
<p>Przykład:</p>
<pre class="brush: xml; title: ;">&lt;p&gt;
	&lt;button type=&quot;button&quot; onclick=&quot;stop();&quot;&gt;Stop&lt;/button&gt;
	&lt;button type=&quot;button&quot; onclick=&quot;lour();&quot;&gt;Wycisz&lt;/button&gt;
&lt;/p&gt;</pre>
<pre class="brush: jscript; title: ;">&lt;script type=&quot;text/javascript&quot;&gt;
var element = document.getElementById(&quot;audio&quot;); /* pobranie elementu */
function stop() { /* funkcja zatrzymująca */
	if ( !!(element.canPlayType) != false ) {
		element.currentTime = 0; /* ustawienie czasu na początek */
		element.pause(); /* pauza */
	}
}
function lour() { /* funkcja wyciszająca */
	if ( !!(element.canPlayType) != false ) {
		element.volume = 0; /* głośność na zero */
	}
}
&lt;/script&gt;</pre>
<p>Przykład z użyciem <code>new Audio()</code>:</p>
<pre class="brush: jscript; title: ;">var obj = new Audio('');
alert(!!(obj.canPlayType));</pre>
<h2>Kwestia filmowa: element VIDEO</h2>
<p>Drugi, ważny element HTML 5. Oparty o znacznik <code><a target="_blank" href="http://utnij.eu/html5_video/"  title="Specyfikacja: video">video</a></code>. Przyjmuje te same atrybuty co <code>audio</code>, a ponadto:</p>
<ul>
<li><code><a target="_blank" href="http://utnij.eu/html5_height/"  title="Specyfikacja: height">height</a></code> &#8211; określa wysokość okna playera,</li>
<li><code><a target="_blank" href="http://utnij.eu/html5_poster/"  title="Specyfikacja: poster">poster</a></code> &#8211; adres URL alternatywnej grafiki, wyświetlanej jeżeli domyślny zasób nie będzie dostępny,</li>
<li><code><a target="_blank" href="http://utnij.eu/html5_width/"  title="Specyfikacja: width">width</a></code> &#8211; określa szerokość okna odtwarzacza.</li>
</ul>
<p>Tak oto możemy stworzyć podstawowy przykład użycia:</p>
<pre class="brush: xml; title: ;">&lt;!-- buforowanie zasobu w trakcie ładowania strony, jeden plik --&gt;
&lt;video src=&quot;test.mp4&quot; preload&gt;&lt;/video&gt;</pre>
<p>Ponownie, w praktyce, powinno się zdefiniować kilka, różnych źródeł plików, w celu obsługi odtwarzacza przez większą ilość przeglądarek.</p>
<pre class="brush: xml; title: ;">&lt;!-- domyślny układ, buforuje przy ładowaniu, wiele źródeł --&gt;
&lt;video controls preload&gt;
	&lt;!-- Firefox ge 3.5, Chrome ge 3 beta, Opera ge 10.5 --&gt;
	&lt;source src=&quot;test.ogv&quot; type=&quot;audio/ogg; codecs='theora, vorbis'&quot;&gt;
	&lt;!-- Safari ge 4, Chrome ge 3 beta --&gt;
	&lt;source src=&quot;test.mp4&quot; type=&quot;video/mp4; codecs='avc1.42E01E, mp4a.40.2'&quot;&gt;
	&lt;!-- mobilne --&gt;
	&lt;source src=&quot;video.3gp&quot; type=&quot;video/3gpp; codecs='mp4v.20.8, samr'&quot;&gt;
	&lt;!-- alternatywny wynik --&gt;
	Twoja przeglądarka nie obsługuje HTML 5.
&lt;/video&gt;</pre>
<p style="text-align: center; font-size: 10px;"><video controls style="width: 480px; height: 320px;" poster="http://farm5.static.flickr.com/4019/4447584693_278f64dba5_o.png"><source src="http://osaddict.com/files/elephantsdream-480-h264-st-aac.mov" /><source src="http://mirrorblender.top-ix.org/peach/bigbuckbunny_movies/big_buck_bunny_480p_stereo.ogg" /><img src="http://farm5.static.flickr.com/4019/4447584693_278f64dba5_o.png" alt="Znacznik video nieobsługiwany" /></video><br />W odtwarzaczu wyświetlane są dwa filmy (Elephants Dream, Big Buck Bunny) na licencji zezwalającej na rozprowadzanie kopii w trybie online.</p>
<h2>Obróbka</h2>
<p>Zarówno w przypadku jednego, jak i drugiego elementu możemy je stylować.</p>
<pre class="brush: css; title: ;">audio, video {
	width: 480px;
	height: 320px;
}</pre>
<h2>Kompatybilność</h2>
<table class="article_table">
<thead>
<tr>
<th>Kodek (kontener)</th>
<th>Android</th>
<th>Chrome >= 3.0</th>
<th>Firefox >= 3.5</th>
<th>Iphone</th>
<th>Opera >= 10.5</th>
<th>Safari >= 4</th>
</tr>
</thead>
<tbody>
<tr>
<td class="t_sm">Theora video (Ogg/.ogv)</td>
<td>x</td>
<td>✓</td>
<td>✓</td>
<td>x</td>
<td>✓</td>
<td>x</td>
</tr>
<tr>
<td class="t_sm">Vorbis audio (Ogg/.ogg)</td>
<td>x</td>
<td>✓</td>
<td>✓</td>
<td>x</td>
<td>✓</td>
<td>x</td>
</tr>
<tr>
<td class="t_sm">H.264 video (MP4/.mp4)</td>
<td>✓</td>
<td>✓</td>
<td>x</td>
<td>✓</td>
<td>x</td>
<td>✓</td>
</tr>
<tr>
<td class="t_sm">AAC audio (MP4/.mp3)</td>
<td>✓</td>
<td>✓</td>
<td>x</td>
<td>✓</td>
<td>x</td>
<td>✓</td>
</tr>
<tr>
<td class="t_sm">WAV audio (WAV/.wav)</td>
<td>-</td>
<td>-</td>
<td>✓</td>
<td>-</td>
<td>✓</td>
<td>✓</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://m1chu.eu/2010/03/19/html5-obsluga-elementow-audio-i-video/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://osaddict.com/files/elephantsdream-480-h264-st-aac.mov" length="103636531" type="video/quicktime" />
		</item>
		<item>
		<title>Efekt graficznego podświetlenia w jQuery i Prototype z Scriptaculous</title>
		<link>http://m1chu.eu/2009/02/09/efekt-graficznego-podswietlenia-w-jquery-i-prototype-z-scriptaculous/</link>
		<comments>http://m1chu.eu/2009/02/09/efekt-graficznego-podswietlenia-w-jquery-i-prototype-z-scriptaculous/#comments</comments>
		<pubDate>Mon, 09 Feb 2009 12:45:54 +0000</pubDate>
		<dc:creator>m1chu</dc:creator>
				<category><![CDATA[(x)HTML]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Prototype]]></category>
		<category><![CDATA[Webhosting]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[highlighter]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[podświetlenie]]></category>
		<category><![CDATA[product]]></category>
		<category><![CDATA[scriptaculous]]></category>
		<category><![CDATA[xhtml]]></category>

		<guid isPermaLink="false">http://m1chu.eu/?p=1157</guid>
		<description><![CDATA[Jedni nie korzystają z nich wcale, niektórzy tylko po to aby zwiększyć funkcjonalność tworzonych przez siebie stron, a u jeszcze innych zauważalny jest przepych tego typu rozwiązań. Biblioteki programistyczne języka JavaScript, bo o ich wykorzystaniu tu mowa to źródło bardzo różnorodnych, nie tylko funkcjonalnych, ale także estetycznych efektów. Sieć aż kipi od dobrych i słabych, [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><img class="iborder" src="http://farm1.static.flickr.com/242/3264023222_981cfd8fd0_o.png" alt="Efekt podświetlania w jQuery i Prototype" style="height: 119px;" /></p>
<p>Jedni nie korzystają z nich wcale, niektórzy tylko po to aby zwiększyć funkcjonalność tworzonych przez siebie stron, a u jeszcze innych zauważalny jest przepych tego typu rozwiązań. Biblioteki programistyczne języka JavaScript, bo o ich wykorzystaniu tu mowa to źródło bardzo różnorodnych, nie tylko funkcjonalnych, ale także estetycznych efektów. Sieć aż kipi od dobrych i słabych, lepiej oraz słabiej wytłumaczonych przykładów użycia możliwości <a target="_blank" href="http://mootools.net/"  title="MooTools">MooTools</a>, <a target="_blank" href="http://jquery.com/"  title="jQuery">jQuery</a>, <a target="_blank" href="http://www.prototypejs.org/"  title="Prototype">Prototype</a> z <a target="_blank" href="http://script.aculo.us/"  title="Scriptaculous">Scriptaculous</a>, czy innych mniej powszechnych frameworków.</p>
<p>Jednym z takich efektów jest możliwość stworzenia animowanego, graficznego podświetlenia pojawiającego się np. nad grafiką wywołującą animację. Interaktywność taka została opisana na <a target="_blank" href="http://utnij.eu/product-highlighter-mootools/"  title="Product highlighter with MooTools">NetTuts</a> z wykorzystaniem MooTools. My osiągniemy taki wynik dzięki zastosowaniu jQuery (w jednym przykładzie) oraz dodatkowo także za pomocą Prototype wraz z Scriptaculous (w drugim przykładzie).</p>
<p><span id="more-1157"></span></p>
<p style="text-align: center; font-size: 10px;"><object type="application/x-shockwave-flash" width="538" height="352" data="http://www.vimeo.com/moogaloop.swf?clip_id=3136566&amp;server=www.vimeo.com&amp;fullscreen=1&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=01AAEA"><param name="quality" value="best" /><param name="allowfullscreen" value="true" /><param name="scale" value="showAll" /><param name="movie" value="http://www.vimeo.com/moogaloop.swf?clip_id=3136566&amp;server=www.vimeo.com&amp;fullscreen=1&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=01AAEA" /><img class="iborder" src="http://farm1.static.flickr.com/190/3263308689_e6578263b5_o.png" alt="Oczekiwany efekt" style="height: 366px;" /></object><br />Oczekiwany efekt.</p>
<h2>Krok 1: Za co się chwycić na początku&#8230;</h2>
<p>Na początek musisz wiedzieć w jakim celu potrzebny jest Ci prezentowany w tym artykule efekt. Menu? Wyświetlanie dodatkowych informacji w graficznej liście produktów? Czy może szybki, animowany splash? Wybór jest Twój i podług niego będziesz musiał zaopatrzyć się w dodatkowe, niezbędne elementy do wykonania podświetlenia.</p>
<p>Chodzi tu mianowicie o grafiki, których musi być dwa razy więcej niż elementów podatnych na działanie mechanizmu. Powiedzmy, jeżeli chcemy w pięcioelementowym menu zastosować w każdym zdarzenie po najechaniu myszką zgodne z przesłaniem tego artykułu to potrzebujemy dziesięciu grafik. Pięć opisujących przyciski menu i drugie tyle będące &#8222;treścią&#8221; pojawiającą się po podświetleniu.</p>
<p>Po uporaniu się z wizualną częścią problemu oraz strony internetowej możemy ruszyć krok dalej.</p>
<h2>Krok 2: Zaopatrujemy się w jQuery i/lub Prototype i Scriptaculous!</h2>
<p><strong>jQuery</strong> to aktualnie najpopularniejsza biblioteka. I najłatwiej ją skatalogować w czeluścia własnego projektu. Wystarczy ze <a target="_blank" href="http://jquery.com/"  title="jQuery">strony głównej</a> pobrać wersję <strong>1.3.1 production/Minified</strong> i umieścić ją w obrębie plików tworzonego przez nas przykładu (niezbędny będzie tylko plik <strong>jquery-1.3.1.min.js</strong>).</p>
<p>Z <strong>Prototype</strong> sprawa jest ciut bardziej skomplikowana, bo prócz standardowego frameworka musimy pobrać także dodatkowy interfejs w postaci <strong>Scriptaculous</strong>, dzięki któremu uzyskamy dostęp do efektu pozwalającego na dynamiczne zmienianie właściwości CSS elementów strony. Ściągamy więc <a target="_blank" href="http://utnij.eu/prototype-download/"  title="Prototype">wersję 1.6.0.3 pierwszej biblioteki</a>, oraz paczkę z <a target="_blank" href="http://utnij.eu/scriptaculous-download/"  title="Scriptaculous">wersją 1.8.2 drugiej</a>. Z obydwu wyodrębniamy pliki i w ramach folderu tworzonego przez nas projektu umieszczamy tylko <strong>prototype.js</strong> oraz <strong>effects.js</strong> (z drugiego archiwum).</p>
<p>W przypadku tego artykułu umownie pliki związane z frameworkami będą znajdować się w podkatalogu <strong>javascript</strong> folderu głównego. Obydwa przykłady (dotyczące, jeden <strong>jQuery</strong>, a drugi <strong>Prototype z Scriptaculous</strong>) będą oczywiście wykonywane w osobnych plikach znajdujących się w dwóch różnych katalogach.</p>
<p style="text-align: center; font-size: 10px;"><img class="iborder" src="http://farm1.static.flickr.com/243/3263426717_b9e39151ce_o.png" alt="Rozdzielenie implementacji przykładów na dwa katalogi" style="height: 280px;" /><br />Przykładowe rozdzielenie implementacji przykładów na dwa katalogi. W naszym przypadku pliki <strong>.js</strong> znajdują się dodatkowo w podkatalogu <strong>javascript</strong>.</p>
<h2>Krok 3: Tworzymy strukturę XHTML</h2>
<p>Atutem naszego rozwiązania jest kompatybilność z serwowaniem dokumentu XHTML w postaci <code>application/xhtml+xml</code>, czego bardzo często brakuje w przypadku efektów opartych na bibliotekach JS. Z racji tego także, że i w przypadku <strong>Prototype</strong> i <strong>jQuery</strong> struktura strony pozostaje niezmienna to obojętnie który framework wykorzystujesz poniższe tłumaczenie i partie kodu będą prawidłowe.</p>
<p>Z powodu tego w jaki sposób będziemy wysyłać treść strony posłużymy się małą częścią kodu PHP, a co za tym idzie plik korzystający z naszego mechanizmu musi mieć też takie rozszerzenie (no chyba, że serwer jest inaczej skonfigurowany, ale to już problematyka do rozwiązania na inny temat).</p>
<pre class="brush: php; title: ;">&lt;?php
if ( stristr($_SERVER['HTTP_ACCEPT'], 'application/xhtml+xml') ) // jeżeli przeglądarka obsługuje application/xhtml+xml
{
	header(&quot;Content-Type: application/xhtml+xml; charset=utf-8&quot;); // wysłanie odpowiednich nagłówków
	print '&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;'.&quot;\r\n&quot;;
	print '&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.1//EN&quot;'.&quot;\r\n&quot;;
	print '&quot;http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd&quot;&gt;'.&quot;\r\n&quot;;
}
else // wysłanie dokumentu jako text/html dla przeglądarek nie obsługujących typu zawartości pliku z powyższego warunku, np. dla IE
{
	header(&quot;Content-Type: text/html; charset=utf-8&quot;);
	print '&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot;'.&quot;\r\n&quot;;
	print '&quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;'.&quot;\r\n&quot;;
}
?&gt;</pre>
<p>Poniżej dodajemy uniwersalny układ strony. Ważnym ułatwieniem jest możliwość tworzenia odnośników z elementów graficznych podatnych mechanizmowi, a także fakt, że nie korzystamy w nim z tagów <code>img</code>, a efektu zbliżonego do <a href="http://m1chu.eu/webmastering/efekt-rollover-w-css-bez-przeladowywania-obrazka"  title="Efekt rollover">sliding-doors</a> w celu wyświetlania obrazów.</p>
<pre class="brush: xml; title: ;">&lt;html lang=&quot;pl&quot; xml:lang=&quot;pl&quot; xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
	&lt;meta http-equiv=&quot;Content-type&quot; content=&quot;&lt;?php print ( stristr($_SERVER['HTTP_ACCEPT'], 'application/xhtml+xml') ? 'application/xhtml+xml' : 'text/html' ); // typ zawartości zależny do możliwości przeglądarki użytkownika ?&gt;; charset=utf-8&quot; /&gt;
  	&lt;meta name=&quot;Description&quot; content=&quot;Product highlighter - tworzenie dynamicznych opisów produktów - m1chu.eu&quot; /&gt;
  	&lt;meta name=&quot;Keywords&quot; content=&quot;product, highlighter&quot; /&gt;
	&lt;title&gt;Product highlighter&lt;/title&gt;
	&lt;style type=&quot;text/css&quot;&gt;@import url('stylesheet.css');&lt;/style&gt; &lt;!-- arkusz stylów --&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;div id=&quot;siteContainer&quot;&gt;
		&lt;div id=&quot;highlightsContainer&quot;&gt; &lt;!-- zbiór grafik wyświetlanych przy najechaniu kursorem --&gt;
			&lt;div class=&quot;highlights&quot; id=&quot;highlight1&quot;&gt;&lt;/div&gt;
			&lt;div class=&quot;highlights&quot; id=&quot;highlight2&quot;&gt;&lt;/div&gt;
			&lt;div class=&quot;highlights&quot; id=&quot;highlight3&quot;&gt;&lt;/div&gt;
		&lt;/div&gt;

		&lt;div id=&quot;pageContainer&quot;&gt; &lt;!-- zbiór grafik podatnych na efekt --&gt;
			&lt;div class=&quot;pages&quot; id=&quot;page1&quot;&gt;&lt;a href=&quot;http://m1chu.eu/&quot;&gt;&lt;/a&gt;&lt;/div&gt;
			&lt;div class=&quot;pages&quot; id=&quot;page2&quot;&gt;&lt;a href=&quot;http://vivee.info/&quot;&gt;&lt;/a&gt;&lt;/div&gt;
			&lt;div class=&quot;pages&quot; id=&quot;page3&quot;&gt;&lt;a href=&quot;http://utnij.eu/&quot;&gt;&lt;/a&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<h2>Krok 4: Stylizujemy strukturę strony za pomocą CSS</h2>
<p>Posługując się metodami <a href="http://m1chu.eu/2009/01/08/pozycjonujemy-za-pomoca-kaskadowego-arkusza-stylow-css/"  title="Pozycjonowanie za pomocą CSS">pozycjonowania elementów</a> dostępnymi w kaskadowym arkuszu stylów możemy operując na elementach o identyfikatorach <code>siteContainer</code>, <code>pageContainer</code>, <code>highlightsContainer</code> oraz <code>divach</code> potomnych ułożyć i wystylizować wygląd, w tym położenie jak na wyżej zamieszczonym filmiku (screenie) obrazującym wykonanie zadania z tego artykułu.</p>
<p>Do wszystkich bloków kodu CSS odwołujących się do tagów zawierających identyfikatory grafik zostały dodane także właściwości <code>background</code> z adresem pliku tła.</p>
<p>W naszym przypadku poniższy kod zapisujemy do pliku <strong>stylesheet.css</strong>.</p>
<pre class="brush: css; title: ;">/* ustawienia domyślne dla ciała strony (w poprawnie wysyłanym XHTML jest to html+body, a nie tylko body) */
html, body {
	margin: 0px;
	padding: 0px;
	background: #000 url('bg.png') repeat-x;
}

#siteContainer {
	margin: 150px auto 0px auto; /* marginesy - wyśrodkowanie poziome */
	width: 573px;
	height: 345px;
	position: relative; /* relatywna pozycja, kontener */
	background: transparent url('container.png') no-repeat top left;
}
#pageContainer {
	position: absolute; /* pozycja względem #siteContainer */
	z-index: 5; /* ponad ciałem strony i pod #highlightsContainer */
	top: 128px;
	left: 0px;
}
#highlightsContainer {
	position: absolute; /* pozycja względem #siteContainer */
	z-index: 10; /* ponad pozostałymi elementami */
	left: 178px;
	top: 30px;
}
/* ustawienie w linii wraz z zmianą wyglądu kursora */
#pageContainer &gt; div {
	float: left;
	cursor: pointer;
}
/* rozmiary klikalnych divów potomnych znajdujących się w kontenerze listy grafik podatnych na działanie mechanizmu */
#pageContainer &gt; div a {
	width: 178px;
	height: 178px;
	display: block;
}
#page1 {
	margin-right: 19px; /* prawy margines - odstęp od kolejnego diva */
}
#page1 a {
	background: url('icon_1.png') no-repeat; /* tło grafiki podatnej na działanie efektu */
}
#page2 {
	margin-right: 20px; /* prawy margines - odstęp od kolejnego diva */
}
#page2 a {
	background: url('icon_2.png') no-repeat; /* tło grafiki podatnej na działanie efektu */
}
#page3 a {
	background: url('icon_3.png') no-repeat; /* tło grafiki podatnej na działanie efektu */
}

/* rozmiary wszystkich potomków typu div kontenera zawierającego podświetlenia */
#highlightsContainer &gt; div {
	position: absolute;
	width: 222px;
	height: 101px;
	display: block;
}
/* pliki tła w pojawiających się podświetleniach */
#highlight1 {
	background: transparent url('highlights_1.png') no-repeat;
}
#highlight2 {
	background: transparent url('highlights_2.png') no-repeat;
}
#highlight3 {
	background: transparent url('highlights_3.png') no-repeat;
}</pre>
<h2>Krok 5a: Dodajemy jQuery do dokumentu</h2>
<p>Tego, czego zabrakło dotychczasowo w naszym dokumencie to załączenie bibliotek oraz pliku <strong>.js</strong> w którym będzie znajdować się kod animujący pożądany przez nas efekt.</p>
<p>Dla <strong>jQuery</strong> w sekcji <code>head</code> należy dodać pliki <strong>jquery-1.3.1.min.js</strong> oraz <strong>product-highlighter.js</strong> (który umownie będzie zawierał dodatkowy kod).</p>
<pre class="brush: xml; title: ;">	&lt;script type=&quot;text/javascript&quot; src=&quot;javascript/jquery-1.3.1.min.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;javascript/product-highlighter.js&quot;&gt;&lt;/script&gt;</pre>
<h2>Krok 5b: Dodajemy Prototype z Scriptaculous do dokumentu</h2>
<p>Tym razem musimy dodać jeden plik więcej. Bibliotekę (<strong>prototype.js</strong>), jej dodatkowy interfejs, a dokładniej plik zawierający obiekt <strong>Effect</strong> (<strong>effects.js</strong>) oraz jak w powyższym przypadku plik z naszym kodem animacji (<strong>product-highlighter.js</strong>).</p>
<pre class="brush: xml; title: ;">		&lt;script type=&quot;text/javascript&quot; src=&quot;javascript/prototype.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;javascript/effects.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;javascript/product-highlighter.js&quot;&gt;&lt;/script&gt;</pre>
<h2>Krok 6a: Implementujemy kod animacji z użyciem jQuery</h2>
<p>Jak to bywa w przypadku tego frameworka, aby jakieś zdarzenie działało poprawnie powinno się je umieszczać w funkcji <code>$(document).ready()</code>, której zawartość zostanie załadowana w momencie załadowania drzewa dokumentu.</p>
<pre class="brush: jscript; title: ;">$(document).ready(function() {
	[kod]
});</pre>
<p>W <strong>[</strong><strong>kod]</strong> musimy przypisać (do tablicy) wg. klasy wszystkie grafiki wyświetlane podczas podświetlenia, ustawić parametry podstawowe CSS oraz stworzyć sprawdzanie w pętli, czy dana grafika o klasie <code>.pages</code> nie jest najechana przez kursor i w zależności o danego trybu (<em>kursor na/kursor poza</em>) wykonać pożądaną animacji (<em>wyłonienie dodatkowego tła / zanikanie dodatkowego tła</em>).</p>
<p>Poniższy kod umieszczamy w pliku <strong>product-highlighter.js</strong>.</p>
<pre class="brush: jscript; title: ;">$(document).ready(function() {
	// tablica elementów o klasie .highlights
	var highlights = $('.highlights');

	// ustawienie pełnej przezroczystości elementów pojawiających się w czasie najechania myszką na obiekty podatne efektowi oraz widzialności ich kontenera
	$('.highlights').css('opacity', 0);
	$('#highlightsContainer').css('visibility', 'visible');

	// sprawdzanie każdego elementu podatnego mechanizmowi
	$('.pages').each(function(i) {
		// jeżeli na danym elemencie znajduje się kursor
		$(this).mouseover(function() {
			// wykonanie animacji grafiki wyłanianej i przypisanej do najechanego elementu (margines o 15px w górę i brak przezroczystości w czasie 0,5 sekundy)
			$(highlights[i]).animate({
				opacity: 1,
				marginTop: '-15px'
			}, 500);
		}).mouseout(function(){ // jeżeli na danym elemencie nie znajduje się już kursor
			$(highlights[i]).animate({
				opacity: 0,
				marginTop: '-0px'
			}, 500);
		});
	});
});</pre>
<p>Należy jeszcze wyjaśnić dokładniej w jaki sposób działa <code>$(highlights[i]).animate()</code>. Mianowicie przy każdej iteracji pętli <code>$('.pages').each()</code> przekazuje ona do parametru <code>function(i)</code> aktualny numer elementu na którym się znajduje. Ponieważ w id <code>pageContainer</code> znaczniki potomne muszą być posegregowane i musi być ich tyle samo co obiektów graficznych w <code>highlightsContainer</code> to jeżeli kursor znajduje się na pierwszym podatnym na efekt obrazie to w podświetleniu wyłania się także pierwsza grafika. Wszystko to dzięki wyłuskaniu jej z tablicy <code>highlights</code> poprzez parametr <code>i</code>.</p>
<h2>Krok 6b: Implementujemy kod animacji z użyciem Prototype z Scriptaculous</h2>
<div class="explain"><code>Event.observe</code> &#8211; uchwyt rejestrujący zdarzenie na drzewie dokumentu. Funkcja obiektu składającego się na bibliotekę <strong>Prototype</strong>. Posiada cztery argumenty:
<ul>
<li><strong>element</strong> &#8211; obserwowany element DOM, mogący być referencją do niego bądź jego identyfikatorem,</li>
<li><strong>nazwaZdarzenia</strong> &#8211; standaryzowana wg. <a target="_blank" href="http://utnij.eu/af/"  title="DOM Level 2 Events">DOM Level 2 Events</a> nazwa zdarzenia, np. <strong>load</strong>,</li>
<li><strong>uchwyt</strong> &#8211; uchwyt w postaci funkcji.</li>
</ul>
<p>Przykład:</p>
<pre class="brush: xml; title: ;">&lt;p id=&quot;test&quot;&gt;Prototype&lt;/p&gt;</pre>
<pre class="brush: jscript; title: ;">Event.observe('test', 'click', function() {
	[kod]
});</pre>
</div>
<p>Podobnie w <strong>Prototype</strong> obserwujemy zdarzenie, ale tym razem załadowania całej strony w celu późniejszej obserwacji aktywności kursora na wybranych elementach aktywnych. Można oczywiście podobnie jak w poprzednim podpunkcie wykonać obserwacje zdarzeń wraz z załadowanie DOM (drzewa dokumentu) poprzez użycie <code>document.observe('dom:loaded', function() {})</code>. To tylko kwestia osobistego wyboru.</p>
<pre class="brush: jscript; title: ;">Event.observe(window, 'load', function() {
	[kod]
});</pre>
<p>Dalsze postępowanie jest adekwatne do tego opisanego w przypadku zastosowania <strong>jQuery</strong>. Z tymże, tablicę elementów o danej klasie pobiera się poprzez podwójny znak dolara (<code>$$</code>), a najechanie oraz zjechanie kursorem poza zadany obszar rozpoznaje się także poprzez obiekt <code>Event</code> i metodę <code>observe()</code>. Do animacji służy funkcja <code>Morph</code> instancji <code>Effect</code> z pliku <code>effects.js</code> interfejsu <strong>Scriptaculous</strong >.</p>
<pre class="brush: jscript; title: ;">Event.observe(window, 'load', function() {
	var highlights = $$('.highlights'); // utworzenie tablicy

	$$('.highlights').invoke('setStyle', { opacity: 0 }); // ustawienie stylu przezroczystości
	$$('#highlightsContainer').invoke('setStyle', { visibility: 'visible' }); // widzialność kontenera

	$$('.pages').each(function(v, i) { // pętla
		Event.observe(v, 'mouseover', function() { // zdarzenie wykonywane w momencie pojawienia się kursora na elemencie
			new Effect.Morph(highlights[i], { // animacja
				style: 'opacity: 1; margin-top: -15px;',
				duration: 0.5 // czas 0,5 sekundy
			});
		});
		Event.observe(v, 'mouseout', function() { // zdarzenie wykonywane w momencie wyjechania kursorem poza element
			new Effect.Morph(highlights[i], {
				style: 'opacity: 0; margin-top: 0px;',
				duration: 0.5
			});
		});
	});
});</pre>
<p>Tym razem do funkcji w <code>$$('.pages').each()</code> przekazywane są dwa parametry: <code>v</code> i <code>i</code>. Pierwszy z nich jest odpowiednikiem <code>this</code> i wskazuje na aktualnie przetwarzany element tablicy znaczników o klasie <code>.pages</code>. Drugi to numer pokazujący który z kolei tag jest aktualnie sprawdzany. Inaczej pisząc jego zadanie jest równoznaczne do działania parametru <code>i</code> w przykładzie z <strong>jQuery</strong>.</p>
<div class="explain"><code>Effect.Morph</code> &#8211; metoda interfejsu <code>Scriptaculous</code> >= <strong>1.7</strong>. Pozwala na animacyjną zmianę właściwości CSS elementu. Przyjmuje jeden podstawowy argument <code>style</code> zawierający w sobie właściwości i wartości CSS w formie oryginalnej bądź w postaci <strong>Camel-Case</strong>, czyli bez spacji i znaków specjalnych pomiędzy kilkoma członami nazwy właściwości. Opcjonalnie można dodawać kolejne parametry rdzenia obiektu <code>Effect</code>, takie jak <code>duration</code> (czas animacji), czy <code>transition</code> (rodzaj animacji, wymaga <code>Effect.Transitions</code>).</p>
<p>Przykład:</p>
<pre class="brush: jscript; title: ;">new Effect.Morph('div_id', {
	style: {
		background-color: '#000',
		color: '#fff'
	},
	duration: 0.5,
	transition: Effect.Transitions.spring
});</pre>
</div>
<h2>Demonstracja wyników&#8230;</h2>
<p>Stworzyłem dwa gotowe przykłady, których analiza pozwoli Wam jeszcze bardziej zrozumieć jak stworzyć ten efekt. <a href="http://use.m1chu.eu/-jquery/product-highlighter/"  title="Product Highlighter - jQuery"><strong>Pierwszy</strong></a>, za pomocą jQuery. <a href="http://use.m1chu.eu/-prototype/product-highlighter/"  title="Product Highlighter - Prototype z Scriptaculous"><strong>Drugi</strong></a>, za pomocą Prototype z Scriptaculous.</p>
<p>Jeżeli chcecie dowiedzieć się więcej o tych bibliotekach to zapraszam do ich dokumentacji (<a target="_blank" href="http://www.prototypejs.org/api"  title="API Prototype">Prototype</a>, <a target="_blank" href="http://docs.jquery.com/Main_Page"  title="API jQuery">jQuery</a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://m1chu.eu/2009/02/09/efekt-graficznego-podswietlenia-w-jquery-i-prototype-z-scriptaculous/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Haki CSS i komentarze warunkowe dla niepokornego Internet Explorera</title>
		<link>http://m1chu.eu/2008/12/22/haki-css-dla-niepokornego-internet-explorera/</link>
		<comments>http://m1chu.eu/2008/12/22/haki-css-dla-niepokornego-internet-explorera/#comments</comments>
		<pubDate>Mon, 22 Dec 2008 02:10:56 +0000</pubDate>
		<dc:creator>m1chu</dc:creator>
				<category><![CDATA[(x)HTML]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Webhosting]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[haki]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[komentarze warunkowe]]></category>
		<category><![CDATA[xhtml]]></category>

		<guid isPermaLink="false">http://m1chu.eu/?p=372</guid>
		<description><![CDATA[Dla zwykłego użytkownika Internet Explorer to po prostu pierwsza linia dostępu do Internetu. Nie każdy z nich wie jednak, że jest to linia stosunkowo mało bezpieczna i niestabilna. Wiele mówi się o istniejących już od wielu lat i ciągle rozwijanych alternatywach. I pomimo, że sporo osób skusiło się już na wymianę używanej przeglądarki to rynek [...]]]></description>
			<content:encoded><![CDATA[<div style="float: left; display: inline; width: 70%; height: 205px;">
<p>Dla zwykłego użytkownika <strong>Internet Explorer</strong> to po prostu pierwsza linia dostępu do Internetu. Nie każdy z nich wie jednak, że jest to linia stosunkowo mało bezpieczna i niestabilna. Wiele mówi się o istniejących już od wielu lat i ciągle rozwijanych <a href="http://browsehappy.pl/"  title="BrowseHappy - alternatywne przeglądarki!" onclick="this.target='_blank';">alternatywach</a>. I pomimo, że sporo osób skusiło się już na wymianę używanej przeglądarki to rynek nie tylko najnowszej, ale i starszych odsłon IE jest nadal prężny. Zbyt prężny, co najbardziej odbija się na twórcach witryn internetowych. Niepodporządkowanie się standardom powoduje, że często aby praca wychodząca spod ich ręki była prawidłowo interpretowana przez przeglądarkę Microsoftu trzeba użyć pewnego typu zamienników&#8230;</p>
</div>
<div style="float: left; display: inline; width: 30%; text-align: center; height: 205px;"><img class="iborder" src="http://farm4.static.flickr.com/3072/2986531107_2b71aa262b_o.png" alt="Stop użytkowaniu IE!" style="height: 159px; margin-top: 20px;" /></div>
<p><span id="more-372"></span></p>
<h2>Dlaczego dyskryminuję IE?</h2>
<p>Bo mam przez tą przeglądarkę więcej pracy. Pracy której by nie było, gdyby wielce wykształceni, po jeszcze większych pod względem stopnia prestiżu uczelniach programiści potrafili &#8222;sklepać&#8221; ten twór porządnie, wg. istniejących od wielu lat standardów. I nie tylko mi to przysparza nerwów. Wiem, wiem &#8211; za chwilę znajdzie się tutaj jakiś specjalista z ogromnej korporacji developerskiej który wytknie mi, że nie szanuję przez to swoich klientów. Ich akurat traktuję poważnie i poświęcam swój czas w takiej ilości, aby zrobić co ma być wykonane porządnie. W hobbistycznych projektach powiem dobitnie i szczerze&#8230; w pewnym stopniu lekceważę użytkowników tegoż browsera. Przynajmniej tych którzy świadomie go używają i co najmniej w wersjach niższych niż siódemka. Bo z całej serii chłamu którą wydała korporacja z Redmond tylko ostatnia, &#8222;stabilna&#8221; (z nazwy) wersja choć odrobinę pokrywa się z wyznaczonymi regułami. Użytkownikom wersji szóstej&#8230; współczuję, a ci którzy z premedytacją korzystają z jeszcze starszych odsłon nie zasługują nawet na to.</p>
<p>Żeby nie być gołosłownym wypadałoby podać kilka przyczyn moich ostrych słów.</p>
<ul>
<li>ilość wykrywanych luk i prędkość ich łatania jest niekiedy zastraszająco długa &#8211; przykładem są tutaj niektóre błędy opisane na <a href="http://utnij.eu/secunia_ie7/"  title="Secunia - IE7" onclick="this.target='_blank';">Secunii (dla IE7 w tym przypadku)</a>.</li>
<li>fakt braku wsparcia dla wersji niższych niż szósta tej przeglądarki, a co za tym idzie niełatanie dziur wykrywanych w nich (niemiło byłoby wstać kiedyś rano i zobaczyć, że konto bankowe z którego korzystaliśmy dzień wcześniej poprzez przeglądarkę z Redmond jest puste, prawda?).</li>
<li>pomimo zrobienia kilku kroków w przód nadal MSIE jest jednym z wolniejszych tego typu rozwiązań.</li>
<li>jest wiele alternatyw takich jak <a href="http://utnij.eu/get_firefox/"  title="Pobierz najnowszego Firefoxa" onclick="this.target='_blank';"><strong>Firefox</strong></a>, <a href="http://utnij.eu/get_opera/"  title="Pobierz Operę" onclick="this.target='_blank';"><strong>Opera</strong></a> (<a href="http://m1chu.eu/2008/11/16/w-pogoni-za-doskonaleniem-synchronizacji-obslugi-poczty-i-rss-opera-96x/"  title="Recenzja Opery 9.6x"><strong>recenzja Opery 9.6x</strong></a>), czy <a href="http://utnij.eu/get_safari/"  title="Pobierz Safari" onclick="this.target='_blank';"><strong>Safari</strong></a>. Są one proste w obsłudze, wręcz intuicyjne, a dzięki zaimplementowanym, dodatkowym modułom, czy wtyczkom potrafią w znaczny sposób pomóc w surfowaniu po sieci.</li>
<li>alternatywne przeglądarki względnie poprawnie interpretują standardy sieciowe dotyczące wyświetlania stron przez co nigdy nie zobaczysz prawidłowo napisanej strony w niepoprawnie ułożonym stylu.</li>
</ul>
<p>To tylko namiastka różnic. W sieci znajduje się wiele artykułów pokazujących wyższość przeglądarek, jeszcze kilka lat temu niszowych od tej promowanej przez amerykańskiego giganta. Dlatego nawracajcie swoich znajomych, bo w tym wypadku naprawdę &#8222;pozornie inne&#8221; znaczy lepsze&#8230;</p>
<p style="text-align: center;"><img class="iborder" src="http://farm4.static.flickr.com/3183/2986841231_56998c714d_o.png" alt="Ranking przeglądarek polskiej części internetu" style="height: 179px;" /></p>
<h2>Nie w jeden dzień Rzym zbudowano&#8230;</h2>
<p>Pomimo kilku słów mojej dezaprobaty, i wielu przeszłych lat negatywnych opinii innych ludzi nie da się oczywiście z dnia na dzień nawrócić wszystkich &#8222;niewiernych&#8221; :] Dlatego meritum dzisiejszego wpisu będzie tematyka komentarzy warunkowych i haków dla &#8222;zbuntowanej&#8221; przeglądarki.</p>
<p style="text-align: center; font-size: 10px;"><img class="iborder" src="http://farm4.static.flickr.com/3201/3126136255_69a44689eb_o.png" alt="Różne typy komentarzy" style="height: 270px;" /><br />Różne typy komentarzy.</p>
<h2>Ukryte komentarze warunkowe</h2>
<p>Od wersji <strong>5</strong> Internet Explorer obsługuje ukryte (pozytywne) komentarze warunkowe (z angielskiego <em>downlevel-hidden (positive) conditional comments</em>). Obsługuje, ale tylko w wersji pod Windowsem (<em>IE/Win</em>), pod Macintoshem już nie (<em>IE/Mac</em>). W zależności od treści w nich zawartych są one widzialne lub nie przez daną przeglądarkę. Jest to szczególnie przydatne jeżeli dany element strony musimy inaczej opisać w IE, niż w jej zamiennikach. Za pewnie sami twórcy zorientowali się wtedy jaki dziki twór stworzyli i choć ciut chcieli się zrehabilitować pozwalając webmasterom chociażby w nadmiarowy sposób tworzyć strony zgodne z ich &#8222;dziełem&#8221;.</p>
<pre class="brush: plain; title: ;">&lt;!--[if IE]&gt;
kod pomiędzy tymi komentarzami zadziała tylko w odsłonach IE
&lt;![endif]--&gt;</pre>
<p>Oto przykład najprostszego zastosowania komentarzy. Można ją wykorzystać np. w sekcji <code>head</code> w celu zaimportowania arkusza stylów wykorzystywanego przez produkt z Doliny Krzemowej.</p>
<pre class="brush: plain; title: ;">&lt;!--[if IE]&gt;
&lt;link type=&quot;text/css&quot; rel=&quot;stylesheet&quot; href=&quot;ie_only.css&quot; /&gt;
&lt;![endif]--&gt;</pre>
<p>Pierwszy komentarz można także stosownie modyfikować. Obowiązują tu elementy logiczne takie jak negacja, czy znane z systemów *nixowych operatory porównania. Ważnym jest także, aby wiedzieć, że komentarze te istnieją tylko w kodzie (X)HTML, więc jeśli posiadamy na stronie dla przykładu integralny arkusz stylów to nie możemy tychże warunków używać wewnątrz kodu CSS.</p>
<pre class="brush: plain; title: ;">&lt;!-- dla IE 5: --&gt; &lt;!--[if IE 5]&gt;
&lt;!-- dla IE niższego niż 6: --&gt; &lt;!--[if lt IE 6]&gt;
&lt;!-- dla IE równego lub niższego od 7: --&gt; &lt;!--[if lte IE 7]&gt;
&lt;!-- dla IE innego niż 5.5: --&gt; &lt;!--[if !IE 5.500]&gt;
&lt;!-- dla IE równego lub wyższego niż 6: --&gt; &lt;!--[if gte IE 6]&gt;
&lt;!-- dla IE wyższego niż 5: --&gt; &lt;!--[if gt IE 5]&gt;
&lt;!-- dla IE różnego od 6: --&gt; &lt;!--[if !(IE 6)]&gt;
&lt;!-- dla IE 5: --&gt; &lt;!--[if (IE 5)]&gt;
&lt;!-- dla IE 6 i IE 7: --&gt; &lt;!--[if (gt IE 5)&amp;(lte IE 7)]&gt;
&lt;!-- dla IE 5 lub IE 6: --&gt; &lt;!--[if (IE 5)|(IE 6)]&gt;</pre>
<p>Jak można zobaczyć po czwartym przykładzie dozwolone jest używanie wartości <strong>&#8222;po przecinku&#8221;</strong>. Jest to tzw. wektor wersji (z angielskiego <em>version vector</em>) i trzeba w nim użyć 4rech znaków. W praktyce nie używa się tego prócz wersji <strong>5.500</strong>, gdyż różnice pomiędzy poszczególnymi, bardziej skrupulatnymi odsłonami są niewielkie.</p>
<p>Dozwolone są także łączenia warunków za pomocą znaku <strong>&#038;</strong> lub <strong>|</strong> oraz określanie wersji przeglądarki poprzez użycie nawiasów.</p>
<p style="text-align: center; font-size: 10px;"><img class="iborder" src="http://farm4.static.flickr.com/3198/2986980751_da1c718df7_o.png" alt="Operatory porównania wraz z negacją" style="height: 279px;" /><br />Operatory porównania wraz z negacją.</p>
<p>Jest także jeszcze jedna konstrukcja ukrytych komentarzy która pozwala na wysyłanie partii kodu tylko do przeglądarek innych niż IE (a dokładniej ukrywa ona go przed Internet Explorerem). Początkowo miały to wykonywać komentarze odkryte (o których będzie w dalszej części artykułu), ponieważ jednak ingerują one w prawidłowość struktury HTML to można to zrobić poprzez następującą formę.</p>
<pre class="brush: plain; title: ;">&lt;!--[if !IE]&gt;&lt;!--&gt;
kod pomiędzy tymi komentarzami zadziała w przeglądarkach innych niż IE
&lt;!--&lt;![endif]--&gt;</pre>
<p>Posiłkując się ostatnim wersem możemy skonstruować kod który będzie wyświetlał różny tekst w zależności od rodzaju przeglądarki.</p>
<pre class="brush: plain; title: ;">&lt;body&gt;
	&lt;p&gt;
		Używasz
		&lt;!--[if !IE]&gt;&lt;!--&gt;
		diabelsko dobrej, alternatywnej przeglądarki!
		&lt;!--&lt;![endif]--&gt;
		&lt;!--[if lt IE 7]&gt;
		archaicznego i dzurawego kodu insynującego miano przeglądarki :(
		&lt;![endif]--&gt;
		&lt;!--[if IE 7]&gt;
		przeglądarki która pretenduje do tego miana... z mizernym skutkiem :/
		&lt;![endif]--&gt;
	&lt;/p&gt;
&lt;/body&gt;</pre>
<p>Co w rezultacie da (zauważ, że wynik będzie się różnił w zależności od używanej przez Ciebie przeglądarki):</p>
<p style="padding: 20px; background-color: #f6f7ee; border: 2px solid #DEDBD1;">Używasz: <strong><!--[if !IE]><!-->diabelsko dobrej, alternatywnej przeglądarki!<!--<![endif]--><!--[if lt IE 7]>archaicznego i dzurawego kodu insynującego miano przeglądarki :(<![endif]--><!--[if IE 7]>przeglądarki która pretenduje do tego miana&#8230; z mizernym skutkiem :/<![endif]--></strong></p>
<h2>Ciekawostka w postaci odkrytych komentarzy warunkowych</h2>
<p>Odkryte (negatywne) komentarze warunkowe (z angielskiego <em>downlevel-revealed (negative) conditional comments</em>) jak już wspomniałem miały służyć do ukrywania kodu bądź tekstu przed przeglądarkami IE lub przed ich konkretnymi wersjami (np. przed wersjami obsługującymi ukryte komentarze warunkowe, czyli <strong>>= 5.0</strong>). Ich użycie powoduje, że strona przestaje być prawidłowym dokumentem (X)HTML, dlatego nie zalecam ich stosowania.</p>
<pre class="brush: plain; title: ;">&lt;![if !IE]&gt;
kod pomiędzy tymi komentarzami zadziała w przeglądarkach innych niż IE
&lt;![endif]&gt;</pre>
<p>Zaleca się jednak używanie alternatywnej, już wspomnianej w poprzednim paragrafie techniki &#8222;pozytywnych komentarzy&#8221;.</p>
<pre class="brush: plain; title: ;">&lt;!--[if !IE]&gt;&lt;!--&gt;
&lt;script src=&quot;ie_javascript.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;!--&lt;![endif]--&gt;</pre>
<p>Anglojęzyczne tłumaczenie specyfiki komentarzy warunkowych można zaczerpnąć z <a target="_blank" href="http://utnij.eu/10a891e/"  title="MSDN CC">MSDN</a>.</p>
<h2>Elementarz komentarzy warunkowych w JavaScript / JScript!</h2>
<p>Nie każdy wie, że od <strong>4rtej</strong> odsłony MSIE także komentarze warunkowe dostępne są w kodzie <strong>Javascript / JScript</strong>.</p>
<pre class="brush: jscript; title: ;">&lt;script type=&quot;text/javascript&quot;&gt;
/*@cc_on
Kod warunkowy
@*/
&lt;/script&gt;</pre>
<p>W dyrektywę <code>/*@cc_on</code> i <code>@*/</code> wstawiamy kod warunkowy. Pierwsza fraza pochodzi od angielskiego <em>Conditional Compilation</em>, czyli po polsku kompilacja warunkowa.</p>
<p>Same warunki opierają się o dyrektywy <code>@if</code> (jeżeli), <code>@elif</code> (inaczej jeżeli), <code>@else</code> (ostatecznie jeżeli) i <code>@end</code> (ostateczna wytyczna). Same użycie instrukcji warunkowych nie pozwoli nam na sprawdzenie jakiej przeglądarki używa użytkownik. Należy po danej nazwie dyrektywy dodać <code>@*/</code> co spowoduje, że zostanie wykonana ona w przeglądarkach alternatywnych.</p>
<pre class="brush: jscript; title: ;">/*@cc_on
   @if (@_x86)
      document.write(&quot;Przeglądarka IE, 32bitowy procesor Intela&quot;)
   @else
      document.write(&quot;Przeglądarka IE, inny procesor&quot;);
   @end
@*/</pre>
<p>Nie umieściliśmy po pierwszym warunku podanego wyżej ciągu znaków, dlatego obydwa warunki zostaną wykonane w wypadku Internet Explorera. Można jednak zmusić skrypt do odniesienia się w przypadku <code>@else</code> tylko jeżeli nie korzystamy z IE.</p>
<pre class="brush: jscript; title: ;">/*@cc_on
   /*@if (@_x86)
      document.write(&quot;Przeglądarka IE, 32bitowy procesor Intela&quot;)
   @else @*/
      document.write(&quot;Przeglądarka alternatywna, inny procesor&quot;);
   /*@end
@*/</pre>
<p>W tym wypadku część <code>document.write("Przeglądarka alternatywna, inny procesor");</code> została odkomentowana i zostanie wykonana w przypadku użycia alternatywnych browserów.</p>
<p>Można spytać w tym momencie: &#8222;w jaki sposób wykryć wersję Microsoftowskiej przeglądarki?&#8221;. W dwóch wcześniejszych przykładach zawarłem warunki z argumentem tego typu: <code>@_x86</code>. Jest to jedna z wbudowanych, przedefiniowanych zmiennych których ogółem jest dwanaście (o tylu przynajmniej wiem, a jedną z nich celowo pominąłem z racji zwracania stałej wartości).</p>
<p style="text-align: center; font-size: 10px;"><img class="iborder" src="http://farm4.static.flickr.com/3229/2988158568_e21601dd3c_o.png" alt="Predefiniowane zmienne kompilacji warunkowych" style="height: 980px;" /><br />Predefiniowane zmienne kompilacji warunkowych.</p>
<p>Dla przykładu wykorzystując wiedzę o tym, że wersja <strong>JScript 3.x</strong> była zaimplementowana w <strong>IE4</strong>, wersja <strong>4</strong> do <strong>5.5</strong> w <strong>IE5+</strong>, a <strong>5.6</strong> w <strong>IE6</strong> możemy poprzez użycie zmiennej <code>@_jscript_version</code> utworzyć odpowiednie komentarze warunkowe.</p>
<pre class="brush: jscript; title: ;">/*@cc_on
   /*@if (@_jscript_version &lt; 4)
      document.write(&quot;Internet Explorer 4&quot;);
   @elif (@_jscript_version &lt;= 5.5)
      document.write(&quot;Internet Explorer 5+&quot;);
   @elif (@_jscript_version == 5.6)
      document.write(&quot;Internet Explorer 6/7&quot;);
   @else @*/
      document.write(&quot;Alternatywa :D&quot;);
   /*@end
@*/</pre>
<p>Ostatecznie jeżeli będziemy mieć taką potrzebę możemy posiłkować się użyciem własnych zmiennych, definiując je poprzez dyrektywę <code>@set</code>.</p>
<pre class="brush: jscript; title: ;">/*@cc_on
   @set zmiennax = 4;
   @set zmiennay = @_jscript_version;
   /*@if (@zmiennay != @zmiennax)
      document.write(&quot;To nie jest IE4!&quot;)
   @else
      document.write(&quot;IE4 :(&quot;);
   @end
@*/</pre>
<h2>Ciekawostka numer dwa &#8211; tag <em>comment</em></h2>
<p>Drugą ciekawostką dzisiejszego artykułu której nie powinno się stosować z tego samego powodu co poprzedniej jest tag <code>comment</code>. Nie jest to standardowy znacznik ani HTML-a, ani XHTML-a. IE potraktuje go jako zwykły komentarz. Inne przeglądarki powinny za to wyświetlić tekst znajdujący się w nim. Dodatkową różnicą jest fakt, że w tym wypadku i <strong>IE/Win</strong>, i <strong>IE/Mac</strong> tak samo wspierają tą &#8222;funkcjonalność&#8221;, przez co tekst będzie niewidoczny w obydwu wersjach.</p>
<pre class="brush: xml; title: ;">&lt;p&gt;To &lt;comment&gt;nie&lt;/comment&gt; jest MSIE.&lt;/p&gt;</pre>
<p style="padding: 20px; background-color: #f6f7ee; border: 2px solid #DEDBD1;">To <comment><strong>nie</strong></comment> jest MSIE.</p>
<h2>Omijamy niedoskonałości interpretowania CSS przez MSIE (haki)</h2>
<p>Haki CSS to konstrukcje zmieszania różnorodnych znaków z regułami dostępnymi standardowo w arkuszach stylów. Nowoczesne przeglądarki takie konstrukcje w zależności od formy pominą lub zmodyfikują do prawidłowego stylu. IE ich nie ignoruje, po prostu na nich operuje. Nawet w siódmej odsłonie&#8230;</p>
<p>Standardowym hakiem jest użycie <code>*</code> przed daną dyrektywą CSS. Zadziała ona we wszystkich wersjach tej przeglądarki, poczynając od <strong>piątki</strong> i patrząc wzwyż.</p>
<pre class="brush: css; title: ;">p {
	background-color: #fff;
	* background-color: #000; /* zadziala tylko w 8 &gt; IE &gt; 4 */
}</pre>
<p>Krótko wyjaśniając. Wszystkim przeglądarkom obsługującym arkusze stylów zostanie przekazany <strong>biały</strong> kolor tła dla elementu <code>p</code>, z tymże dla Internet Explorera dodatkowo dyrektywa ta zostanie nadpisana tak, że w rezultacie kolor tego tła będzie w nim <strong>czarny</strong> (druga linijka).</p>
<pre class="brush: css; title: ;">* html #id {
	background-color: #ccc; /* nada elementowi o identyfikatorze id tło o odcieniu szarym */
}</pre>
<p>Oto inny sposób użycia &#8222;gwiazdki&#8221;. Sposób który działa tylko i wyłącznie na <strong>IE6</strong>.</p>
<pre class="brush: css; title: ;">*+html #id {
	background-color: #ccc; /* nada elementowi o identyfikatorze id tło o odcieniu szarym */
}</pre>
<p>Jak przypomniał <strong>_wsl</strong> z <a target="_blank" href="http://www.webhosting.pl/Haki.CSS.i.komentarze.warunkowe.dla.niepokornego.Internet.Explorera"  title="webhosting.pl">webhosting.pl</a>, aby wyselekcjonować właściwości w selektorze tylko dla <strong>IE7</strong> należy posłużyć się powyższa konstrukcją, która od poprzedniej różni się tylko <strong>plusem</strong> umieszczonym za znakiem gwiazdki. Obydwa powyższe przykłady są zgodne ze standardami CSS.</p>
<p>Jeśli na początku właściwości umieścimy znak <code>_</code> to ograniczymy renderowanie dla wersji <strong>5.5</strong> i <strong>6.0</strong>. Dodanie podkreślenia, bądź myślnika (co znane jest z używania rozszerzeń poszczególnych przeglądarek, opisywanych przeze mnie np. <a href="http://m1chu.eu/webmastering/efekt-rollover-w-css-bez-przeladowywania-obrazka"  title="Efekt sliding-doors"><strong>tutaj</strong></a>) jest dozwolone wg. specyfikacji co znaczy, że użycie takiej formy dyrektywy nie pozbywa nas walidacji dokumentu CSS.</p>
<pre class="brush: css; title: ;">div#special p {
	margin-left: 10px;
	_margin-left: 15px; /* styl zadziała tylko w IE5.5 i IE6 */
}</pre>
<p>W podobny sposób poprzez użycie <strong>backslasha</strong> (<code>\</code>) wewnątrz właściwości możemy ograniczyć jej działanie do przeglądarek (!IE) z numerkami innymi niż <strong>5.x</strong> (czyli praktycznie zezwolić na działanie w każdej innej wersji i we wszystkich pozostałych browserach). Należy wiedzieć także, że hak ten nie zadziała jeżeli ukośnik wsteczny umieścimy na początku frazy.</p>
<pre class="brush: css; title: ;">#container {
	width: 250px;
	widt\h: 500px; /* tylko dla IE5.x szerokość nie zostanie nadpisana do 500px */
}

#withBorder {
	border: 1px solid #ccc;
	bor\der: 5px solid #ccc; /* tylko dla IE5.x szerokość krawędzi nie zostanie nadpisana do 5px */
}</pre>
<p>Idąc za rozwiązaniem na <a target="_blank" href="http://utnij.eu/tantek_hacks/"  title="Tantek">Tantek.com</a> możemy uzyskać powyższy wynik także poprzez następującą konstrukcję.</p>
<pre class="brush: css; title: ;">.hack {
	height: 800px; /* dla IE5.x/Windows */
	voice-family: &quot;\&quot;}\&quot;&quot;; /* selektor nie bedzie dalej przetwarzany dla powyzszego przykladu */
	voice-family: inherit;
	height: 640px; /* nadpisanie w alternatywach */
}</pre>
<p>Podatne na ten błąd wersje możemy oczywiście zmusić w inny sposób do prawidłowej interpretacji arkusza.</p>
<pre class="brush: css; title: ;">html&gt;body .hack { /* bez spacji przy &gt; */
  	height: 640px;
}</pre>
<p>Komuś może nasunąć się teraz pytanie, jak odróżnić już wspomniane przeze mnie tutaj wersje piątą na Macinthosha i Windowsa?</p>
<pre class="brush: css; title: ;">/* poczatek dla IE5/Mac \*/
#ieMac {
	height: 50px;
}
/* koniec */ </pre>
<p>Oto konstrukcja którą należy użyć, aby zaaprobować styl pod <strong>IE/Mac</strong>.</p>
<pre class="brush: css; title: ;">/* poczatek dla innych niz IE5/Mac *//*/
#notIeMac {
	height: 150px;
}
/* */</pre>
<p>A tak wyglądałoby to dla przeglądarek innych niż <strong>IE/Mac</strong>. Bardzo fajnie (w języku angielskim) jest to opisane na <a href="http://utnij.eu/ie5mac_bpf/"  title="IE5/Mac Filter" onclick="this.target='_blank';">StopDesign</a>.</p>
<p>Co mogliście zauważyć większość z tych metod pomija siódme wydanie Internet Explorera. Developerzy tej wersji już dawno na swoim blogu <a href="http://utnij.eu/no_hacks_in_ie7/"  title="MSDN Blog" onclick="this.target='_blank';">pisali, aby usunąć ze swoich stron haki</a>. W najnowszej wersji przeglądarki został zastosowany tryb zbliżonej kompatybilności z standardami, pewnie stąd te zalecenia. Nie mniej jednak grupa konstrukcji związanych z własnościami pozostała i po części została rozszerzona.</p>
<pre class="brush: css; title: ;">/* zbior hackow dla IE7 */
html {
	` background: #cdcdcd;
	~ background: #cdcdcd;
	! background: #cdcdcd;
	@ background: #cdcdcd;
	# background: #cdcdcd;
	$ background: #cdcdcd;
	% background: #cdcdcd;
	^ background: #cdcdcd;
	&amp; background: #cdcdcd;
	* background: #cdcdcd;
	( background: #cdcdcd;
	) background: #cdcdcd;
	= background: #cdcdcd;
	+ background: #cdcdcd;
	[ background: #cdcdcd;
	] background: #cdcdcd;
	{ background: #cdcdcd;
	| background: #cdcdcd;
	, background: #cdcdcd;
	&lt; background: #cdcdcd;
	. background: #cdcdcd;
	&gt; background: #cdcdcd;
	/ background: #cdcdcd;
	? background: #cdcdcd;
}</pre>
<p>Znakami które sprawiają, że IE7 zaczyna interpretować regułę są więc praktycznie wszystkie dostępne spoza polskiego alfabetu na standardowej klawiaturze użytkownika. Co ciekawsze można je w specyficzny sposób łączyć co daje efekt równoznaczny z pojedynczą linią ostatniego przykładu z tymże dla poprzednich odsłon browsera.</p>
<pre class="brush: css; title: ;">.zlaczone {
	`~!@#$%^&amp;* background: #cdcdcd; /* &lt; IE 7 */
}</pre>
<p>We wszystkich wersjach obsługujących haki prócz siódmej (jej niestabilne odsłony są jednak jeszcze podatne na ten błąd) możemy do właściwości dodać <code>!important</code> o wyższym priorytecie niż zwykła reguła i nieobsługiwanym w takim wypadku przez wcześniej wymienione przeglądarki.</p>
<pre class="brush: css; title: ;">div#dzialanieImportant {
	width: 800px !important; /* inne */

	width: 640px; /* IE5.x / IE6.x / IE7beta */
}</pre>
<h2>No i na finiszu zarys rozszerzenia <em>expressions</em></h2>
<p>Kiedy każda z powyższych metod zawodzi z ostateczną pomocą (pomijając rozwiązania zewnętrzne) przychodzi nam metoda zaawansowanego użytkowania haków z poziomu CSS, czyli rozszerzenie <strong>expressions</strong>.</p>
<div class="explain">
<p><strong>expressions</strong> (dynamiczne właściwości) &#8211; rozszerzenie przeglądarek IE (włącznie z siódmą odsłoną) pozwalające na używanie pseudokodu JavaScript (gdyż jest on ograniczony strukturą CSS, czego przykładem jest brak możliwości deklaracji zmiennych za pomocą <strong>var</strong>, czy używanie przecinków zamiast średników) na elementach arkusza stylów.</p>
<p><strong>Składnia:</strong></p>
<pre class="brush: css; title: ;">blok {
	własciwość: expression(JavaScript);
}</pre>
</div>
<p>Nie przeprowadzę tu wykładu na temat JavaScript, którego znajomość jest niezbędna do operowania na <em>expressions</em>. Podam jednak kilka przykładów obrazujących co może być parametrem tego rozszerzenia.</p>
<p>Elementarnymi słowami kluczowymi są <code>document</code> (będący obiektem) oraz <code>this</code> (będący referencją do aktualnie przetwarzanego obiektu). W pierwszym wypadku używając odpowiednich właściwości możemy na przykład ustawić absolutną pozycję danego elementu względem rozmiarów okna przeglądarki, bądź nadać stronie maksymalną, dozwoloną szerokość względem rozdzielczości ekranu użytkownika (czego nie da się zrobić w starszych odsłonach Internet Explorera z powodu nie obsługiwania przez nie dyrektyw <code>max-height</code>, <code>min-height</code>, <code>max-width</code> i <code>min-width</code>). Przedstawiam dwa przykłady, które tylko i wyłącznie mają zobrazować możliwości operowania JS-em w kodzie CSS.</p>
<pre class="brush: css; title: ;">div#container {
	max-width: 800px;
	/* ponizej mamy dwa przyklady tzw. wyrazenia dynamicznego */
	width: expression(document.body.clientWidth &gt; 800 ? &quot;800px&quot; : &quot;100%&quot;); /* ustawi 800px szerokosci jezeli szerokosc klienta jest wieksza niz 800px, w przeciwnym wypadku nastąpi skalowanie do tej wartosci */
	min-height: 600px;
	height: expression(document.body.clientHeight &lt; 600 ? &quot;100%&quot; : &quot;600px&quot;); /* ustawi 100% wysokosci jezeli wysokosc klienta jest mniejsza niz 600px, w przeciwnym wypadku nastąpi skalowanie do tej wartosci */
}</pre>
<pre class="brush: css; title: ;">p#logo {
	position: absolute;
	left: expression((document.body.offsetWidth - 500) + &quot;px&quot;); /* ustalenie pozycji lewej wzgledem szerokosci okna przegladarki - dla XHTML nalezaloby posilkowac sie obiektem window */
	bottom: expression((document.body.offsetHeight - 200) + &quot;px&quot;); /* ustalenie pozycji dolnej wzgledem wysokosci okna przegladarki - dla XHTML nalezaloby posilkowac sie obiektem window */
	color: expression(this.parentNode.lastChild.style.color = '#f0f0f0'); /* ustalenie koloru czcionki ostatniego potomka rodzica przetwarzanego elementu DOM */
	width: 300px;
	height: 20px;
}</pre>
<p>W wypadku zmiany koloru skorzystaliśmy z konstrukcji odniesienia się do rodzica elementu (<code>parentNode</code>), po czym do ostatniego potomka tegoż rodzica (<code>lastChild</code>), by na koniec po prostu nadać pożądany kolor (<code>style.color</code>). </p>
<p>W wypadku stylów możemy nadać wartość własności także poprzez <code>setProperty()</code> zalecane przez W3C.</p>
<pre class="brush: css; title: ;">color: expression(this.parentNode.lastChild.style.setProperty(&quot;color&quot;, &quot;#f0f0f0&quot;, null)); /* forma preferowana przez w3c */</pre>
<p>Takich własności jest oczywiście więcej, a przykładami są:</p>
<ul>
<li>wspomniane <code>parentNode</code> &#8211; wskazuje na rodzica elementu w drzewie dokumentu,</li>
<li><code>childNodes</code> &#8211; tablica elementów potomnych, których istnienie można sprawdzić poprzez użycie metody <code>.hasChildNodes()</code> lub przez sprawdzenie jej długości argumentem <code>.length</code>. Do danych potomków odnosimy się jak do zwykłej tablicy, czyli np. <strong>3ci</strong> element odczytywalibyśmy w formie <code>element.childNodes[2];</code>,</li>
<li><code>firstChild</code> &#8211; pierwszy element potomny,</li>
<li><code>lastChild</code> &#8211; ostatni element potomny,</li>
<li><code>previousSibling</code> &#8211; poprzedni element,</li>
<li><code>nextSibling</code> &#8211; następny element,</li>
<li><code>nodeName</code> &#8211; nazwa aktualnego elementu,</li>
<li><code>nodeValue</code> &#8211; wartość aktualnego elementu.</li>
</ul>
<p style="text-align: center; font-size: 10px;"><a target="_blank" href="http://farm4.static.flickr.com/3271/2996137314_982227421d_o.png"  title="Własności DOM dla drzewa dokumentu" class="lightbox"><img class="iborder" src="http://farm4.static.flickr.com/3271/2996137314_44709a2649.jpg" alt="Własności DOM dla drzewa dokumentu" style="height: 279px;" /></a><br />Własności DOM dla drzewa dokumentu.</p>
<p>Korzystając z tego rozszerzenia należy to robić z reguły w osobnym arkuszu przeznaczonym tylko dla MSIE. Jeżeli robimy to jednak w arkuszu ogólnodostępnym to zaleca się poprzedzanie właściwości ciągiem <code>-ie</code> (podobnie jak dla przeglądarek fundacji Mozilla stosuje się <code>-moz</code>).</p>
<pre class="brush: css; title: ;">div#practiceEval {
	-ie-noeval = expression(p = document.createElement(&quot;p&quot;), this.parentNode.appendChild(p));
	-ie-witheval = expression(get_width = document.body.clientWidth,
		eval(if ( get_width &gt; 800 ) {
			this.appendChild(document.createTextNode(get_width))
		})
	);
}</pre>
<p>I na koniec bardziej skomplikowany, finalny przykład. Pierwsza właściwość tworzy tag typu <code>p</code> i przenosi go na koniec zawartości rodzica. Ma on ukazać użycie <strong>przecinka</strong> zamiast <strong>średnika</strong> w wielolinijkowym kodzie. W <code>-ie-witheval</code> użyliśmy za to funkcji <code>eval()</code> dzięki której w jej parametrze mogą znajdować się wyrażenia zawierające takie elementy jak instrukcje warunkowe, czy wyłapywanie błędów. Nadal jednak niedozwolona jest deklaracja zmiennych z użyciem wyrażenia <code>var</code> oraz posługiwanie się średnikami w celu oddzielenia partii kodu.</p>
<h2>Wspomniałeś coś o rozwiązaniach zewnętrznych, to znaczy?</h2>
<p>Jednym z takich rozwiązań jest skrypt (o wielkości <strong>1kB</strong>!) <a target="_blank" href="http://utnij.eu/css_browser_selector/"  title="CSS Browser Selector">CSS Browser Selector</a> który dzięki możliwości dodawania do właściwości nazw klasy określających przeglądarkę lub system ułatwia pisanie pod nie kodu arkusza stylów.</p>
<pre class="brush: css; title: ;">.win.ie5 #test {
	margin: 5px
}</pre>
<p>Powyższy kod ustawiony zostanie dla identyfikatora <strong>test</strong> i przeglądarki IE5 systemu Windows. Nadany zostanie oczywiście margines o szerokości pięciu pikseli.</p>
<p>Skrypt korzysta z JavaScriptu co może powodować, że nie zostanie on zaaplikowany każdemu użytkownikowi, albo zostanie to wykonane dopiero po załadowaniu DOM.</p>
<p>&#8212;&#8211;</p>
<p>Coś niezrozumiałego? Jakieś pytania? Zapraszam do komentowania.</p>
]]></content:encoded>
			<wfw:commentRss>http://m1chu.eu/2008/12/22/haki-css-dla-niepokornego-internet-explorera/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Jak poprawnie osadzić Flasha w kodzie (X)HTML strony?</title>
		<link>http://m1chu.eu/2008/12/14/jak-poprawnie-osadzic-flasha-w-kodzie-xhtml-strony/</link>
		<comments>http://m1chu.eu/2008/12/14/jak-poprawnie-osadzic-flasha-w-kodzie-xhtml-strony/#comments</comments>
		<pubDate>Sun, 14 Dec 2008 22:22:58 +0000</pubDate>
		<dc:creator>m1chu</dc:creator>
				<category><![CDATA[(x)HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Webhosting]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[embed]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[flash satay]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[object]]></category>
		<category><![CDATA[param]]></category>
		<category><![CDATA[swfobject]]></category>
		<category><![CDATA[ufo]]></category>
		<category><![CDATA[xhtml]]></category>

		<guid isPermaLink="false">http://m1chu.eu/?p=707</guid>
		<description><![CDATA[Walidacja kodu jest istotna. Nieważne czy powodem jest chęć wyszlifowania w sobie dobrych nawyków, czy po prostu zwykła i naturalna potrzeba poprawienia napisanego przez siebie kodu. Co jednak jeżeli tworzysz stronę wg. przyjętych w specyfikacji zasad, z dumą chcesz umieścić na niej odnośnik potwierdzający poprawność kodu zawierającego animację Flash i nagle spotka Cię niemiła niespodzianka? [...]]]></description>
			<content:encoded><![CDATA[<div style="float: left; display: inline; width: 40%; text-align: center; padding-top: 5px; height: 270px;"><img class="iborder" src="http://farm4.static.flickr.com/3169/3101822023_c88251641c_o.png" alt="osadzanie flasha" style="height: 260px;" /></div>
<div style="float: left; display: inline; width: 60%; height: 290px;">
<p>Walidacja kodu jest istotna. Nieważne czy powodem jest chęć wyszlifowania w sobie dobrych nawyków, czy po prostu zwykła i naturalna potrzeba poprawienia napisanego przez siebie kodu. Co jednak jeżeli tworzysz stronę wg. przyjętych w specyfikacji zasad, z dumą chcesz umieścić na niej odnośnik potwierdzający poprawność kodu zawierającego animację Flash i nagle spotka Cię niemiła niespodzianka? I wszystko poprzez krążące po zaułkach Internetu niepoprawne konstrukcje osadzania wcześniej wymienionej technologii&#8230;</p>
<p>W jaki sposób poprawnie implementować Flash? Jakich zastępczych metod można używać? Co jest sprawcą tego, że z reguły nasz kod jest nieprawidłowy? Ten artykuł odpowie Ci na wszystkie powyższe pytania&#8230;</p>
</div>
<p><span id="more-707"></span></p>
<h2>Internet źródłem nieprawidłowego rozwiązania&#8230;</h2>
<p>Pomimo tego, że treści dostępne w kanonach sieci są podatne na &#8222;proces edukacji&#8221; i powoli zmieniają swoją zawartość na coraz to bardziej prawidłową, to nadal można znaleźć wiele wyników wyszukiwań które są rozwiązaniami błędnymi. Tak jest także z tematyką poruszaną w tym wpisie.</p>
<pre class="brush: xml; title: ;">&lt;embed type=&quot;application/x-shockwave-flash&quot;
	width=&quot;1024&quot;
	height=&quot;768&quot;
	src=&quot;flash.swf&quot;
	quality=&quot;high&quot;
	bgcolor=&quot;#ffffff&quot;&gt;
	&lt;noembed&gt;
	Przeglądarka nie obsługuje znacznika &quot;embed&quot;, animacja Flash nie zostanie wyświetlona!
	&lt;/noembed&gt;
&lt;/embed&gt;</pre>
<p>Oto przykład jednej z nieprawidłowych solucji. Problemem jest tu znacznik <code>embed</code> który nie jest, ani częścią specyfikacji <strong>HTML4</strong>, ani <strong>XHTML1.x</strong>, a jedynie naleciałością wprowadzoną kiedyś przez programistów <strong>Netscape Navigatora</strong>. Ponieważ jednak jest on wspomagany także przez przeglądarki takie jak <strong>Opera</strong>, <strong>Firefox</strong>, <strong>Safari</strong>, czy <strong>Internet Explorer</strong> przyjęło się pospolicie użytkowanie powyższego, nieprawidłowego rozwiązania (a wszystko za sprawą nieszczęsnego, kapitalistycznego marketingu w postaci bezmyślnego kopiowania danego artykułu ze strony na stronę i czerpania z tego korzyści). Niekiedy można napotkać także poradę w której <code>embed</code> znajduje się w tagu <code>object</code>, które w takim połączeniu jest także błędne.</p>
<div class="explain"><code>embed</code> &#8211; jest znacznikiem wykorzystywanym do wstawiania obiektów typu plugin do kodu strony. <span style="text-decoration: underline;">Niezgodny z specyfikacją <strong>HTML4</strong> i <strong>XHTML1</strong></span>. Obsługiwany jednak przez <strong>Firefoksa 1.0+</strong>, <strong>Mozille 0.6+</strong>, <strong>Operę 3.0+</strong>, <strong>Safari</strong>, <strong>Netscape Navigatora 1.0+</strong> i <strong>Internet Explorera 3.0+</strong>. Obsługuje atrybuty <code>class</code>, <code>dir</code>, <code>hidden</code>, <code>hspace</code>, <code>id</code>, <code>lang</code>, <code>name</code>, <code>pluginpage</code>, <code>src</code> i <code>style</code>. Używany często wraz z <code>noembed</code> (także niezgodnym z w.w. specyfikacjami) którego zawartość wyświetlana jest w momencie kiedy przeglądarka nie obsługuje <code>embed</code>.</p>
<p>Przykład:</p>
<pre class="brush: xml; title: ;">&lt;embed src=&quot;stream.mp3&quot; type=&quot;audio/mp3&quot; style=&quot;width: 640px; height: 480px;&quot;&gt;
	&lt;noembed&gt;
	Tekst dla przeglądarek nie obsługujących &quot;embed&quot;.
	&lt;/noembed&gt;
&lt;/embed&gt;</pre>
</div>
<p>W wyniku, po wykonaniu walidacji otrzymamy kilka błędów związanych z użyciem właśnie tego, nieprawidłowego tagu.</p>
<p style="text-align: center;"><img class="iborder" src="http://farm4.static.flickr.com/3236/3048166631_253abb51ae_o.png" alt="niepoprawność metody z embed" style="height: 215px;" /></p>
<h2>Osadźmy więc poprawnie&#8230;</h2>
<p>Jeżeli chcemy kierować się zaleceniami specyfikacji to musimy skupić się jedynie na znacznikach <code>object</code> z zaaplikowanymi wewnątrz sparametryzowanymi tagami <code>param</code> (metoda nazwana <em>Flash Satay</em>). Od tego momentu <code>embed</code> przechodzi w niepamięć, bo tak naprawdę wszystko co dzięki niemu mogliśmy osiągnąć, będziemy mogli stworzyć także poprzez naszą nową formułę.</p>
<div class="explain"><code>object</code> &#8211; pozwala na wstawienie do dokumentu obiektu multimedialnego. Zaimplementowany w przeglądarkach <strong>Firefox 0.1+</strong>, <strong>Opera 4.0+</strong>, <strong>Mozilla 0.6+</strong>, <strong>Safari</strong>, <strong>Netscape Navigator 6.0+</strong> i <strong>Internet Explorer 3.0+</strong>. Służy za zamiennik m.in. dla niepoprawnych <code>bgsound</code>, czy <code>embed</code>. Znacznik ten jest częścią specyfikacji <strong>HTML 4.01 Strict/Transitional/Frameset</strong>, <strong>XHTML 1.0 Strict/Transitional/Frameset</strong> oraz <strong>XHTML 1.1</strong>. Obsługuje atrybuty takie jak: <code>accesskey</code>, <code>archive</code>, <code>class</code>, <code>classid</code>, <code>codebase</code>, <code>codetype</code>, <code>data</code>, <code>dir</code>, <code>id</code>, <code>lang / xml:lang</code>, <code>name</code>, <code>style</code>, <code>title</code>, <code>type</code> i <code>xmlns</code>.</p>
<p>Przykład:</p>
<pre class="brush: xml; title: ;">&lt;!-- próba załadowania pliku MOV typu QuickTime --&gt;
&lt;object data=&quot;katalog/film.mov&quot; type=&quot;video/quicktime&quot; style=&quot;width: 640px; height: 480px;&quot;&gt;
	&lt;!-- jeżeli plik MOV nie będzie mógłbyć załadowany zostanie podjęta próba załadowania w jego miejsce grafiki o rozszerzeniu PNG --&gt;
	&lt;object data=&quot;katalog/alternatywa.png&quot; type=&quot;image/png&quot; style=&quot;width: 640px; height: 480px;&quot;&gt;
 		&lt;p&gt;
  			Tekst wyświetlany w wypadku nie załadowania jakiegokolwiek z zasobów dwóch powyższych znaczników.
 		&lt;/p&gt;
	&lt;/object&gt;
&lt;/object&gt;</pre>
</div>
<p>Tak więc, aby wkomponować w naszą stronę obiekt Flash musimy określić co najmniej <a target="_blank" href="http://utnij.eu/mimereference/"  title="Lista najpopularniejszych typów MIME">typ</a> tego obiektu (<code>type</code>), plik źródłowy (<code>data</code>) i ostylować jego wymiary (<code>style</code>). Z podanej listy typów MIME dostrzegamy, że pożądanym przez nas jest <strong>application/x-shockwave-flash</strong>. Należy zwrócić uwagę na fakt, że nie korzystamy w ostatnim przypadku bezpośrednio z parametrów <code>height</code> oraz <code>width</code>, a idąc z duchem czasu wykorzystujemy po prostu możliwości wewnętrznego arkusza stylów.</p>
<div class="explain"><code>param</code> &#8211; pozwala na wprowadzenie parametrów do obiektów (<code>object</code>) i apletów (przestarzale za pomocą <code>applet</code>, bądź aktualnie także za pomocą <code>object</code>). Każdy z takowych parametrów musi być ustawiony w osobnym znaczniku <code>param</code>. Jest zgodny z dokumentacją <strong>HTML 4.01 Strict/Transitional/Frameset</strong>, <strong>XHTML 1.0 Strict/Transitional/Frameset</strong> oraz <strong>XHTML 1.1</strong>, a także obsługiwany w przeglądarkach <strong>Firefox 0.1+</strong>, <strong>Opera 4.0+</strong>, <strong>Mozilla 0.6+</strong>, <strong>Netscape Navigator 6.0+</strong> i <strong>Internet Explorer 3.0+</strong>. Obsługuje atrybuty takie jak: <code>id</code>, <code>name</code>, <code>value</code> oraz <code>xmlns</code> (tylko dla <strong>XHTML</strong>).</p>
<p>Przykład dla <strong>XHTML 1.0</strong>:</p>
<pre class="brush: xml; title: ;">&lt;!-- próba załadowania pliku MPG --&gt;
&lt;object data=&quot;katalog/film.mpg&quot; type=&quot;video/mpeg&quot; style=&quot;width: 640px; height: 480px;&quot;&gt;
	&lt;param name=&quot;autoplay&quot; value=&quot;true&quot; /&gt;
	&lt;param name=&quot;pluginspage&quot; value=&quot;http://www.microsoft.com/Windows/Downloads/Contents/Products/MediaPlayer/&quot; /&gt;
	&lt;!-- jeżeli plik MPG nie będzie mógłbyć załadowany zostanie podjęta próba załadowania w jego miejsce filmu w postaci MOV --&gt;
	&lt;object data=&quot;katalog/film.mov&quot; type=&quot;video/quicktime&quot; style=&quot;width: 640px; height: 480px;&quot; title=&quot;Filmik alternatywny!&quot;&gt;
		&lt;param name=&quot;autoplay&quot; value=&quot;true&quot; /&gt;
		&lt;param name=&quot;pluginspage&quot; value=&quot;http://quicktime.apple.com/&quot; /&gt;
	 	&lt;p&gt;
  			Tekst wyświetlany w wypadku nie załadowania jakiegokolwiek z zasobów dwóch powyższych znaczników.
	 	&lt;/p&gt;
	&lt;/object&gt;
&lt;/object&gt;</pre>
<p>Przykład <strong>HTML</strong>:</p>
<pre class="brush: xml; title: ;">&lt;!-- próba załadowania pliku MPG --&gt;
&lt;object data=&quot;katalog/film.mpg&quot; type=&quot;video/mpeg&quot; style=&quot;width: 640px; height: 480px;&quot;&gt;
	&lt;param name=&quot;autoplay&quot; value=&quot;true&quot;&gt;
	&lt;param name=&quot;pluginspage&quot; value=&quot;http://www.microsoft.com/Windows/Downloads/Contents/Products/MediaPlayer/&quot;&gt;
	&lt;!-- jeżeli plik MPG nie będzie mógłbyć załadowany zostanie podjęta próba załadowania w jego miejsce filmu w postaci MOV --&gt;
	&lt;object data=&quot;katalog/film.mov&quot; type=&quot;video/quicktime&quot; style=&quot;width: 640px; height: 480px;&quot; title=&quot;Filmik alternatywny!&quot;&gt;
		&lt;param name=&quot;autoplay&quot; value=&quot;true&quot;&gt;
		&lt;param name=&quot;pluginspage&quot; value=&quot;http://quicktime.apple.com/&quot;&gt;
	 	&lt;p&gt;
  			Tekst wyświetlany w wypadku nie załadowania jakiegokolwiek z zasobów dwóch powyższych znaczników.
	 	&lt;/p&gt;
	&lt;/object&gt;
&lt;/object&gt;</pre>
</div>
<p>Aby mieć pewność, że każda nowoczesna przeglądarka będzie poprawnie egzekwować tą metodą powinniśmy użyć dodatkowo kilku nazw parametrów. W naszym przypadku będą to kolejno ścieżka wraz z nazwą pliku animacji Flash (<code>movie</code>), a także jakość (<code>quality</code>). Nie są to oczywiście wszystkie dostępne własności. Przede wszystkim wśród nich możemy wyróżnić:</p>
<ul>
<li><strong>play</strong> przyjmujące wartość <strong>true</strong> (domyślne) / <strong>false</strong> określające, czy animacja ma być odtwarzana wraz z załadowaniem strony.</li>
<li><strong>loop</strong> przyjmujące także wartość <strong>true</strong> (domyślne) / <strong>false</strong> określające, czy animacja ma być wyświetlana ponownie w pętli po zakończeniu poprzedniego odtwarzania.</li>
<li><strong>bgcolor</strong> przyjmujące wartość <strong>#rrggbb</strong> i określające (szesnastkowo) kolor tła.</li>
<li><strong>menu</strong> przyjmujące wartości <strong>true</strong> (menu z dodatkowymi funkcjami) / <strong>false</strong>.</li>
<li><strong>quality</strong> przyjmujące wartości <strong>best</strong> (najlepsza jakość wraz z Anti-Aliasingiem dla wszystkich elementów), <strong>high</strong> (występuje Anti-Aliasing, ale wygładzanie jest tylko w przypadku statyczności elementów), <strong>autohigh</strong> (w przypadku spadku wydajności usuwa Anti-Aliasing w celu zachowania poziomu szybkości animacji), <strong>medium</strong> (podobnie jak w poprzednim przypadku, ale bez wygładzania), <strong>low</strong> (najsłabsza jakość bez A-A) i <strong>autolow</strong> (Anti-Aliasing włączany jest dopiero w przypadku kiedy pozwalają na to zasoby w takim stopniu, aby nie pojawił się znaczy spadek poziomu prędkości działania animacji).</li>
<li><strong>scale</strong> przyjmujące wartości <strong>exactfit</strong> (klip dopasowany jest do podanych wymiarów), <strong>noborder</strong> (dopasowuje proporcjonalnie skalując animację do obszaru) i <strong>showall</strong> (wyświetla w podanym obszarze bez zmian w proporcjach).</li>
<li><strong>allowscriptaccess</strong> nadaje prawa do wykonywania skryptów od <strong>szóstej</strong> wersji Flasha. Mianowicie: <strong>always</strong> zezwala na wykonywanie wszystkich skryptów, <strong>never</strong> nie zezwala, a <strong>samedomain</strong> pozwala tylko na te dostępne w obrębie poruszanej się domeny.</li>
</ul>
<p>Ponieważ, jak już pewnie zauważyliście wewnątrz najbardziej zagnieżdżonego znacznika <code>object</code> można (lecz oczywiście <strong>nie trzeba!</strong>) umieścić po jego parametrach alternatywnie wyświetlany kod to w naszym przykładzie wyświetlimy w takim wypadku grafikę o takich samych rozmiarach.</p>
<pre class="brush: xml; title: ;">&lt;object type=&quot;application/x-shockwave-flash&quot;
	data=&quot;skompilowany_flash.swf&quot;
	style=&quot;width: 1024px; height: 768px;&quot;&gt;
	&lt;param name=&quot;movie&quot;
		value=&quot;skompilowany_flash.swf&quot; /&gt;
	&lt;param name=&quot;quality&quot;
		value=&quot;best&quot; /&gt;
	&lt;img src=&quot;zastepcza_grafika.png&quot;
		style=&quot;width: 1024px; height: 768px;&quot;
		alt=&quot;Brak pluginu Flash&quot; /&gt;
&lt;/object&gt;</pre>
<p>Powyższy przykład będzie poprawny dla kodu <strong>XHTML</strong>. Dla czystego <strong>HTML-a</strong> należy formę zminimalizowaną parametrów oraz opcjonalnej grafiki (<strong> /></strong>) zamienić na tradycyjną, bądź w ogóle tych znaczników nie zamykać.</p>
<p><a href="http://use.m1chu.eu/-html/flash-satay/"  title="Przykład">Zapraszam do przejrzenia przykładu implementacji metody</a>.</p>
<p style="text-align: center;"><img class="iborder" src="http://farm4.static.flickr.com/3233/3054352334_9e19a43902_o.png" alt="Poprawny rezultat po użyciu object i param" style="height: 215px;" /></p>
<h2>Rozwiązanie problemów z ładowaniem dużych plików</h2>
<p>W wypadku klipów o sporej wadze powyższa metoda ma jeden mankament. Dopóki plik nie zostanie w całości załadowany animacja nie zostanie odtworzona.</p>
<p>Można temu zapobiec tworząc prosty loader, także korzystając z Flasha. Tworząc nowy dokument (rozmiary mogą być minimalne, np. <em>10x10px</em>) wystarczy w jego pierwszej klatce dodać następujący kod <strong>ActionScript</strong>:<br />
[as]var fileName = _root.path;<br />
if ( -1 == fileName.indexOf(&#8222;%25&#8243;) &#038;&#038; fileName != &#8222;&#8221; )<br />
{<br />
	_root.loadMovie(fileName + &#8222;.swf&#8221;, 0);<br />
}[/as]<br />
Przy eksporcie do pliku wymagane jest, aby dokonywać go korzystając z <strong>ActionScript 1.0</strong> (AS), a w opcji <strong>Local playback security:</strong> należy wybrać <strong>Access local files only</strong>. Archiwum z plikiem źródłowym i wynikowym znajduje się <a href="http://get.m1chu.eu/-examples/-actionscript/loader/get_loader.php"  title="Źródła">tutaj</a>.</p>
<p>Dla nowszych AS, na przykład trójki powyższy przykład nie zadziała. Należy posłużyć się za to klasą <code>Loader</code>.<br />
[as]var path:String = new String();<br />
path = ( root.loaderInfo.parameters.path ? root.loaderInfo.parameters.path : &#8222;&#8221; );<br />
if ( -1 == path.indexOf(&#8222;%25&#8243;) &#038;&#038; path != &#8222;&#8221; )<br />
{<br />
	var loader:Loader = new Loader();<br />
	loader.load(new URLRequest(path + &#8222;.swf&#8221;));<br />
	addChild(loader);<br />
}[/as]</p>
<p>Na koniec zostaje jeszcze jedna zmiana do wykonania. W znaczniku <code>object</code> oraz w jego parametrach należy zmienić ścieżki do pliku na <code>loader.swf?path=skompilowany_flash</code> (bez rozszerzenia). Oczywiście w tym wypadku obydwa pliki muszą znajdować się w jednym i tym samym katalogu.</p>
<pre class="brush: xml; title: ;">&lt;object type=&quot;application/x-shockwave-flash&quot;
	data=&quot;loader.swf?path=skompilowany_flash&quot;
	style=&quot;width: 1024px; height: 768px;&quot;&gt;
	&lt;param name=&quot;movie&quot;
		value=&quot;loader.swf?path=skompilowany_flash&quot; /&gt;
	&lt;param name=&quot;quality&quot;
		value=&quot;best&quot; /&gt;
	&lt;img src=&quot;zastepcza_grafika.png&quot;
		style=&quot;width: 1024px; height: 768px;&quot;
		alt=&quot;Brak pluginu Flash&quot; /&gt;
&lt;/object&gt;</pre>
<h2>Zastępcze sposoby oparte na JavaScriptcie i komentarzach warunkowych&#8230;</h2>
<p>Jeżeli Twoim audytorium mają być osoby korzystające z czytników ekranowych (<strong>JAWS</strong>) to cały mój wywód poszedł na marne, bo po prostu nie zadziała. Nie zostawię Was jednak na lodzie. Wystarczy skorzystać z jednego z poniższych rozwiązań.</p>
<p>Pierwsze, <strong>SWFObject 2.1</strong> ogranicza się do <a target="_blank" href="http://utnij.eu/swfobject_download/"  title="Pobierz plik">pobrania</a> pliku klasy, wprowadzenia opcjonalnych zmiennych i wywołania metody wraz z argumentami która przypisze wynik do elementu o odpowiednim ID. Niestety wymaga włączonej obsługi JavaScript w przeglądarce użytkownika. Pełnej dokumentacji można zasięgnąć <a target="_blank" href="http://utnij.eu/swfobject_wiki/"  title="Wiki">tutaj</a>.</p>
<pre class="brush: xml; title: ;">&lt;head&gt;
[...]
&lt;script type=&quot;text/javascript&quot; src=&quot;swfobject.js&quot;&gt;&lt;/script&gt;
&lt;!-- parametry swfobject.embedSWF: plik, ID_bloku, szerokosc, wysokosc, minimalna_wersja_flasha [, odnośnik_do_ekspresowej_instalacji, zmienne_flasha, parametry, atrybuty ]; --&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
	var flashvars = false;
	var attributes = {
		id: &quot;flashContent&quot;
	}
	var params = {
		menu: &quot;false&quot;,
		quality: &quot;medium&quot;
	};
	swfobject.embedSWF(&quot;skompilowany_flash.swf&quot;, &quot;zawartosc&quot;, &quot;640&quot;, &quot;480&quot;, &quot;8.0.0.0&quot;, false, flashvars, params, attributes);
&lt;/script&gt;
[...]
&lt;/head&gt;
&lt;body&gt;
&lt;div id=&quot;zawartosc&quot;&gt;
	Alternatywny tekst.
&lt;/div&gt;
&lt;/body&gt;</pre>
<p>Na podobnej zasadzie działa <a target="_blank" href="http://utnij.eu/ufo_page/"  title="UFO">Unobtrusive Flash Objects</a>. Została ona jednak oficjalnie uznana za przestarzałą na rzecz wcześniej opisanego rozwiązania.</p>
<p>Drugi sposób zagnieżdżania oparty jest na ukrytych komentarzach warunkowych. <strong>Nested Objects</strong>, bo o nim mowa pozwala na określenie jakie przeglądarki nie powinny korzystać z kluczowego w tym wpisie sposobu. W przykładzie przeglądarki IE nie będą mogły używać rozwiązania opartego na <strong>Flash Satay</strong>.</p>
<pre class="brush: xml; title: ;">&lt;object classid=&quot;clsid:D27CDB6E-AE6D-11cf-96B8-444553540000&quot;
	codebase=&quot;http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0&quot;
	style=&quot;width: 1024px; height: 768px;&quot;&gt;
	&lt;param name=&quot;movie&quot; value=&quot;skompilowany_flash.swf&quot; /&gt;
	&lt;param name=&quot;quality&quot; value=&quot;high&quot; /&gt;
	&lt;!-- poczatek: kod z tego bloku nie zostanie wykonany w przegladarkach IE --&gt;
	&lt;!--[if !IE]&gt;&lt;!--&gt;
	&lt;object data=&quot;skompilowany_flash.swf&quot;
		type=&quot;application/x-shockwave-flash&quot;
		style=&quot;width: 1024px; height: 768px;&quot;&gt;
	&lt;param name=&quot;quality&quot; value=&quot;high&quot; /&gt;
	&lt;param name=&quot;pluginurl&quot; value=&quot;http://www.macromedia.com/go/getflashplayer&quot; /&gt;
	&lt;!--&lt;![endif]--&gt;
	&lt;!-- koniec --&gt;
	&lt;img src=&quot;zastepcza_grafika.png&quot;
		style=&quot;width: 1024px; height: 768px;&quot;
		alt=&quot;Brak pluginu Flash&quot; /&gt;
	&lt;!-- poczatek: kod z tego bloku nie zostanie wykonany w przegladarkach IE --&gt;
	&lt;!--[if !IE]&gt;&lt;!--&gt;
    	&lt;/object&gt;
    	&lt;!--&lt;![endif]--&gt;
    	&lt;!-- koniec --&gt;
&lt;/object&gt;</pre>
<p>Oczywiście odpowiednio modyfikując ujęte w kodzie komentarze warunkowe możemy manipulować tym która przeglądarka, które rozwiązanie będzie mogła stosować.</p>
<h2>Podsumowując&#8230;</h2>
<p>Na pewno buszując po otchłaniach Internetu spotkalibyście jeszcze kilka innych, mniej lub bardziej profesjonalnych rozwiązań. Pomimo, że te które tym razem zaprezentowałem działały bez większego zająknięcia na <strong>Operze 9.62</strong>, <strong>Firefoksie 3.0.4</strong>, <strong>Safari 3.2</strong>, a nawet na diabelnie niepokornym <strong>Internet Explorerze 7</strong> to chociażby dla pogłębienia swojej wiedzy warto się zainteresować pozostałymi metodami. </p>
<p>Oczywiście wykorzystanie <code>object</code> i <code>param</code> nie musi tylko i wyłącznie służyć do obsługi Flasha. Operowanie na filmach, muzyce, czy grafice to tylko przykłady możliwości tych znaczników. Wystarczy poeksperymentować i zapamiętać jedną rzecz&#8230; <code>embed</code> od dziś odchodzi w niepamięć&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://m1chu.eu/2008/12/14/jak-poprawnie-osadzic-flasha-w-kodzie-xhtml-strony/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>2 animowane menu za pomocą funkcji jQuery &#8211; animate()</title>
		<link>http://m1chu.eu/2008/10/27/2-animowane-menu-za-pomoca-funkcji-jquery-animate/</link>
		<comments>http://m1chu.eu/2008/10/27/2-animowane-menu-za-pomoca-funkcji-jquery-animate/#comments</comments>
		<pubDate>Sun, 26 Oct 2008 23:24:14 +0000</pubDate>
		<dc:creator>m1chu</dc:creator>
				<category><![CDATA[(x)HTML]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Webhosting]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[animate()]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[floating]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jumping]]></category>
		<category><![CDATA[navigation]]></category>
		<category><![CDATA[xhtml]]></category>

		<guid isPermaLink="false">http://m1chu.eu/?p=246</guid>
		<description><![CDATA[Mając do dyspozycji jQuery możemy dokonać wielu mniej lub bardziej oryginalnych modyfikacji dla urozmaicenia wyglądu tworzonej przez nas nawigacji na stronie. Funkcja animate() znakomicie nadaje się do kreowania animacji różnego typu relatywnie lub absolutnie pozycjonowanych elementów pozwalając na operowanie np. na ich szerokości, czy wysokości. animate() &#8211; funkcja zezwalająca na wykonywanie animacji elementów strony. Pozwala [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><img class="iborder" src="http://farm4.static.flickr.com/3277/2978445162_490b1dd3a1_o.png" alt="Animacje nawigacji za pomocą jQuery" /></p>
<p>Mając do dyspozycji <strong>jQuery</strong> możemy dokonać wielu mniej lub bardziej oryginalnych modyfikacji dla urozmaicenia wyglądu tworzonej przez nas nawigacji na stronie. Funkcja <a target="_blank" href="http://docs.jquery.com/Effects/animate"  title="jQuery: animate()"><strong>animate()</strong></a> znakomicie nadaje się do kreowania animacji różnego typu relatywnie lub absolutnie pozycjonowanych elementów pozwalając na operowanie np. na ich szerokości, czy wysokości.</p>
<p><span id="more-246"></span></p>
<p class="explain"><strong>animate()</strong> &#8211; funkcja zezwalająca na wykonywanie animacji elementów strony. Pozwala na działanie na właściwościach stylów takich jak szerokość (<em>width</em>), wysokość (<em>height</em>), <em>padding</em>, margines (<em>margin</em>), krawędź (<em>border</em>), górny brzeg elementu (<em>top</em>), czy wielkość czcionki (<em>font-size</em>). Dozwolone są więc właściwości przyjmujące wartości numeryczne (bądź <strong>&#8222;toggle&#8221;</strong>, <strong>&#8222;show&#8221;</strong> lub <strong>&#8222;hide&#8221;</strong>), a zapis ich nazw musi być w formie <strong>CamelCase</strong>, czyli poprzez bikapitalizację pojęć złożonych (usunięcie spacji i zastąpienie pierwszych znaków kolejnych słów dużymi literami). Przykładowo odpowiednikiem <strong>margin-right</strong> będzie <strong>marginRight</strong>. Od wersji <strong>1.2 jQuery</strong> pozwala je animować poprzez nadanie w.w. wartości także w postaci <strong>em</strong> i <strong>%</strong>. Wprowadzono w nim także krótkie zwiększanie (<strong>&#8222;+=&#8221;</strong>, np. <em>width: &#8222;+=5px&#8221;</em>) i zmniejszanie (<strong>&#8222;-=&#8221;</strong>, np. <em>height: &#8222;-=&#8221;+value</em>) wartości.</p>
<h2>Przygotowanie grafiki&#8230;</h2>
<p>Po przeczytaniu tego artykułu dowiesz się jak utworzyć dwa typy różnych menu oparty na frameworku jQuery, CSS-ie i (X)HTML-ie. Przykłady zastosowane w artykule będą przystosowane do XHTML-a/HTML-a wysyłanego jako <strong>text/html</strong>, a także do XHTML-a wysyłanego jako <strong>application/xhtml+xml</strong>.</p>
<p>Pierwszy z naszych efektów będzie opierał się na gotowych elementach graficzny oraz dla ukazania zwiększonych możliwości na jednej grafice będącej logiem konkretnego serwisu. Zastosujemy w tym przypadku opisywany już przeze mnie efekt <a href="http://m1chu.eu/webmastering/efekt-rollover-w-css-bez-przeladowywania-obrazka"  title="Efekt rollover - sliding-doors"><strong>sliding-doors</strong></a> (także wyjaśniany na <a target="_blank" href="http://vivee.info/2008/06/07/poziome-menu-z-efektem-sliding-doors/"  title="Sliding-doors - vivee">vivee</a>) dzięki któremu pozbędziemy się problemu związanego z nadmiernym ładowaniem grafik.</p>
<p>Potrzebne będzie nam sześć obrazków. Trzy z których będziemy korzystać dla wyświetlania w stanie nie najechania myszką, w stanie najechania i w stanie kliknięcia (bądź wyboru za pomocą tabulatora), oraz drugie trzy używane w takiej samej kolejności, ale które będą stworzone specjalnie dla przykładu użycia grafiki oddzielnego typu dla konkretnego przycisku. Należy pamiętać, aby realna wysokość grafiki była co najmniej tak duża, żeby spełniała potrzeby po, a nie przed pojawieniem się kursora nad nią. Tak więc, jeśli np. w normalnej pozycji ma ona <strong>57px</strong>, a po rozszerzeniu o <strong>10px</strong> więcej to szerokość jednego, pojedynczego obrazu nie powinna być mniejsza niż <strong>67px</strong>.</p>
<p style="text-align: center;"><img class="iborder" src="http://farm4.static.flickr.com/3200/2975302246_39ff35023f_o.png" alt="Cięcie podstawowego typu grafiki" /></p>
<p>Jak widać na wyżej załączonym screenie dzielimy przyciski na trzy kolumny &#8211; lewą, prawą i środek. Dwie pierwsze w naszym rozwiązaniu będą stałe, a środek będzie powielany w arkuszu stylów względem osi X (<strong>repeat-x</strong>). W przypadku wspomnianego już przycisku specjalnego ten podział nie istnieje (zapisujemy całość), gdyż szerokość generowanego w HTML-u rozwiązania będzie niezmienna.</p>
<p style="text-align: center;"><img class="iborder" src="http://farm4.static.flickr.com/3248/2978566762_d835e142c0_o.png" alt="Tworzenie specjalnego typu grafiki" /></p>
<h2>I. Jumping navigation (nawigacja &#8222;podskakująca&#8221;): kod XHTML</h2>
<p>Kod struktury menu oprę o znaczniki listowania które oczywiście należy wstawić w sekcję <strong>body</strong>.</p>
<pre class="brush: xml; title: ;">&lt;ul id=&quot;jumping-nav&quot;&gt;
	&lt;li&gt;&lt;a href=&quot;#&quot; title=&quot;#&quot;&gt;&lt;span class=&quot;left&quot;&gt;&lt;/span&gt;Link 1&lt;span class=&quot;right&quot;&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#&quot; title=&quot;#&quot;&gt;&lt;span class=&quot;left&quot;&gt;&lt;/span&gt;Link 2&lt;span class=&quot;right&quot;&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://m1chu.eu/&quot; title=&quot;Programowanie, webdeveloping&quot;&gt;&lt;span class=&quot;left&quot;&gt;&lt;/span&gt;m1chu.eu&lt;span class=&quot;right&quot;&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
	&lt;li id=&quot;with-image&quot;&gt;&lt;a href=&quot;http://utnij.eu/&quot; title=&quot;Prawdopodobnie najlepszy serwis do skracania linków&quot;&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</pre>
<p>Jak można zauważyć w trzech pierwszych odnośnikach nawigacji na stronie znajduje się tekst oraz znaczniki <strong>span</strong>. Odpowiadają one za wyświetlenie lewej oraz prawej krawędzi tła każdego z przycisków menu. W wypadku ostatniego linka nie jest to potrzebne, gdyż tło jest jednolitej szerokości, a tekst naniesiony jest bezpośrednio na nim. Specjalny element tej listy oznaczony jest ID <strong>with-image</strong>.</p>
<h2>I. Jumping navigation: kod CSS</h2>
<pre class="brush: css; title: ;">ul#jumping-nav
{
	position: relative;
	float: left; /* przemianowanie listy na szeregową */
	overflow: hidden;
	border-bottom: 1px solid #fff;
	padding: 0 10px;
	list-style: none;
	height: 4em; /* szerokosc przycisku */
}

ul#jumping-nav li, ul#jumping-nav li a
{
	position: relative;
	float: left; /* przemianowanie listy na szeregową */
} 

ul#jumping-nav li
{
	background: none;
	margin: 0;
	padding: 0;
	padding-left: 1px; /* 1-pikselowe rozdzielenie dwoch przyciskow od siebie */
	top: 15px; /* odleglosc od gornej krawedzi danej listy */
}

ul#jumping-nav li a
{
	display: block;
	background: url('srodkowa_czesc_grafiki.png') 0 0 repeat-x; /* adres do grafiki srodka przycisku powtarzany na osi X */
	padding: 0.9em 1.1em;
	text-decoration: none;
	color: #129397;
	height: 57px;
}

ul#jumping-nav li a span.left {
	display: block;
	/* pozycja absolutna */
	position: absolute;
	background: url('lewa_krawedz_grafiki.png') 0 0 no-repeat; /* adres do grafiki lewej krawedzi przycisku */
	height: 57px;
	width: 12px;
	/* ustawienie grafiki lewej krawedzi w pozycji lewego, gornego rogu elementu listy */
	left: 0;
	top: 0;
	z-index: 10; /* ustawienie grafiki granicznej nad powielana, srodkowa */
}

ul#jumping-nav li a span.right {
	display: block;
	/* pozycja absolutna */
	position: absolute;
	background: url('prawa_krawedz_grafiki.png') 0 0 no-repeat; /* adres do grafiki prawej krawedzi przycisku */
	height: 57px;
	width: 12px;
	/* ustawienie grafiki prawej krawedzi w pozycji prawego, gornego rogu elementu listy */
	right: 0;
	top: 0;
	z-index: 10; /* ustawienie grafiki granicznej nad powielana, srodkowa */
}

/* zmiany dokonywane przy najechaniu mysza na przycisk (grafika srodkowa + grafiki krawedzi) */
ul#jumping-nav li a:hover, ul#jumping-nav li a:hover span
{
	background-position: 0 -57px; /* przesuniecie pozycji tla o 57px w dol */
	color: #3f5f5a;
}

/* zmiany dokonywane przy kliknieciu mysza na przycisk lub po zaznaczeniu jej tabulatorem (grafika srodkowa + grafiki krawedzi) */
ul#jumping-nav li a:active, ul#jumping-nav li a:active span, ul#jumping-nav li a:focus, ul#jumping-nav li a:focus span
{
	background-position: 0 -114px; /* przesuniecie pozycji tla o 114px w dol */
	color: #333;
}</pre>
<p>Stosowne komentarze pozostawiłem w kodzie. Wytłumaczyć należałoby za to dokładniej zastosowaną w bloku elementu listy odległość od górnej granicy tejże listy.</p>
<pre class="brush: css; title: ;">top: 15px; /* odleglosc od gornej krawedzi danej listy */</pre>
<p>Odległość ta pozwala na ustalenie pozycji wyjściowej przycisków i będzie tak samo na stałe ustawiona w kodzie jQuery. Odejmując od niej otrzymamy pożądany przez nas efekt podniesienia przycisku po najechaniu na niego kursorem.</p>
<p>O czymś jednak pozornie zapomniałem w powyższym kodzie. Mianowicie o wspomnianym już przycisku specjalnym znajdującym się w tagu <strong>li</strong> o ID <strong>with-image</strong>. Sprawa jest prosta, a jej rozwiązanie będzie opierać się o dodanie kodu opartego na dwóch ostatnich blokach podanych w w.w. kodzie CSS.</p>
<pre class="brush: css; title: ;">ul#jumping-nav li#with-image a
{
	display: block;
	padding: 0.9em 1.1em;
	background: url('grafika_specjalna.png') 0 0 no-repeat; /* brak powtarzania w jakiejkolwiek osi */
	color: #333;
	text-decoration: none;
	height: 57px;
	width: 117px; /* okreslona na stale szerokosc przycisku */
}

/* zmiany dokonywane po najechaniu mysza na przycisk specjalny */
ul#jumping-nav li#with-image a:hover
{
	background-position: 0 -57px;
}

/* zmiany dokonywane przy kliknieciu mysza na przycisku specjalnym lub po zaznaczeniu jej tabulatorem */
ul#jumping-nav li#with-image a:active, ul#jumping-nav li#with-image a:focus
{
	background-position: 0 -114px;
}</pre>
<h2>I. Jumping navigation: animacja dzięki jQuery</h2>
<div class="explain"><strong>animate( parametry, [czas_wykonania], [styl_animacji], [akcja_zwrotna] )</strong></p>
<ul>
<li><strong>parametry</strong> &#8211; elementy animacji do wykonania (będące odpowiednikami dyrektyw CSS), np. <strong>top</strong>, <strong>left</strong>, <strong>marginLeft</strong>, <strong>width</strong>, <strong>height</strong>, czy <strong>opacity</strong>. Podawane są w formie <strong>nazwa: wartosc</strong> i rozdzielane przecinkami.</li>
<li><strong>czas_wykonywania</strong> &#8211; czas w milisekundach (lub w postaci wbudowanego ciągu znaków: <strong>&#8222;slow&#8221;</strong>, <strong>&#8222;normal&#8221;</strong> lub <strong>&#8222;fast</strong>) wykonywania animacji.</li>
<li><strong>styl_animacji</strong> (<em>opcjonalny</em>) &#8211; styl animacji, wymaga odpowiedniej wtyczki jQuery obsługującej tą opcję!</li>
<li><strong>akcja_zwrotna</strong> (<em>opcjonalny</em>) &#8211; funkcja zwracana wraz z zakończeniem animacji.</li>
</ul>
<p>Przykład:</p>
<pre class="brush: jscript; title: ;">$(&quot;div&quot;).animate({
      left: &quot;15px&quot;, opacity: .5
}, 300, &quot;easing&quot;, function(){alert(&quot;koniec!&quot;);});</pre>
</div>
<p>Na początek należy ściągnąć i zaimportować na swoją stronę najnowszą wersję <strong>jQuery</strong>. Pobrać ją można np. <a target="_blank" href="http://utnij.eu/jquery-min-1_2_6/"  title="jQuery 1.2.6">stąd</a>.</p>
<pre class="brush: xml; title: ;">&lt;script type=&quot;text/javascript&quot; src=&quot;jquery-1.2.6.min.js&quot;&gt;&lt;/script&gt; &lt;!-- jeżeli biblioteka będzie znajdować się w głównym katalogu strony --&gt;</pre>
<p>Nasz kod będzie przeznaczony dla jednego tego typu menu na danej podstronie. Po załadowaniu DOM zostanie wywołane zdarzenie <strong>:hover</strong> jQuery, a w nim funkcje wykonywane kolejno po najechaniu i po usunięciu kursora myszy z danego przycisku.</p>
<pre class="brush: jscript; title: ;">$(document).ready(function() {
    $('ul#jumping-nav li').hover(function() {
    	$(this).animate({ top : &quot;-=10px&quot; }, 150); // przesuniecie krawedzi przycisku o 10px w gore w czasie 150ms
    }, function() {
    	$(this).animate({ top : &quot;15px&quot; }, 150); // przesuniecie krawedzi do pozycji wejsciowej w czasie 150ms
    });
});</pre>
<h2>I. Jumping navigation: rezultat!</h2>
<p>Wynik jaki powinniście otrzymać po złożeniu tych części kodu w całość możecie podejrzeć <a href="http://use.m1chu.eu/-jquery/jumping-navigation/"  title="Jumping navigation - przykład"><strong>tutaj</strong></a>.</p>
<p style="text-align: center;"><img class="iborder" src="http://farm4.static.flickr.com/3031/2977596835_7b1c11d536_o.png" alt="Jumping navigation w przykładzie" /></p>
<h2>II. Floating navigation (nawigacja pływająca): kod XHTML</h2>
<p>Drugi przykład będzie ciut bardziej zaawansowany (pomysłodawcą i autorem efektu jest <a href="http://www.bedrichrios.com/"  title="Bedrich Rios" onclick="this.target='_blank';">Bedrich Rios</a>). Pod tym względem, że przedstawię użycie dwóch menu razem na stronie. Jednego poziomego i drugiego pionowego. Elementy graficzne obydwu będą opierać się tylko i wyłącznie o arkusz stylów.</p>
<p>Dla usystematyzowania położenia obydwu list odpowiedzialnych za wyświetlanie nawigacji na stronie wstawimy je w element blokowy <strong>div</strong>. Ponieważ będziemy chcieli, aby każde menu w trakcie wyświetlania aktywnego elementu podświetlane było na inny kolor to każdemu z nich nadamy odpowiedni identyfikator. Odpowiednio będą to <strong>yellow</strong> (gdzie tekst będzie podświetlany na odcień żółtego) i <strong>blue</strong> (gdzie tekst będzie podświetlany na odcień niebieskiego).</p>
<p>Ostatecznie naszym zamiarem jest dodanie także przy każdym menu tytułu. Aby jednak skrypt mógł rozróżnić go od normalnego pola z odnośnikiem musimy zastosować znacznik nagłówka. W naszym wypadku jest to <code>h4</code>.</p>
<pre class="brush: xml; title: ;">&lt;div id=&quot;nav-block&quot;&gt;
	&lt;ul class=&quot;floating-navigation&quot; id=&quot;yellow&quot;&gt;
		&lt;li&gt;&lt;h4&gt;Menu główne!&lt;/h4&gt;&lt;/li&gt; &lt;!-- nagłówek menu poziomego --&gt;
		&lt;li&gt;&lt;a href=&quot;#&quot; title=&quot;#&quot;&gt;Odnośnik 1&lt;/a&gt;&lt;/li&gt;

		&lt;li&gt;&lt;a href=&quot;#&quot; title=&quot;#&quot;&gt;Odnośnik 2&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://thenet.pl/&quot; title=&quot;Technologiczne spojrzenie na świat&quot; onclick=&quot;this.target='_blank';&quot;&gt;thenet.pl&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://after-all.eu/&quot; title=&quot;Nowoczesny bash z cytatami z IRC&quot; onclick=&quot;this.target='_blank';&quot;&gt;after-all.eu&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;
	&lt;ul class=&quot;floating-navigation&quot; id=&quot;blue&quot;&gt;
		&lt;li&gt;&lt;h4&gt;Menu boczne!&lt;/h4&gt;&lt;/li&gt; &lt;!-- nagłówek menu pionowego --&gt;
		&lt;li&gt;&lt;a href=&quot;#&quot; title=&quot;#&quot;&gt;Odnośnik 1&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#&quot; title=&quot;#&quot;&gt;Odnośnik 2&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://m1chu.eu/&quot; title=&quot;Another devblog - programowanie, webdeveloping&quot; onclick=&quot;this.target='_blank';&quot;&gt;m1chu.eu&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://utnij.eu/&quot; title=&quot;Prawdopodobnie najlepszy serwis do skracania linków&quot; onclick=&quot;this.target='_blank';&quot;&gt;utnij.eu&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;
&lt;/div&gt;</pre>
<h2>II. Floating navigation: kod CSS</h2>
<pre class="brush: css; title: ;">ul.floating-navigation
{
	list-style-type: none;
	font-size: 12px;
	margin: 30px 0px; /* odleglosc od lewej i prawej krawedzi */
	padding-top: 10px;
	&amp; padding-left: 30px; /* padding zastepujacy margines w IE */
	width: 985px; /* szerokosc wszystkich elementow poziomego menu + suma wymaganych szerokosci w efekcie &quot;wjezdzania&quot; (podawana w funkcji JS floatNav()) */
}

ul.floating-navigation li h4,
ul.floating-navigation li a
{
	display: block;
	width: 150px;
	padding: 5px 15px;
	margin: 0;
	margin-bottom: 2px;
}

ul.floating-navigation li h4
{
	color: #fff;
	background: #333;
	border: 1px solid #1a1a1a;
	font-weight: normal;
	font-size: 12px;
}

ul.floating-navigation li a
{
	color: #999;
	border: 1px solid #1a1a1a;
	background: #222;
	text-decoration: none;
	opacity: .7; /* opcjonalna przezroczystosc elementow */
}

ul#yellow li
{
	float: left; /* ustawienie w szeregu elementow listy w menu glownym - utworzenie menu poziomego */
}

ul#yellow li a:hover
{
	color: #ffff66; /* kolor tekst gdy myszka jest na obiekcie w menu poziomym */
	background-color: #1e1e1e;
}

ul#blue li a:hover
{
	color: #006699; /* kolor tekst gdy myszka jest na obiekcie w menu pionowym */
	background-color: #1e1e1e;
}</pre>
<p>Jedynym aspektem który należałoby wytłumaczyć jest magiczne <code>&#038; padding-left: 30px;</code>. Jest to wartość która tylko i wyłącznie pozycjonuje rozmieszczenie elementów którymi się tutaj zajmujemy. Zastanawiacie się za pewnie co robi to <strong>&#038;</strong> przez tą regułą? Jest to tzw. <strong>hack IE</strong> który działaja podobnie jak najbardziej znany <strong>*</strong> i dzięki którym dana dyrektywa wykonywana jest tylko w przeglądarkach opartych na Internet Explorerze. Musieliśmy dokonać takiego zabiegu, gdyż inaczej marginesy w przeglądarce Microsoftu byłyby ustawione na <strong>0</strong> (z niewiedzy, złej implementacji, złośliwości jej programistów&#8230; jak zwał, tak zwał :D).</p>
<h2>II. Floating navigation: animacja dzięki jQuery</h2>
<p>Podobnie jak w poprzednim typie nawigacji tutaj także trzeba skorzystać z ściągniętej już wcześniej biblioteki jQuery.</p>
<p>Tym razem jednak po załadowaniu DOM wywołamy kolejno dwie funkcje.</p>
<pre class="brush: jscript; title: ;">$(document).ready(function()
{
	floatNav(&quot;ul#yellow&quot;, 25, 15, 150, .7, 500, &quot;#fff&quot;);
	floatNav(&quot;ul#blue&quot;, 25, 15, 150, .7, 500);
});</pre>
<p>Posiadają one siedem parametrów o niżej wymienionym przeznaczeniu.</p>
<pre class="brush: plain; title: ;">floatNav(id_listy_menu, paddingLeft_gdy_kursor_jest_na_obiekcie, paddingLeft_gdy_kursor_jest_poza_obiektem, czas_wykonywania_animacji, mnoznik_kolejnego_animowania_wlotu_elementow_po_zaladowaniu_DOM [, kolor_napisow_menu_po_kliknieciu]);</pre>
<p>Ostatni parametr jest opcjonalny. W wypadku, gdy nie zostanie podany po kliknięciu zostanie zwrócony domyślny kolor. Należy zdawać sobie także sprawę, że ten sposób zadziała tylko w wypadku otwierania stron w oknach innych niż te używane przez skrypt.</p>
<pre class="brush: jscript; title: ;">function floatNav(float_nav_id, float_hover_out, float_hover_in, float_run_time, float_multiplier, float_click_effect, float_clicked_color)
{
	var list_elements = float_nav_id + &quot; li&quot;;
	var link_elements = list_elements + &quot; a&quot;;

	var timer = 0; // czas poczatkowy

	$(list_elements).each(function(i) // wczytywanie elementow po zaladowaniu strony
	{
		timer = (timer * float_multiplier + float_run_time); // zmienna przetrzymujaca czas wczytania elementu zwiekszana o wartosc sumy mnoznika i czas dzialania animacji w stosunku do czasu wczytania poprzedniego elementu

		$(this).css(&quot;margin-left&quot;,&quot;-180px&quot;); // wczytanie od strony lewego marginesu i kolejno efekt &quot;wstrzasniecia&quot; z jednej pozycji do drugiej i z powrotem
		$(this).animate({ marginLeft: &quot;0&quot; }, timer);
		$(this).animate({ marginLeft: float_hover_out }, timer);
		$(this).animate({ marginLeft: &quot;0&quot; }, timer);
	});

	var link_hover_width = $(link_elements).width(); // pobranie szerokosci wejsciowej elementu listy
	$(link_elements).hover(
		function()
		{
			$(this).animate({ paddingLeft: float_hover_out, opacity: 1, width: link_hover_width-(float_hover_out-float_hover_in) }, float_run_time); // w trakcie pojawienia sie kursora na elemencie nastepuje zmiana przezroczystosci na pelna, przesuniecie w prawo oraz zmniejszenie szerokosci elementu
		},
		function()
		{
			$(this).animate({ paddingLeft: float_hover_in, opacity: float_multiplier, width: link_hover_width }, float_run_time); // przywrocenie do wartosci podstawowych po przeniesieniu kursora poza menu
		}
	);

	$(link_elements).click(
		function()
		{
			$(this).fadeOut(float_click_effect); // efekt zanikania
			$(this).fadeIn((float_click_effect/2)); // efekt pojawiania sie w czasie dwukrotnie mniejszym niż w trakcie efektu zanikania
			if ( float_clicked_color != &quot;&quot; )
			{
				$(this).css(&quot;color&quot;, float_clicked_color); // zmiana koloru kliknietego elementu o ile podany zostal ostatni parametr funkcji nadrzednej
			}
		}
	);
}

$(document).ready(function()
{
	floatNav(&quot;ul#yellow&quot;, 25, 15, 150, .7, 500, &quot;#fff&quot;);
	floatNav(&quot;ul#blue&quot;, 25, 15, 150, .7, 500);
});</pre>
<h2>II. Jumping navigation: wynik!</h2>
<p>Także tym razem przygotowałem Wam praktyczne zobrazowanie tego co chcieliśmy osiągnąć. O! <a href="http://use.m1chu.eu/-jquery/floating-navigation/"  title="Floating navigation - przykład"><strong>tutaj, zapraszam</strong></a>.</p>
<p style="text-align: center;"><a target="_blank" href="http://farm4.static.flickr.com/3211/2975293355_49cb674e9e_o.png"  title="Pełny rozmiar - floating navigation" class="lightbox"><img class="iborder" src="http://farm4.static.flickr.com/3211/2975293355_702e58199f.jpg" alt="Jumping navigation w przykładzie" /></a></p>
<h2>Kurde! Tyle czytania i nie działa! Dlaczego?!</h2>
<p>Obydwie metody testowałem na poniższy przeglądarkach i na wszystkich działały prawidłowo:</p>
<ul>
<li>Firefox 3.0.3,</li>
<li>Opera 9.60</li>
<li>Safari 3.1.2</li>
<li>SeaMonkey 1.1.9</li>
<li>Flock 1.1.1</li>
<li>Sleipnir 2.7.2</li>
</ul>
<p>Mogę domniemać, że problem tkwi w użytkowaniu kilku frameworków naraz. Problem ten opisywałem <a href="http://m1chu.eu/wordpress/kolizje-wspoldzialania-bibliotek-javascript-na-podstawie-wtyczek-wordpress"  title="Kolizja bibliotek z jQuery w tle">tutaj</a> i radzę od jego przeczytania zacząć rozpoznawanie błędu :]</p>
]]></content:encoded>
			<wfw:commentRss>http://m1chu.eu/2008/10/27/2-animowane-menu-za-pomoca-funkcji-jquery-animate/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Kolizje współdziałania bibliotek JavaScript na podstawie wtyczek WordPress&#8230;</title>
		<link>http://m1chu.eu/2008/10/02/kolizje-wspoldzialania-bibliotek-javascript-na-podstawie-wtyczek-wordpress/</link>
		<comments>http://m1chu.eu/2008/10/02/kolizje-wspoldzialania-bibliotek-javascript-na-podstawie-wtyczek-wordpress/#comments</comments>
		<pubDate>Thu, 02 Oct 2008 10:45:38 +0000</pubDate>
		<dc:creator>m1chu</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Prototype]]></category>
		<category><![CDATA[Webhosting]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[biblioteka]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[wtyczka]]></category>

		<guid isPermaLink="false">http://m1chu.eu/?p=96</guid>
		<description><![CDATA[Coraz więcej różnorodnych stron internetowych korzysta z techniki która w szeroki sposób pozwoliła rozwinąć się przede wszystkim JavaScriptowi &#8211; z Ajaxa. Podobnie jest z różnorodnymi wtyczkami do systemu blogów WordPress. Z reguły korzystają one jednak z jakiejś biblioteki JavaScript zbierającej w całość jego najważniejsze funkcje i pozwalającej na ich prostsze użycie. W momencie jednak, kiedy [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><img class="iborder" src="http://farm4.static.flickr.com/3066/2953934393_d684ed0058_o.png" alt="Współdziałanie framework'ów na przykładzie WordPress'a" /></p>
<p>Coraz więcej różnorodnych stron internetowych korzysta z techniki która w szeroki sposób pozwoliła rozwinąć się przede wszystkim JavaScriptowi &#8211; z Ajaxa. Podobnie jest z różnorodnymi wtyczkami do systemu blogów <a target="_blank" href="http://wordpress.org/"  title="WordPress">WordPress</a>. Z reguły korzystają one jednak z jakiejś biblioteki JavaScript zbierającej w całość jego najważniejsze funkcje i pozwalającej na ich prostsze użycie. W momencie jednak, kiedy w naszych pluginach pojawi się w użyciu kilka wtyczek możemy napotkać problem kolizji ich współdziałania.</p>
<p><span id="more-96"></span></p>
<h2>Prolog!</h2>
<p>Zanim zacznę muszę wspomnieć, że kolizja opisywana poniżej może występować na jakiejkolwiek stronie, a opisywana przeze mnie sytuacja jest tylko przykładem. Nie mniej jednak mankament ten postaram się wytłumaczyć na podstawie jednoczesnego działania <a target="_blank" href="http://utnij.eu/ajax-comments/"  title="WP Ajax Comments">AJAX Comments</a> i przystosowanej do personalnych potrzeb modyfikacji zakładek (przykładem są te umieszczone z lewej strony tego wpisu). Pierwsza wtyczka domyślnie używa <a target="_blank" href="http://script.aculo.us/"  title="Script.Aculo.Us">Script.Aculo.Us</a>, a co za tym idzie także frameworku <a target="_blank" href="http://www.prototypejs.org/"  title="Prototype">Prototype</a>. W drugim wypadku oprę się o <a target="_blank" href="http://vivee.info/2008/08/05/zakladki-do-sidebara/"  title="Zakładki do Sidebara">kurs tworzenia zakładek</a> w WP <strong>palmiaka</strong>, który używa za to <a target="_blank" href="http://jquery.com/"  title="jQuery">jQuery</a>.</p>
<p>Po poprawnej instalacji obydwu modyfikacji pewnie spora część z Was nie dostrzeże dręczącego nas feleru. Dlaczego? Gdyż na stronie głównej wszystko będzie działało prawidłowo, ale bynajmniej nie na podstronach w których będzie możliwe komentowanie wpisów. Dla przykładu w momencie wczytania najpierw <strong>prototype.js</strong> i <strong>scriptaculous.js</strong>, a później <strong>jquery.js</strong> stworzone przez nas zakładki nie będą poprawnie działać (nie zostaną one ukryte i nie będzie możliwości przejścia pomiędzy nimi). Dlaczego tak się dzieje? Tutaj należałoby poruszyć pewną sprawę dotyczącą samego działania frameworków tego typu.</p>
<h2>Funkcja $(argumenty)</h2>
<p>Między innymi do tworzenia obiektu danej biblioteki używa się funkcji <code>$(argumenty);</code>. Dzięki temu operujące np. na obiektach DOM, czy tablicach frameworki dzięki tej specjalnej konstrukcji pozwalają użytkownikowi na wykorzystywanie ich konkretnych funkcji.</p>
<p style="text-align: center;"><a target="_blank" href="http://farm4.static.flickr.com/3155/2905203185_36c209390b_o.png"  title="Powiększenie" class="lightbox"><img src="http://farm4.static.flickr.com/3155/2905203185_1e8236bb72.jpg" alt="Różnorodne metody korzystania z elementów strony" /></a></p>
<h2>Problematyka korzystania z więcej niż jednej biblioteki naraz&#8230;</h2>
<p>W momencie kiedy w skrypcie korzystamy z dwóch lub większej ilości frameworków może nastąpić kolizja w ich działaniu. W uproszczeniu przez użycie <code>$();</code> w każdej z nich. I tak to w naszym przykładzie funkcje, czy odwołania do obiektów które powinny być wykonane za pomocą <strong>jQuery</strong> zostaną wykonane przez pierwszą wczytaną klasę. A wszystko przez to, że każda z podanych bibliotek odwołuje się do danego elementu w taki sam sposób.</p>
<h2>Solucja!</h2>
<p>Na szczęście od wersji <strong>1.1.4</strong> z pomocą przychodzą nam developerzy <strong>jQuery</strong> wraz z funkcją pozwalającą na interoperacyjność &#8211; <code>jQuery.noConflict(param);</code>.</p>
<pre class="brush: jscript; title: ;">jQuery.noConflict(); // zwraca kontrolę nad $ bibliotece domyślnej (wcześniej używanej)
jQuery.noConflict(true); // zwraca kontrolę nad $ i jQuery (którego $ jest aliasem) oryginalnemu właścicielowi - należy używać z ostrożnością!</pre>
<p>Co należy wiedzieć w kwestii używania tego to przede wszystkim fakt, że wymaga się, aby powyższą funkcję wywołać przed użyciem elementów innych bibliotek, a także <strong>jQuery</strong> powinno być wczytywane po pozostałych frameworkach. W konkretnym wypadku związanym z WP który opisujemy należy także domyślnie dostarczone niżej wymienione biblioteki uaktualnić. Niestety w opisywanych tutaj wtyczkach i systemie blogów są to wersje starsze i przedstawiony trick w tym artykule nie zadziała dopóki nie ściągniemy zaktualizowanych wersji frameworków.</p>
<pre class="brush: jscript; title: ;">&lt;script type=&quot;text/javascript&quot; src=&quot;libs/prototype.js&quot; /&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;libs/scriptaculous.js&quot; /&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;libs/jquery.js&quot; /&gt;</pre>
<p>Domyślnie także należy używać w tym trybie <strong>jQuery</strong> zamiast <strong>$</strong>.</p>
<pre class="brush: jscript; title: ;">jQuery.noConflict();
jQuery(&quot;p&quot;).hide(); // użycie frameworka jQuery
$(&quot;div&quot;).style.display = 'none'; // użycie innego frameworka, np. prototype</pre>
<p>Ponieważ oczywiście zaprezentowana funkcja jest podatna na przypisywanie do zmiennych to niekoniecznie musimy używać standardowej, dłuższej nazwy. Negatywem tego rozwiązania jest jednak potencjalny konflikt nazw w przypadku pisania aplikacji internetowej przez wielu programistów.</p>
<pre class="brush: jscript; title: ;">var q = jQuery.noConflict();
q(&quot;p&quot;).hide();
$(&quot;div&quot;).style.display = 'none';</pre>
<p>Ostatecznie moglibyście także spytać <strong>&#8222;co zrobić, aby móc wewnątrz bloku kodu używać $ dla jQuery?&#8221;</strong>. Wystarczy poprzedzić zadaną funkcję przez <code>jQuery</code>, bądź zakończyć poprzez <code>(jQuery)</code>.</p>
<pre class="brush: jscript; title: ;">jQuery(function($) { [...] }); // wersja pierwsza
(function($) { [...] })(jQuery); // wersja druga</pre>
<p>Niestety w takim wypadku wewnątrz powyższych bloków kodu nie ma możliwości odniesienia się do obiektów innych bibliotek.</p>
<h2>Przykład pozwalający na prawidłowe działanie wspomnianych zakładek&#8230;</h2>
<p>Poprawiony przykład z <strong>vivee</strong>, który należy użyć w wypadku w.w. konfliktu (kod JavaScript).</p>
<pre class="brush: jscript; title: ;">jQuery.noConflict();

function tabs(id) {
	jQuery(&quot;#&quot;+id+&quot; h2:first a&quot;).addClass(&quot;active&quot;);
    jQuery(&quot;#&quot;+id+&quot; div&quot;).not(&quot;:first&quot;).hide();

    jQuery(&quot;#&quot;+id+&quot; h2 a&quot;).click(function() {
    	var licznik = jQuery(&quot;#&quot;+id+&quot; h2 *&quot;).index(this);                                             

        jQuery(&quot;#&quot;+id+&quot; h2 a&quot;).removeClass(&quot;active&quot;);
        jQuery(this).addClass(&quot;active&quot;);
        jQuery(&quot;#&quot;+id+&quot; div:visible&quot;).hide();

        jQuery(&quot;#&quot;+id+&quot; div&quot;).eq(licznik).show();
        return false;
    });
}

jQuery(document).ready(function(){
    tabs(&quot;zakladki&quot;);
});</pre>
<h2>Epilog&#8230;</h2>
<p><strong>WPNinja</strong> na swoim blogu poświęconym WordPressowi prawidłowo stwierdził w stosunku do mojej osoby, że mieszanie bibliotek nie jest dobrym zwyczajem.</p>
<pre class="brush: plain; title: ;">&quot;@m1chu,
Mieszanie ze sobą bibliotek to masakra. Nie dość, że zajmuje to niemiłosiernie dużo miejsca to, jak zauważyłeś w swoim artykule, może powodować konflikty.&quot;</pre>
<p>Opisany przeze mnie artykuł powinien być stosowany tylko w wyjątkowych sytuacjach. Należy z reguły <strong>unikać</strong> użytkowania kilku frameworków naraz, bo to obciąża w znacznym stopniu skrypt poprzez ich wagę, a co za tym idzie ilością danych do załadowania. Zdaję sobie jednak sprawę, że niekiedy jest to niezmiernie trudne (czego jak na razie w fazie rozwojowej przykładem jest mój blog ;]). Podziękowania za przypomnienie dla <strong>WPNinja&#8217;y</strong> o tym, że zapomniałem tak ważnego faktu umieścić w swoich wpisie.</p>
]]></content:encoded>
			<wfw:commentRss>http://m1chu.eu/2008/10/02/kolizje-wspoldzialania-bibliotek-javascript-na-podstawie-wtyczek-wordpress/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

