<?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>ForestMist &#187; JavaScript</title>
	<atom:link href="http://forestmist.org/tag/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://forestmist.org</link>
	<description></description>
	<lastBuildDate>Tue, 11 Oct 2011 03:17:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>PHP 5 &#8211; Sort by Folder</title>
		<link>http://forestmist.org/2011/06/php-5-sort-by-folder/</link>
		<comments>http://forestmist.org/2011/06/php-5-sort-by-folder/#comments</comments>
		<pubDate>Sun, 26 Jun 2011 23:01:50 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHP 5]]></category>

		<guid isPermaLink="false">http://forestmist.org/?p=1295</guid>
		<description><![CDATA[Recently, I needed to display a list of files with PHP. My only caveat was that I wanted to do so using newer methods of PHP 5 where possible. I was delighted to find scandir. Problem was, scandir returns files mixed with folders and that would upset my flock of easily frightened Windows users. So a quick&#8230; er [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I needed to display a list of files with PHP. My only caveat was that I wanted to do so using newer methods of PHP 5 where possible.</p>
<p>I was delighted to find <a href="http://php.net/manual/en/function.scandir.php">scandir</a>. Problem was, scandir returns files mixed with folders and that would upset my flock of easily frightened Windows users.</p>
<p>So a quick&#8230; er medium&#8230; ok fine,  an exasperating search on Google and only outdated, complex and inefficient samples were to be found. <a href="http://www.youtube.com/watch?v=1Lr_TVZnuxs">PUFF</a>!</p>
<p>So, here is the version I came up with.</p>
<div style="text-align: center"><a class="css3-button" href="http://forestmist.org/share/code/php-sort-by-folder/demo/">Demo<span></span></a></div>
<h2>Downloads</h2>
<ul>
<li><a href="/share/code/php-sort-by-folder/Sort%20by%20Folder.zip"><strong>Sort by Folder</strong></a> is optimized for easier PHP comprehension.</li>
<li><a href="http://forestmist.org/share/code/php-sort-by-folder/Sort%20by%20Folder%20(with%20HTML).zip"><strong>Sort by Folder (with HTML)</strong></a> contains extra code which adds more information and cleaner formatting to the generated HTML.</li>
</ul>
<h2>How it works</h2>
<p>The most crucial part of all the code you will see inside the demo is the PHP getObjects() function. Without this everything else would be moot so lets go over it in a bit more detail.</p>
<pre class="brush: php; title: ; notranslate">
function getObjects($path) {
    $path .= '/';
    $array = scandir($path); // returns an array of files and folders sorted alphabetically
    $array = array_diff($array, array('.', '..', '.DS_Store', 'Thumbs.db')); // filter out things we don't want

    $return_array = array();

    foreach($array as $item) {
        if(is_dir($path . $item)) {
            $return_array[$item] = getObjects($path . '/' . $item);
        }
    }

    $count = 0;
    foreach($array as $item) {
        if(!is_dir($path . $item)) {
            $return_array[$item] = $item;
            $count++;
        }
    }
    if($count == 0) {
        $return_array[''] = '';
    }

    return $return_array;
}
</pre>
<p><strong>Line 3</strong><br />
Scandir returns an array of mixed folders and files for the path requested. This does not include sub directories.</p>
<p><strong>Line 4</strong><br />
Filter out any undesirables. That means the current &#8216;.&#8217; and parent directory &#8216;..&#8217; although we don&#8217;t want any Mac &#8216;.DS_Store&#8217; or WIndows &#8216;Thumbs.db&#8217; files either.</p>
<p><strong>Line 6</strong><br />
We create a new array called $return_array which will be built up with all the folders and files in the order we want them. Folders first, then files. Both alphabetically.</p>
<p><strong>Line 8-12</strong><br />
Here we loop through each item in our filtered results from scandir. If the item is a directory we set the results of $return_array[$item] to a recursive call of the very same function we are already in. Traveling deeper each recursive call, that means we can handle seemingly infinite directory structures. Neat.</p>
<p>This first loop through <em>only</em> cares about directories which is exactly what puts them first in our $return_array. Files will come next.</p>
<p><strong>Line 14</strong><br />
We set a variable $count to 0 to keep track of how many files we find in the next foreach loop.</p>
<p><strong>Line 15-19</strong><br />
In this second loop we check to make sure the items are not directories and if so return those items while incrementing the $count variable.</p>
<p><strong>Line 21-23</strong><br />
Now that we are finished looping for files we can check our $count variable. If 0 then set $return_array to &#8221;. This can useful later in case we want to do something special for directories without files.</p>
<p><strong>Line 25</strong><br />
Finally, we return whatever we have found. In most cases this means returning an $array to another instance of the function although ultimately the original one will return a completed array to the PHP call outside our function that started it all.</p>
<p>In the demo we can now loop through this nicely ordered array and write out some HTML and CSS, add a sprinkle of JavaScript and we have a real working web app.</p>
<div style="position: absolute; margin-left: -96px;"><a href="http://www.flickr.com/search/?q=elephpant&#038;s=rec"><img src="http://forestmisty.org/wp-content/uploads/2011/06/php-elephant.png" width="65" height="88" style="border-width: 0px; moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none;"><img src="http://forestmisty.org/wp-content/uploads/2011/06/php-elephant-nose.png" width="95" height="89" style="border-width: 0px; moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; position: absolute; margin-left: -66px;"></a></div>
<h2>Epilogue</h2>
<p>Once you get your head around recursive loops things become much simpler. Plus you get to worry more about optimizing your code since each loop can be run so many times. It&#8217;s a good problem to have, really.</p>
<p>Anyway, I certainly hope this helps you in your next endeavor. I know I certainly would be lost without all the wonderful code and tutorials shared by others.</p>
<p>Cheers!</p>
]]></content:encoded>
			<wfw:commentRss>http://forestmist.org/2011/06/php-5-sort-by-folder/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>HTML5 Audio Loops</title>
		<link>http://forestmist.org/2010/04/html5-audio-loops/</link>
		<comments>http://forestmist.org/2010/04/html5-audio-loops/#comments</comments>
		<pubDate>Mon, 12 Apr 2010 00:02:01 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web Browser]]></category>

		<guid isPermaLink="false">http://forestmist.org/?p=1102</guid>
		<description><![CDATA[One of the neatest things about HTML5 is support for the new &#60;audio&#62; tag. Like &#60;video&#62; it allows you to natively support media in good browsers like Chrome, FireFox, Opera and Safari. Add a touch of JavaScript and a new era of  media applications become possible. Synthesizers, music trackers and games require seamless audio loops though [...]]]></description>
			<content:encoded><![CDATA[<p>One of the neatest things about HTML5 is support for the new &lt;audio&gt; tag. Like &lt;video&gt; it allows you to natively support media in good browsers like Chrome, FireFox, Opera and Safari. Add a touch of JavaScript and a new era of  media applications become possible.</p>
<p>Synthesizers, music trackers and games require seamless audio loops though so we need something a bit simpler for our first foray into HTML5 audio.</p>
<p>Oooh, how about a retro beatbox with individual track adjustments (start/stop/loop/volume) that could be used to build a unique soundscape from many separate instruments. Perfect!</p>
<p>Fantasy can only become reality through hard work so let&#8217;s get started with some tests first.</p>
<h2>Loop Method 1</h2>
<pre><audio id="audio_1" controls preload loop>
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.ogg">
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.wav">
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.mp3">
</audio></pre>
<p>Uses the &#8216;loop&#8217; property.</p>
<pre class="brush: xml; title: ; notranslate">&lt;audio id=&quot;audio_1&quot; controls preload loop&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.ogg&quot;&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.wav&quot;&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.mp3&quot;&gt;
&lt;/audio&gt;</pre>
<h2>Loop Method 2</h2>
<pre><audio id="audio_2" controls preload>
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.ogg">
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.wav">
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.mp3">
</audio></pre>
<p>Uses a JavaScript function to loop when an &#8216;ended&#8217; event is called.</p>
<pre class="brush: xml; title: ; notranslate">&lt;audio id=&quot;audio_2&quot; controls preload&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.ogg&quot;&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.wav&quot;&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.mp3&quot;&gt;
&lt;/audio&gt;</pre>
<pre class="brush: jscript; title: ; notranslate">
document.getElementById('audio_2').addEventListener('ended', function(){
this.currentTime = 0;
}, false);
</pre>
<h2>Loop Method 3</h2>
<pre><audio id="audio_3" controls preload>
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.ogg">
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.wav">
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.mp3">
</audio>
<audio id="audio_4" controls preload>
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.ogg">
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.wav">
	<source src="/wp-content/uploads/2010/04/html5-audio-loop.mp3">
</audio></pre>
<p>Uses two JavaScript functions and two audio elements with the same source to alternate playback duties.</p>
<pre class="brush: xml; title: ; notranslate">&lt;audio id=&quot;audio_3&quot; controls preload&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.ogg&quot;&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.wav&quot;&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.mp3&quot;&gt;
&lt;/audio&gt;
&lt;audio id=&quot;audio_4&quot; controls preload&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.ogg&quot;&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.wav&quot;&gt;
	&lt;source src=&quot;/wp-content/uploads/2010/04/html5-audio-loop.mp3&quot;&gt;
&lt;/audio&gt;</pre>
<pre class="brush: jscript; title: ; notranslate">document.getElementById('audio_3').addEventListener('ended', function(){
this.currentTime = 0;
this.pause();
document.getElementById('audio_4').play();
}, false);

document.getElementById('audio_4').addEventListener('ended', function(){
this.currentTime = 0;
this.pause();
document.getElementById('audio_3').play();
}, false);</pre>
<pre><script type="text/javascript">		document.getElementById('audio_2').addEventListener('ended', function(){
this.currentTime = 0;
}, false);

document.getElementById('audio_3').addEventListener('ended', function(){
this.currentTime = 0;
this.pause();
document.getElementById('audio_4').play();
}, false);

document.getElementById('audio_4').addEventListener('ended', function(){
this.currentTime = 0;
this.pause();
document.getElementById('audio_3').play();
}, false);
</script></pre>
<h2>Browser Support</h2>
<p>Tests were done on Windows 7 with Chrome 5.0.342.9 beta, FireFox 3.6.3, Internet Explorer 9.0 Preview, Opera 10.51 and Safari 4.0.5. </p>
<p><strong>Chrome</strong> seems to trigger loops before the current sound is completely finished leading to some odd jumpiness. All loop methods are affected.</p>
<p><strong>FireFox</strong> doesn&#8217;t seem to like the &#8216;loop&#8217; property of method 1, odd. Method 2 has the slightest of delays between loops and method 3 was actually perfect! I didn&#8217;t believe it until verification at the millisecond level with <a href="http://audacity.sourceforge.net/">Audacity</a>. Hooray Mozilla!</p>
<p><strong>Internet Explorer 9</strong> doesn&#8217;t support the audio tag yet. Hopefully it will before an official release.</p>
<p><strong>Opera</strong> performs almost as well as FireFox although there is still a small delay even when using method 3.</p>
<p><strong>Safari</strong> seems slow to start playback which is very easy to detect once you hear a loop. All loop methods affected.</p>
<p>Feedback on other browsers/OS compatibility would be very interesting so please feel free to discuss any findings in the comments below.</p>
<h2>Final Thoughts</h2>
<p>As of right now (April 11, 2010) only FireFox can do a perfect loop by cheating a bit and using two &lt;audio&gt; elements with JavaScript.</p>
<p>So yeah, it&#8217;s a bit too early for HTML5 audio loops but don&#8217;t let that stop you from creating sound boards, media players and other fun things.</p>
<p>Hopefully with some more optimizations audio support will continue to improve and a HTML5 beatbox fantasy can become reality.</p>
<p>Until then there are plenty of other fun things to play with.</p>
<p>Cheers!</p>
]]></content:encoded>
			<wfw:commentRss>http://forestmist.org/2010/04/html5-audio-loops/feed/</wfw:commentRss>
		<slash:comments>33</slash:comments>
		</item>
		<item>
		<title>Disable right clicking on images only</title>
		<link>http://forestmist.org/2010/03/disable-right-clicking-on-images-only/</link>
		<comments>http://forestmist.org/2010/03/disable-right-clicking-on-images-only/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 03:53:04 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[MooTools]]></category>
		<category><![CDATA[Web Browser]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://forestmist.org/?p=161</guid>
		<description><![CDATA[There are few instances where disabling someone&#8217;s context menu is appropriate. In most cases it&#8217;s unnecessary and can even lead to infuriating your visitors. Here are some ways to target all the image elements on a page while leaving the rest of the hypertext in peace. JavaScript Lightweight, no framework required and works well in [...]]]></description>
			<content:encoded><![CDATA[<p>There are few instances where disabling someone&#8217;s context menu is appropriate. In most cases it&#8217;s unnecessary and can even lead to infuriating your visitors.</p>
<p>Here are some ways to target all the image elements on a page while leaving the rest of the hypertext in peace.</p>
<h2>JavaScript</h2>
<p>Lightweight, no framework required and works well in IE 6, 7, 8, Chrome, FireFox and Safari. <a href="/wp-content/uploads/2010/03/Protect-Images-with-JavaScript.html">Demo »</a></p>
<pre class="brush: jscript; title: ; notranslate">
document.oncontextmenu = context_menu;

function context_menu(e) {
if (!e) var e = window.event;
	var eTarget = (window.event) ? e.srcElement : e.target;

	if (eTarget.nodeName == &quot;IMG&quot;) {
		//context menu attempt on top of an image element
		return false;
	}
}
</pre>
<hr />
<h2>jQuery</h2>
<p>Perhaps the prettiest code of the three. <a href="/wp-content/uploads/2010/03/Protect-Images-with-jQuery.html">Demo »</a></p>
<pre class="brush: jscript; title: ; notranslate">
$(document).ready(function(){
	$(document).bind(&quot;contextmenu&quot;,function(e){
		if(e.target.nodeName == 'IMG'){
			//context menu attempt on top of an image element
			return false;
		}
	});
});
</pre>
<hr />
<h2>MooTools</h2>
<p>Moo&#8230; <a href="/wp-content/uploads/2010/03/Protect-Images-with-MooTools.html">Demo »</a></p>
<pre class="brush: jscript; title: ; notranslate">
window.addEvent('domready', function() {
	$(document.body).addEvent('contextmenu', function(e) {
		if(e.target.nodeName == 'IMG') {
			//context menu attempt on top of an image element
			return false;
		}
	});
});
</pre>
<hr />
<h2>Final Thoughts</h2>
<p>With a bit more code you can target specific IDs, class names or any number of elemental combinations. Doing so will limit your context menu friendly fire and keep both you and your users in a happy balance.</p>
<p>Cheers!</p>
]]></content:encoded>
			<wfw:commentRss>http://forestmist.org/2010/03/disable-right-clicking-on-images-only/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>YES!</title>
		<link>http://forestmist.org/2004/03/yes/</link>
		<comments>http://forestmist.org/2004/03/yes/#comments</comments>
		<pubDate>Tue, 02 Mar 2004 02:58:16 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://forestmist.org/?p=435</guid>
		<description><![CDATA[The very new and exciting javascript DOM code for showing you an instant preview of the picture your uploading now works in both browsers! Muahuahahahah! Yes! Yes! Yes! IE 6 needed a slightly different variation of the command I was using and thanks to Peter-Paul Koch&#8217;s amazing site I have created some of the cleanest [...]]]></description>
			<content:encoded><![CDATA[<p>The very new and exciting javascript DOM code for showing you an instant preview of the picture your uploading now works in both browsers! Muahuahahahah! Yes! Yes! Yes!</p>
<p>IE 6 needed a slightly different variation of the command I was using and thanks to <a href="http://www.quirksmode.org/">Peter-Paul Koch&#8217;s amazing site</a> I have created some of the cleanest and most efficient code to date.</p>
<p>I&#8217;m so incredibly happy right now. It&#8217;s like I&#8217;ve opened my eyes for the first time. That&#8217;s how big this knowledge leap is for me. I can&#8217;t wait to launch the new image gallery feature (starting with my wedding photos no less) and let everyone see what I&#8217;m been working on.</p>
<p>If this was an RPG I&#8217;d have gained a level.</p>
]]></content:encoded>
			<wfw:commentRss>http://forestmist.org/2004/03/yes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

