<?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>En dansk blog om Javascript og Webudvikling</title>
	<atom:link href="http://rune.gronkjaer.dk/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://rune.gronkjaer.dk/blog</link>
	<description>Rune Grønkjær</description>
	<lastBuildDate>Tue, 31 Aug 2010 19:36:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>NY jQuery Modal Window &#8211; nu i min udgave</title>
		<link>http://rune.gronkjaer.dk/blog/2010/08/22/ny-jquery-modal-window/</link>
		<comments>http://rune.gronkjaer.dk/blog/2010/08/22/ny-jquery-modal-window/#comments</comments>
		<pubDate>Sun, 22 Aug 2010 17:51:01 +0000</pubDate>
		<dc:creator>Rune Grønkjær</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Modal Window]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[form]]></category>
		<category><![CDATA[formular]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[jquery modal window]]></category>
		<category><![CDATA[jquery plugin]]></category>
		<category><![CDATA[modal]]></category>
		<category><![CDATA[window]]></category>

		<guid isPermaLink="false">http://rune.gronkjaer.dk/blog/?p=455</guid>
		<description><![CDATA[Hermed genproduktionen af Modal Window plugin'et. Denne gang i en udgave, skrevet
udelukkende af mig selv. Se en masse demoer på siden <a href="http://rune.gronkjaer.dk/blog/jq-modal-window/"> jQuery Modal Window</a>. Min egen udgave byder på en række spændende udvidelser, som gør den endnu mere alsidig.]]></description>
			<content:encoded><![CDATA[Hermed genproduktionen af Modal Window plugin&#8217;et. Denne gang i en udgave, skrevet
udelukkende af mig selv. For nye læsere har jeg jo været tvunget til at skrive jQuery
Modal Window om, da jeg skiftede arbejde. Se en masse demoer på siden <a href="http://rune.gronkjaer.dk/blog/jq-modal-window/">
  jQuery Modal Window</a>.
<h2>
  jQuery Modal Window opbygning</h2>
jQuery Modal Window er opbygget af to dele. jQuery plugin delen og så en controller
klasse, hvis API benyttes til at styre <a href="http://rune.gronkjaer.dk/blog/jq-modal-window/">
  jQuery Modal Window</a> og dets indhold.
<h2>
  jQuery Modal Window udvidelser</h2>
Der er i min nye udgave blevet plads til et par forbedringer og udvidelser. jQuery
Modal Window kan nu nemmere arbejde sammen med andre plugins og der er kommet nogle
nye indstillingsmuligheder til.
<h3>
  jQuery Modal Window samarbejds API</h3>
For bedre at kunne servicere og samarbejde med andre plugins har jeg skrevet en
række hjælpemetoder.
<h4>
  jQuery Modal Window controller</h4>
<a href="http://rune.gronkjaer.dk/blog/jq-modal-window/">jQuery Modal Window</a>
controller har for det første en række public variable, som kan tilgåes for at komme
til elementer og informationer benyttet af jQuery Modal Window.
<ul>
  <li><strong>mwc.settings</strong><br />
    De settings, som ligger til grund for <a href="http://rune.gronkjaer.dk/blog/jq-modal-window/">
      jQuery Modal Window</a>. Det er endnu ikke muligt at ændre settings on the fly.
  </li>
  <li><strong>mwc.modal</strong><br />
    Selve modal vinduet, som jQuery objekt </li>
  <li><strong>mwc.modalContent</strong><br />
    Modal vinduets indhold. Altså det indhold du vælger skal vises. </li>
  <li><strong>mwc.background</strong><br />
    Baggrunden bag modal vinduet. Madpapiret kaldes det også ofte. </li>
  <li><strong>mwc.block</strong><br />
    <a href="http://rune.gronkjaer.dk/blog/jq-modal-window/">jQuery Modal Window</a>
    containeren, som indeholder både modal og background </li>
</ul>
Derudover har <a href="http://rune.gronkjaer.dk/blog/jq-modal-window/">jQuery Modal
  Window</a> også en række metoder, som kan benyttes udefra.
<ul>
  <li><strong>mwc.fireResizeModal(modalCss, ignoreStartEvent, noAnimate)</strong><br />
    Denne metode starter en gencalculering og placering af modal vinduet.<br />
    modalCss giver mulighed for at sende egne mål med på vinduets størrelse og placering.
    ignoreStartEvent vil tvinge <a href="http://rune.gronkjaer.dk/blog/jq-modal-window/">
      jQuery Modal Window</a> til IKKE at fyre onModalResize eventen, hvis den sættes
    til true. noAnimate vil ignorere en eventuel animation når modal vinduet ændrer
    størrelse. </li>
  <li><strong>mwc.calculateModalCSS()</strong><br />
    Denne metode udregner den plads og position modal vinduet vil kunne optage. Kan
    benyttes til at få nøjagtige mål på hvor stort ens indhold må være.<br />
    returnerer en modalCss. </li>
  <li><strong>mwc.deconstruct()</strong><br />
    Lukker og fjerner <a href="http://rune.gronkjaer.dk/blog/jq-modal-window/">jQuery
      Modal Window</a>. </li>
  <li><strong>mwc.getScrollBarWidth()</strong><br />
    Returnerer størrelsen på browserens scrollbar bredde. Kan være nyttig info, hvis
    man har tænkt sig at lave scroll. </li>
</ul>
<h4>
  jQuery Modal Window plugin API</h4>
Jeg har givet selve jQuery plugin&#8217;et en ekstra metode. Her vil jeg dog kort gennemgå
dem alle.
<ul>
  <li><strong>jQuery.fn.openModalWindow(settings)</strong><br />
    Denne metode åbner et bestemt indhold i et nyt <a href="http://rune.gronkjaer.dk/blog/jq-modal-window/">
      jQuery Modal Window</a>. Intet nyt under solen her. </li>
  <li><strong>jQuery.fn.closeModalWindow()</strong><br />
    Kaldes denne metode på et hvilket som helst element inde i <a href="http://rune.gronkjaer.dk/blog/jq-modal-window/">
      jQuery Modal Window&#8217;s</a> block element vil den lukke og fjerne sig selv. </li>
  <li><strong>jQuery.fn.updateModalWindow(modalCss, ignoreStartEvent)</strong><br />
    Kaldes denne metode på et hvilket som helst element inde i <a href="http://rune.gronkjaer.dk/blog/jq-modal-window/">
      jQuery Modal Window&#8217;s</a> block element vil den udregne en ny størrelse og position.
  </li>
  <li><strong>jQuery.fn.getModalWindowControl()</strong><br />
    Denne metode er ny og kaldes den på et hvilket som helst element inde i <a href="http://rune.gronkjaer.dk/blog/jq-modal-window/">
      jQuery Modal Window&#8217;s</a> block element vil den returnere <a href="http://rune.gronkjaer.dk/blog/jq-modal-window/">
        jQuery Modal Window</a> controlleren, hvis API man så kan benytte. </li>
</ul>
<h3>
  Ekstra indstillinger</h3>
<a href="http://rune.gronkjaer.dk/blog/jq-modal-window/">jQuery Modal Window</a>
har fået fire nye indstillingsmuligheder. To events og to booleans til at influere
hvordan <a href="http://rune.gronkjaer.dk/blog/jq-modal-window/">jQuery Modal Window</a>
fungerer.
<ul>
  <li><strong>settings.noBackground</strong><br />
    Hvis sat til true vil der ikke kommer noget madpapir bag modal vinduet.<br />
    Som standard sat til false. </li>
  <li><strong>settings.enableModalScroll</strong><br />
    Hvis sat til false vil <a href="http://rune.gronkjaer.dk/blog/jq-modal-window/">jQuery
      Modal Window</a> ikke lave scroll hvis indholdet bliver for stort.<br />
    Som standard sat til true. </li>
  <li><strong>settings.onModalResize</strong><br />
    Denne event bliver fyret lige inden <a href="http://rune.gronkjaer.dk/blog/jq-modal-window/">
      jQuery Modal Window</a> skal til at ændre størrelse og position på modal vinduet.<br />
    Ønsker man at benytte denne event skal man selv sørge for at ændre størrelsen på
    modal vinduet.<br />
    Som standard sat til null. </li>
  <li><strong>settings.onModalResized</strong><br />
    Denne event bliver fyret efter modal vinduet har ændret størrelse og position.<br />
    Som standard sat til null. </li>
</ul>
Se alle indstillinger på siden <a href="http://rune.gronkjaer.dk/blog/modal-window/dokumentation/">
  jQuery Modal Window dokumentation</a>.
<h2>
  jQuery Image Viewer</h2>
Jeg skriver allerede nu på den nye udgave af jQuery LightView, som kommer til at
hedde jQuery Image Viewer. jQuery Image Viewer kommer til at arbejde tæt sammen
med <a href="http://rune.gronkjaer.dk/blog/jq-modal-window/">jQuery Modal Window</a>,
som jeg tror vil udgøre et solidt fundament for jQuery Image Viewer. En ny blogpost
vil komme online så snart jeg er færdig.]]></content:encoded>
			<wfw:commentRss>http://rune.gronkjaer.dk/blog/2010/08/22/ny-jquery-modal-window/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery.append() hastighedstest</title>
		<link>http://rune.gronkjaer.dk/blog/2010/08/14/hastighedstest-af-jquery-append-metoden/</link>
		<comments>http://rune.gronkjaer.dk/blog/2010/08/14/hastighedstest-af-jquery-append-metoden/#comments</comments>
		<pubDate>Sat, 14 Aug 2010 17:15:59 +0000</pubDate>
		<dc:creator>Rune Grønkjær</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[tests]]></category>
		<category><![CDATA[append]]></category>
		<category><![CDATA[Document object model]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[hastigheds test]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://rune.gronkjaer.dk/blog/?p=357</guid>
		<description><![CDATA[Længe har jeg og mine kolleger spekuleret over hvilken metode, der er bedst til
at tilføje DOM elementer til andre DOM elementer. jQuery har en super metode <a href="http://api.jquery.com/append/">
  jQuery.append()</a>, som kan benyttes til opgaven. Man kalder jQuery.append()
på en jQuery selection, og sender det/de elementer med, som ønskes indsat inde i
det valgte element. Det i sig selv er dødsmart, da det sparer os for en masse bøvlet
kode. Problemet er så... Hvordan benytter man sig bedst af jQuery append metoden?
Specielt når man vil indsætte mange elementer i DOM'en, må der være tid at spare.]]></description>
			<content:encoded><![CDATA[<style type="text/css">
  #insertIntoEle { display: none; }
  table.resultsTable td { border: 1px solid #6c6c6c; background: #ccc; text-align: center; padding: 5px; }
  .looser { color: Red; }
  .winner { color: Green; }
</style>
Længe har jeg og mine kolleger spekuleret over hvilken metode, der er bedst til
at tilføje DOM elementer til andre DOM elementer. jQuery har en super metode <a href="http://api.jquery.com/append/">
  jQuery.append()</a>, som kan benyttes til opgaven. Man kalder jQuery.append()
på en jQuery selection, og sender det/de elementer med, som ønskes indsat inde i
det valgte element. Det i sig selv er dødsmart, da det sparer os for en masse bøvlet
kode. Problemet er så&#8230; Hvordan benytter man sig bedst af jQuery append metoden?
Specielt når man vil indsætte mange elementer i DOM&#8217;en, må der være tid at spare.<br />
<br />
I alle tests vil vi med et loop oprette X antal elementer og så indsætte dem i DOM&#8217;en.
Jeg har til hver test oprettet en metode til håndtering af testen. De følgende kodeeksempler
er skåret ned til det essentielle. Sidst i posten kan den samlede testkode dog læses.
<br />
<br />
Til alle jQuery.append() tests har jeg valgt at benytte mig af html tagget dl (Datalist)
da den passer udemærket til formålet. Eftersom resultatet helt sikkert vil variere
fra computer til computer og imellem browsere, skal man selv køre testen her på
sitet. Som standard indsættes 1000 elementer, men jeg har gjort det muligt for jer,
selv at vælge antallet af elementer.<br />
<br />
JQuery.append() testen vil starte med at indsætte det valgte antal elementer og
derefter gøre det samme med halvt så mange elementer. Den vil så halvere antallet
af elementer indtil der kun indsættes et enkelt. På den måde får man en række konkrete
data listet overskueligt i en tabel. Alle tests er kædet sammen og starter med lille
mellemrum.<br />
<br />
For at teste indsættelse af både store og små elementer har jeg delt testen op i
to. Den første del indsætter helt simple, tomme html dl elementer. Den anden indsætter
mere avancerede dl elementer, med både indhold og attributter.
<h2>
  Løsningsmuligheder</h2>
Vi forudsætter at vi skal have oprettet en række javascript DOM elementer, som så
skal sættes ind som child elementer til et allerede eksisterende DOM element. Vi
skal have fundet den mest optimale procedure og vi skal i øvrigt kunne forsøge os
med et flexibelt antal elementer.<br />
<br />
Jeg vil i alle tests referere til elementet &#8220;insertIntoEle&#8221;, som det element vi
ønsker at indsætte vores autogenererede DOM elementer i. InsertIntoEle vil i alle
tests være det samme og jeg vil inden hver test begynder sørge for at rydde det
for tidligere indsatte elementer. På den måde forventer jeg at denne del af testen
ikke vil kunne have indflydelse på resultatet.<br />
<br />
<strong>UPDATE:</strong> Jeg har nu udvidet testen så man også kan undersøge hvordan append fungerer UDEN oprettelse af elementer. Jeg har altså, i to nye serier af tests helt fjernet, den tid det tager at oprette elementerne fra ligningen.
<h3>
  Test 1: Indsætte elementer efterhånden som de bliver oprettet</h3>
Denne test vil benytte &#8220;document.createElement&#8221; metoden til at oprette de nye elementer.
Før hver ny append selectes insertIntoEle ud af DOM&#8217;en. <br />
<strong>UPDATE:</strong> Alle eksempler er nu udvidet med en ny testfunktion, som viser hvordan jeg benytter append uden at oprette elementerne. Alle elementer er altså oprettet udenfor selve testen, men kun i de nye testserier. De to gamle fungerer som de hele tiden har gjort.
<br />Denne test vil blive udført
i følgende rækkefølge:
<ol>
  <li>Oprette et nyt element </li>
  <li>Selecte insertIntoEle </li>
  <li>Appende til insertIntoEle </li>
  <li>Gentage 1, 2 og 3 indtil vi har oprettet og indsat alle elementer </li>
</ol>
<h4>
  Javascript til test 1</h4>
<pre class="brush: js">
//Simpel test
function (numberOfElements) {
  var ele = null;
  for (var i = 0; i < numberOfElements; i++) {
    jQuery("#insertIntoEle .insertIntoEle").append(createSimpleEle(i));
  }
}
//Avanceret test
function (numberOfElements) {
  var ele = null;
  for (var i = 0; i < numberOfElements; i++) {
    jQuery("#insertIntoEle .insertIntoEle").append(createAdvancedEle(i));
  }
}
//UPDATE: Simple and advanced no elements creation
function (insertIntoEle, numberOfElements) {
  var ele = null;
  for (var i = 0; i < numberOfElements; i++) {
    jQuery("#insertIntoEle .insertIntoEle").append(preCreatedElements[i]);
  }
}

//createAdvancedEle() metoden
function createAdvancedEle(i) {
  var newEle = jQuery(document.createElement("dd"));
  newEle.html('Some text followed by a link &lt;a href="http://rune.gronkjaer.dk"&lt;Runes blog&lt;/a&lt;')
          .attr("id", "eleID" + i)
          .attr("someWeirdAttribute", "someWeirdAttributeContent")
          .addClass("eleClass");
  return newEle;
}
//createSimpleEle() metoden
function createSimpleEle(i, createHtml) {
  var newEle;
  if (createHtml) {
    newEle = '&lt;dd&gt;&lt;/dd&gt;';
  } else {
    newEle = jQuery(document.createElement("dd"));
  }
  return newEle;
}
</pre>
<h3>
  Test 2: Som i test 1 men med cache</h3>
Jeg vil i denne test gemme insertIntoEle, som skal genbruges fra gang til gang.
Jeg formoder at dette vil speede processen voldsomt op. I denne test vil jeg gøre
det i følgende rækkefølge:
<ol>
  <li>Oprette et element af gangen </li>
  <li>Selecte det element, der skal indsættes i, og gemme den i en variabel </li>
  <li>Appende vores insertIntoEle </li>
  <li>Gentage 1 og 3 indtil vi har oprettet og indsat alle elementer </li>
</ol>
<h4>
  Javascript til test 2</h4>
<pre class="brush: js">
//Simpel test
function (insertIntoEle, numberOfElements) {
  var ele = null;
  for (var i = 0; i < numberOfElements; i++) {
    insertIntoEle.append(createSimpleEle(i));
  }
}
//Avanceret test
function (insertIntoEle, numberOfElements) {
  var ele = null;
  for (var i = 0; i < numberOfElements; i++) {
    var newEle = jQuery(document.createElement("dd"));
    insertIntoEle.append(createAdvancedEle(i));
  }
}
//UPDATE: Simple and advanced no elements creation
function (insertIntoEle, numberOfElements) {
  var ele = null;
  for (var i = 0; i < numberOfElements; i++) {
    insertIntoEle.append(preCreatedElements[i]);
  }
}
</pre>
<h3>
  Test 3: Oprette midlertiddig container</h3>
Her skal testes muligheden for at oprette et midlertidigt container element, som
alle nye elementer først indsættes i. Til slut vil jeg så appende containerens children
til insertIntoEle. Teorien skulle være at den midlertidige container speeder processen
op, da den udelukkende findes i computerens hukommelse, og altså ikke i DOM'en.
Det er dog lidt et skud i tågen, da det ligeså godt kan blive langsommere af denne
fremgangsmåde. I denne test vil jeg gøre det i følgende rækkefølge:
<ol>
  <li>Oprette det midlertidige container element </li>
  <li>Oprette et element af gangen </li>
  <li>Appende den midlertidige container </li>
  <li>Gentage 2 og 3 indtil vi har oprettet og indsat alle elementer </li>
  <li>Appende alle containerens children til insertIntoEle </li>
</ol>
<h4>
  Javascript til test 3</h4>
<pre class="brush: js">
//Simpel test
function (insertIntoEle, numberOfElements) {
  var ele = null, jQContainer = jQuery("&lt;dl&gt;");
  for (var i = 0; i < numberOfElements; i++) {
    ele = createSimpleEle(i);
    jQContainer.append(ele);
  }
  insertIntoEle.append(jQContainer.children());
}
//Avanceret test
function (insertIntoEle, numberOfElements) {
  var ele = null, jQContainer = jQuery("&lt;dl&gt;");
  for (var i = 0; i < numberOfElements; i++) {
    jQContainer.append(createAdvancedEle(i));
  }
  insertIntoEle.append(jQContainer.children());
}
//UPDATE: Simple and advanced no elements creation
function (insertIntoEle, numberOfElements) {
  insertIntoEle.append(preCreatedElements.children());
}
</pre>
<h3>
  Test 4: Skrive til en string og appende den til sidst</h3>
Denne test er meget simpel. Jeg konkatenerer alle elementer sammen til en lang html
string, som til sidst appendes til insertIntoEle. Jeg formoder at jQuery skal bruge
en masse tid på at parse string'en, og at denne metode vil være langsom. I denne
test vil jeg gøre det i følgende rækkefølge:
<ol>
  <li>Oprette en string </li>
  <li>Oprette et element af som en string </li>
  <li>Konkatenere elementet til stringen </li>
  <li>Gentage 2 og 3 indtil vi har oprettet alle elementer </li>
  <li>Appende string'en til insertIntoEle </li>
</ol>
<h4>
  Javascript til test 4</h4>
<pre class="brush: js">
//Simpel test
function (insertIntoEle, numberOfElements) {
  var ele = "";
  for (var i = 0; i < numberOfElements; i++) {
    ele += createSimpleEle(i, true);
  }
  insertIntoEle.append(ele);
}
//Avanceret test
function (insertIntoEle, numberOfElements) {
  var ele = "";
  for (var i = 0; i < numberOfElements; i++) {
    ele += '&lt;dd id="eleID' + i + '" class="eleClass"&lt;Some text followed by a link&lt;a href="http://rune.gronkjaer.dk"&lt;Runes blog&lt;/a&lt;&lt;/dd&lt;';
  }
  insertIntoEle.append(ele);
}
//UPDATE: Simple and advanced no elements creation
function (insertIntoEle, numberOfElements) {
  insertIntoEle.append(preCreatedElements);
}
</pre>
<h3>
  Test 5: Udnytte at jQuery er et array med jQuery.add() metoden</h3>
Denne test bygger på at jQuery objectet i bund og grund er et array af elementer.
Med jQuery.add() metode kan man tilføje elementer til en samling, og her skal den
så benyttes til at tilføje de nye elementer til vores container samling I denne
test vil jeg gøre det i følgende rækkefølge:
<ol>
  <li>Oprette et tomt jQuery objekt </li>
  <li>Oprette et element </li>
  <li>Tilføje elementet til jQuery objektet med jQuery.add() </li>
  <li>Gentage 2 og 3 indtil vi har oprettet og indsat alle elementer </li>
  <li>Appende den nu fyldte jQuery samling til insertIntoEle </li>
</ol>
<h4>
  Javascript til test 5</h4>
<pre class="brush: js">
//Simpel test
function (insertIntoEle, numberOfElements) {
  var ele = jQuery([]);
  for (var i = 0; i < numberOfElements; i++) {
    ele = ele.add(createSimpleEle(i));
  }
  insertIntoEle.append(ele);
}
//Avanceret test
function (insertIntoEle, numberOfElements) {
  var ele = jQuery([]);
  for (var i = 0; i < numberOfElements; i++) {
    ele = ele.add(createAdvancedEle(i));
  }
  insertIntoEle.append(ele);
}
//UPDATE: Simple and advanced no elements creation
function (insertIntoEle, numberOfElements) {
  insertIntoEle.append(preCreatedElements);
}
</pre>
<h2>
  Test med simple elementer
</h2>
<div>
  Antal elementer:
  <input id="numberOfElements" value="1000" type="text" />&nbsp;<input id="runTests"
    type="button" value="Kør tests" />
  <table cellpadding="5" cellspacing="0" border="0" id="resultsTable" class="resultsTable">
    <tr>
      <td>
        Antal elementer
      </td>
      <td title="Her selectes insertIntoEle for hvert element, som så appendes">
        T1: Normal
      </td>
      <td title="Her selectes insertIntoEle kun i starten og genbruges derefter. Hvert element indsættes hver gang den laves.">
        T2: Normal med cache
      </td>
      <td title="Elementerne laves og lægges i et wrapperelement, hvis children til sidst appendes til insertIntoEle">
        T3: Et append
      </td>
      <td title="En lang string med html for alle elementer laves. Derefter appendes html'en til insertIntoEle">
        T4: HTML append
      </td>
      <td title="Elementerne add'es til et tomt jQuery objekt, som så appendes til insertIntoEle til sidst">
        T5: Tomt jQuery objekt
      </td>
    </tr>
  </table>
  <h2>
    Test med avancerede elementer
  </h2>
  Vær opmærksom på at denne test kan tage længere tid da der indsættes elementer med
  både atributter og indhold.
  <br />
  <br />
  Antal elementer:
  <input id="numberOfElementsAdvanced" value="1000" type="text" />&nbsp;<input id="runAdvancedTests"
    type="button" value="Kør avancerede tests" />
  <table cellpadding="5" cellspacing="0" border="0" id="advancedResultsTable" class="resultsTable">
    <tr>
      <td>
        Antal elementer
      </td>
      <td title="Her selectes insertIntoEle for hvert element, som så appendes">
        T1: Normal
      </td>
      <td title="Her selectes insertIntoEle kun i starten og genbruges derefter. Hvert element indsættes hver gang den laves.">
        T2: Normal med cache
      </td>
      <td title="Elementerne laves og lægges i et wrapperelement, hvis children til sidst appendes til insertIntoEle">
        T3: Et append
      </td>
      <td title="En lang string med html for alle elementer laves. Derefter appendes html'en til insertIntoEle">
        T4: HTML append
      </td>
      <td title="Elementerne add'es til et tomt jQuery objekt, som så appendes til insertIntoEle til sidst">
        T5: Tomt jQuery objekt
      </td>
    </tr>
  </table>
  <h2>
    UPDATE: Test med simple elementer - fratrukket elementopretteles
  </h2>
  I denne test laver vi elementerne uden for selve testen. Det vil sige at vi her
  KUN måler den tid det tager for selve append() om at udføre opgaven. Antal elementer:
  <input id="numberOfElementsNoEleCreation" value="1000" type="text" />&nbsp;<input
    id="runTestsNoEleCreation" type="button" value="Kør tests" />
  <table cellpadding="5" cellspacing="0" border="0" id="resultsTableNoEleCreation"
    class="resultsTable">
    <tr>
      <td>
        Antal elementer
      </td>
      <td title="Her selectes insertIntoEle for hvert element, som så appendes">
        T1: Normal
      </td>
      <td title="Her selectes insertIntoEle kun i starten og genbruges derefter. Hvert element indsættes hver gang den laves.">
        T2: Normal med cache
      </td>
      <td title="Elementerne laves og lægges i et wrapperelement, hvis children til sidst appendes til insertIntoEle">
        T3: Et append
      </td>
      <td title="En lang string med html for alle elementer laves. Derefter appendes html'en til insertIntoEle">
        T4: HTML append
      </td>
      <td title="Elementerne add'es til et tomt jQuery objekt, som så appendes til insertIntoEle til sidst">
        T5: Tomt jQuery objekt
      </td>
    </tr>
  </table>
  <h2>
    UPDATE: Test med avancerede elementer - fratrukket elementopretteles
  </h2>
  I denne test laver vi elementerne uden for selve testen. Det vil sige at vi her
  KUN måler den tid det tager for selve append() om at udføre opgaven.<br />
  <br />
  Vær opmærksom på at denne test kan tage længere tid da der indsættes elementer med
  både atributter og indhold.
  <br />
  <br />
  Antal elementer:
  <input id="numberOfElementsAdvancedNoEleCreation" value="1000" type="text" />&nbsp;<input
    id="runAdvancedTestsNoEleCreation" type="button" value="Kør avancerede tests" />
  <table cellpadding="5" cellspacing="0" border="0" id="advancedResultsTableNoEleCreation"
    class="resultsTable">
    <tr>
      <td>
        Antal elementer
      </td>
      <td title="Her selectes insertIntoEle for hvert element, som så appendes">
        T1: Normal
      </td>
      <td title="Her selectes insertIntoEle kun i starten og genbruges derefter. Hvert element indsættes hver gang den laves.">
        T2: Normal med cache
      </td>
      <td title="Elementerne laves og lægges i et wrapperelement, hvis children til sidst appendes til insertIntoEle">
        T3: Et append
      </td>
      <td title="En lang string med html for alle elementer laves. Derefter appendes html'en til insertIntoEle">
        T4: HTML append
      </td>
      <td title="Elementerne add'es til et tomt jQuery objekt, som så appendes til insertIntoEle til sidst">
        T5: Tomt jQuery objekt
      </td>
    </tr>
  </table>
  <div id="insertIntoEle">
    <dl class="insertIntoEle">
    </dl>
  </div>
</div>
<h2>
  Konklusion</h2>
Overraskende nok er den klare vinder test nr. 3, html metoden. I de fleste tilfælde
performer den klart bedre end konkurrenterne. Men prøv det lige selv. Der er kæmpe
forskel på valget af browser og computer, hvilket også er ret spændende at teste.
Det er også værd at bemærke, at selvom indsættelse af mere avanceret html er langsomere,
så er det ikke meget langsommere. Man kan altså roligt indsætte også meget større
klumper kode, hvis blot man benytter den rigtige metode.<br />
<br />
Jeg håber at folk kan bruge testen til noget, jeg har i hvert fald lært en del.
Kom endelig med ideer, hvis jeg skal undersøge andre optimeringsmuligheder.
<h2>
  Hele koden</h2>
<strong>UPDATE:</strong> Koden er nu opdateret, så man kan se hvordan jeg udfører de to nye testserier. Det er bestemt ikke kønt mere, men det virker.
<h4>
  Javascript - Hele testkoden</h4>
<pre class="brush: js">
var testIsRunning = false, preCreatedElements = [];
jQuery(function () {
  //Binding the event witch will start the simple test
  jQuery("#runTests").click(function () {
    //Henter antal
    if (!testIsRunning) {
      testIsRunning = true;
      var numberOfElements = parseInt(jQuery("#numberOfElements").val());
      runAllTests(numberOfElements, "appendTests", "resultsTable");
    }
  });
  //Binding the event witch will start the advanced test
  jQuery("#runAdvancedTests").click(function () {
    if (!testIsRunning) {
      testIsRunning = true;
      var numberOfElements = parseInt(jQuery("#numberOfElementsAdvanced").val());
      runAllTests(numberOfElements, "advancedAppendTests", "advancedResultsTable");
    }
  });
  //Binding the event witch will start the advanced test
  jQuery("#runTestsNoEleCreation").click(function () {
    if (!testIsRunning) {
      testIsRunning = true;
      var numberOfElements = parseInt(jQuery("#numberOfElementsNoEleCreation").val());
      runAllTests(numberOfElements, "appendTestsNoEleCreation", "resultsTableNoEleCreation", true);
    }
  });
  //Binding the event witch will start the advanced test
  jQuery("#runAdvancedTestsNoEleCreation").click(function () {
    if (!testIsRunning) {
      testIsRunning = true;
      var numberOfElements = parseInt(jQuery("#numberOfElementsAdvancedNoEleCreation").val());
      runAllTests(numberOfElements, "advancedAppendTestsNoEleCreation", "advancedResultsTableNoEleCreation", true);
    }
  });
});
/*
* Starts all tests of a certain type
*/
function runAllTests(numberOfElements, testMethodsName, resultsTableID, preCreateElements) {
  //The results table is cleared
  jQuery('#' + resultsTableID + ' tr:not(:first)').remove();
  //A Timeout secures the stability of the tests as the browsers will treat each test as a new process with its's own timeout period
  window.setTimeout('initializeTest(' + numberOfElements + ', "' + testMethodsName + '", "' + resultsTableID + '", ' + preCreateElements + ')', 10);
}
/*
* Initialises a series of tests with a given number of elements to create
*/
function initializeTest(numberOfElements, testMethodsName, resultsTableID, preCreateElements) {
  var testResultTable = jQuery('#' + resultsTableID),
      currentTr = testResultTable.find("tr:last"), 
      timeTaken = -1;
  //Starts the new table row
  currentTr = jQuery(document.createElement("tr"));
  currentTr.append('&lt;td&gt;' + numberOfElements + '&lt;/td&gt;');
  testResultTable.append(currentTr);
  //Readies the first test in the series in a timeout
  window.setTimeout('runTest("test01", ' + numberOfElements + ', "' + testMethodsName + '", "' + resultsTableID + '", ' + preCreateElements + ')', 10);
}
/*
* Runs a test and then readies the next test
*/
function runTest(createMethodName, numberOfElements, testMethodsName, resultsTableID, preCreateElements) {
  if (preCreateElements) {
    preCreatedElements = window[testMethodsName + "PreCreate"][createMethodName](numberOfElements);
    var t = preCreatedElements;
  }
  var testResultTable = jQuery('#' + resultsTableID),
      currentTr = testResultTable.find("tr:last"),
      timeTaken = -1,
      insertIntoEle = jQuery("#insertIntoEle .insertIntoEle").html(""),
      startTime = (new Date()).getTime();
  //Gets the current set of tests (Simple or advanced)
  testMethods = window[testMethodsName];
  //Runs the current test
  testMethods[createMethodName](insertIntoEle, numberOfElements)
  //Clocks the runtime of the test
  timeTaken = (new Date()).getTime() - startTime;
  //Appends the test result to the test restult table
  currentTr.append('&lt;td result="' + timeTaken + '"&gt;' + timeTaken + ' ms&lt;/td&gt;');
  var currentMethodFound = false;
  //Find the next test
  for (methodName in testMethods) {
    if (currentMethodFound) {
      //The next test is found and is now being readied to run
      window.setTimeout('runTest("' + methodName + '", ' + numberOfElements + ', "' + testMethodsName + '", "' + resultsTableID + '", ' + preCreateElements + ')', 10);
      return;
    }
    //Checks to find the current test
    currentMethodFound = methodName === createMethodName;
  }
  //If we get to this point, no more tests can be run
  //Mark the looser and winner tests in the test result table
  markWinnerResult(resultsTableID);
  //If the number of elements have been counted down to 1, no mores tests can be run
  if (numberOfElements === 1) {
    testIsRunning = false;
    return;
  }
  //Number of elements is halved for the next test series
  numberOfElements = Math.ceil(numberOfElements / 2);
  //Next test series initialization is readied
  window.setTimeout('initializeTest(' + numberOfElements + ', "' + testMethodsName + '", "' + resultsTableID + '", ' + preCreateElements + ')', 10);
}
/*
* Below starts the actual tests
*/
//Two arrays are created to hold the variable number of tests
var appendTests = [],
    advancedAppendTests = [],
    appendTestsNoEleCreation = [],
    appendTestsNoEleCreationPreCreate = [],
    advancedAppendTestsNoEleCreation = [],
    advancedAppendTestsNoEleCreationPreCreate = [];
//Simple test 1
appendTests["test01"] = function test01(insertIntoEle, numberOfElements) {
  var ele = null;
  for (var i = 0; i < numberOfElements; i++) {
    jQuery("#insertIntoEle .insertIntoEle").append(createSimpleEle(i));
  }
};
//Simple test 2
appendTests["test02"] = function test02(insertIntoEle, numberOfElements) {
  var ele = null;
  for (var i = 0; i < numberOfElements; i++) {
    insertIntoEle.append(createSimpleEle(i));
  }
};
//Simple test 3
appendTests["test03"] = function test03(insertIntoEle, numberOfElements) {
  var ele = null, jQContainer = jQuery("&lt;dl&gt;");
  for (var i = 0; i < numberOfElements; i++) {
    ele = createSimpleEle(i);
    jQContainer.append(ele);
  }
  insertIntoEle.append(jQContainer.children());
};
//Simple test 4
appendTests["test04"] = function (insertIntoEle, numberOfElements) {
  var ele = "";
  for (var i = 0; i < numberOfElements; i++) {
    ele += createSimpleEle(i, true);
  }
  insertIntoEle.append(ele);
};
//Simple test 5
appendTests["test05"] = function (insertIntoEle, numberOfElements) {
  var ele = jQuery([]);
  for (var i = 0; i < numberOfElements; i++) {
    ele = ele.add(createSimpleEle(i));
  }
  insertIntoEle.append(ele);
};
//Advanced test 1
advancedAppendTests["test01"] = function (insertIntoEle, numberOfElements) {
  var ele = null;
  for (var i = 0; i < numberOfElements; i++) {
    jQuery("#insertIntoEle .insertIntoEle").append(createAdvancedEle(i));
  }
};
//Advanced test 2
advancedAppendTests["test02"] = function (insertIntoEle, numberOfElements) {
  var ele = null;
  for (var i = 0; i < numberOfElements; i++) {
    var newEle = jQuery(document.createElement("dd"));
    insertIntoEle.append(createAdvancedEle(i));
  }
};
//Advanced test 3
advancedAppendTests["test03"] = function (insertIntoEle, numberOfElements) {
  var ele = null, jQContainer = jQuery("&lt;dl&gt;");
  for (var i = 0; i < numberOfElements; i++) {
    jQContainer.append(createAdvancedEle(i));
  }
  insertIntoEle.append(jQContainer.children());
};
//Advanced test 4
advancedAppendTests["test04"] = function (insertIntoEle, numberOfElements) {
  var ele = "";
  for (var i = 0; i < numberOfElements; i++) {
    ele += createAdvancedEle(i, true);
  }
  insertIntoEle.append(ele);
};
//Advanced test 5
advancedAppendTests["test05"] = function (insertIntoEle, numberOfElements) {
  var ele = jQuery([]);
  for (var i = 0; i < numberOfElements; i++) {
    ele = ele.add(createAdvancedEle(i));
  }
  insertIntoEle.append(ele);
};
/********************************************************************************************/

//Simple NoEleCreation test 1
appendTestsNoEleCreation["test01"] = function test01(insertIntoEle, numberOfElements) {
  var ele = null;
  for (var i = 0; i < numberOfElements; i++) {
    jQuery("#insertIntoEle .insertIntoEle").append(preCreatedElements[i]);
  }
};
appendTestsNoEleCreationPreCreate["test01"] =
appendTestsNoEleCreationPreCreate["test02"] = function test01(numberOfElements) {
  preCreatedElements = [];
  for (var i = 0; i < numberOfElements; i++) {
    preCreatedElements.push(createSimpleEle(i));
  }
  return preCreatedElements;
};
//Simple NoEleCreation test 2
appendTestsNoEleCreation["test02"] = function (insertIntoEle, numberOfElements) {
  var ele = null;
  for (var i = 0; i < numberOfElements; i++) {
    insertIntoEle.append(preCreatedElements[i]);
  }
};
//Simple NoEleCreation test 3
appendTestsNoEleCreation["test03"] = function (insertIntoEle, numberOfElements) {
  insertIntoEle.append(preCreatedElements.children());
};
appendTestsNoEleCreationPreCreate["test03"] = function test01(numberOfElements) {
  var ele = null, preCreatedElements = jQuery("&lt;dl&gt;");
  for (var i = 0; i < numberOfElements; i++) {
    preCreatedElements.append(createSimpleEle(i));
  }
  return preCreatedElements;
};
//Simple NoEleCreation test 4
appendTestsNoEleCreation["test04"] = function (insertIntoEle, numberOfElements) {
  insertIntoEle.append(preCreatedElements);
};
appendTestsNoEleCreationPreCreate["test04"] = function (numberOfElements) {
  preCreatedElements = "";
  for (var i = 0; i < numberOfElements; i++) {
    preCreatedElements += createSimpleEle(i, true);
  }
  return preCreatedElements;
};
//Simple NoEleCreation test 5
appendTestsNoEleCreation["test05"] = function (insertIntoEle, numberOfElements) {
  insertIntoEle.append(preCreatedElements);
};
appendTestsNoEleCreationPreCreate["test05"] = function (numberOfElements) {
  preCreatedElements = jQuery([]);
  for (var i = 0; i < numberOfElements; i++) {
    preCreatedElements = preCreatedElements.add(createSimpleEle(i));
  }
  return preCreatedElements;
};

//Advanced NoEleCreation test 1
advancedAppendTestsNoEleCreation["test01"] = function (insertIntoEle, numberOfElements) {
  var ele = null;
  for (var i = 0; i < numberOfElements; i++) {
    jQuery("#insertIntoEle .insertIntoEle").append(preCreatedElements[i]);
  }
};
advancedAppendTestsNoEleCreationPreCreate["test01"] =
advancedAppendTestsNoEleCreationPreCreate["test02"] = function (numberOfElements) {
  preCreatedElements = [];
  for (var i = 0; i < numberOfElements; i++) {
    preCreatedElements.push(createAdvancedEle(i));
  }
  return preCreatedElements;
};
//Advanced NoEleCreation test 2
advancedAppendTestsNoEleCreation["test02"] = function (insertIntoEle, numberOfElements) {
  var ele = null;
  for (var i = 0; i < numberOfElements; i++) {
    insertIntoEle.append(preCreatedElements[i]);
  }
};
//Advanced NoEleCreation test 3
advancedAppendTestsNoEleCreation["test03"] = function (insertIntoEle, numberOfElements) {
  insertIntoEle.append(preCreatedElements.children());
};
advancedAppendTestsNoEleCreationPreCreate["test03"] = function (numberOfElements) {
  var ele = null, preCreatedElements = jQuery("&lt;dl&gt;");
  for (var i = 0; i < numberOfElements; i++) {
    preCreatedElements.append(createAdvancedEle(i));
  }
  return preCreatedElements;
};
//Advanced NoEleCreation test 4
advancedAppendTestsNoEleCreation["test04"] = function (insertIntoEle, numberOfElements) {
  insertIntoEle.append(preCreatedElements);
};
advancedAppendTestsNoEleCreationPreCreate["test04"] = function ( numberOfElements) {
  preCreatedElements = "";
  for (var i = 0; i < numberOfElements; i++) {
    preCreatedElements += createAdvancedEle(i, true);
  }
  return preCreatedElements;
};
//Advanced NoEleCreation test 5
advancedAppendTestsNoEleCreation["test05"] = function (insertIntoEle, numberOfElements) {
  insertIntoEle.append(preCreatedElements);
};
advancedAppendTestsNoEleCreationPreCreate["test05"] = function (numberOfElements) {
  preCreatedElements = jQuery([]);
  for (var i = 0; i < numberOfElements; i++) {
    preCreatedElements = preCreatedElements.add(createAdvancedEle(i));
  }
  return preCreatedElements;
};

/********************************************************************************************/
//A method for creating the advanced elements. This ensures that they are alike every time.
function createAdvancedEle(i, createHtml) {
  var newEle;
  if (createHtml) {
    newEle = '&lt;dd id="eleID' + i + '" class="eleClass"&gt;Some text followed by a link&lt;a href="http://rune.gronkjaer.dk"&gt;Runes blog&lt;/a&gt;&lt;/dd&gt;';
  } else {
    newEle = jQuery(document.createElement("dd"));
    newEle.html('Some text followed by a link &lt;a href="http://rune.gronkjaer.dk"&gt;Runes blog&lt;/a&gt;')
          .attr("id", "eleID" + i)
          .attr("someWeirdAttribute", "someWeirdAttributeContent")
          .addClass("eleClass");
  }
  return newEle;
}
//A method for creating the simple elements. This ensures that they are alike every time.
function createSimpleEle(i, createHtml) {
  var newEle;
  if (createHtml) {
    newEle = '&lt;dd&gt;&lt;/dd&gt;';
  } else {
    newEle = jQuery(document.createElement("dd"));
  }
  return newEle;
}
//Helping method for marking the winning and loosing test of each test series
function markWinnerResult(resultsTableID) {
  var winner = -1, looser = -1, results = jQuery('#' + resultsTableID + ' tr:last td:not(:first)');
  for (var i = 0; i < results.length; i++) {
    var thisResult = parseInt(jQuery(results[i]).attr("result"));
    if (winner === -1 || winner > thisResult) {
      winner = thisResult;
    }
    if (looser < thisResult) {
      looser = thisResult;
    }
  }
  results.filter("[result=" + winner + "]").addClass("winner");
  results.filter("[result=" + looser + "]").addClass("looser");
}
</pre>
<h3>
  Tak til</h3>
Jesper Holm Damgård for ideer og hjælp til udførelsen af testen.
<script src="http://rune.gronkjaer.dk/blog/wp-content/BlogPosts/jQuery_Append_test.js"
  type="text/javascript"></script>
]]></content:encoded>
			<wfw:commentRss>http://rune.gronkjaer.dk/blog/2010/08/14/hastighedstest-af-jquery-append-metoden/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Nyt job hos Tea Solutions, nye udfordringer</title>
		<link>http://rune.gronkjaer.dk/blog/2010/08/01/nyt-job-hos-tea-solutions-nye-udfordringer/</link>
		<comments>http://rune.gronkjaer.dk/blog/2010/08/01/nyt-job-hos-tea-solutions-nye-udfordringer/#comments</comments>
		<pubDate>Sun, 01 Aug 2010 20:02:33 +0000</pubDate>
		<dc:creator>Rune Grønkjær</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[umbraco]]></category>
		<category><![CDATA[konkurrent]]></category>
		<category><![CDATA[nye udfordringer]]></category>
		<category><![CDATA[Nyt job]]></category>
		<category><![CDATA[Tea Solutions]]></category>

		<guid isPermaLink="false">http://rune.gronkjaer.dk/blog/?p=366</guid>
		<description><![CDATA[Jeg har opsagt mit job hos Co3 og er blevet ansat, som webudvikler hos <a title="Tea Solutions" href="http://www.teasolutions.dk/" target="_blank">Tea Solutions</a>. Det betyder en masse nye udfordring og et farvel til en flok fantastiske mennesker.]]></description>
			<content:encoded><![CDATA[Så kom dagen hvor jeg har søgt nye græsgange. Jeg har valgt, at sige op hos Co3, for at prøve lykken hos mine gode venner og kamerater i firmaet <a title="Tea Solutions" href="http://www.teasolutions.dk/" target="_blank">Tea Solutions</a>.
<h2>Tak til mine gamle kolleger</h2>
Jeg vil gerne benytte denne chance til, at takke <a title="Co3 - Webagency" href="http://www.co3.dk" target="_blank">Co3 </a>og alle mine fantastiske forhenværende kolleger. Jeg er glad for, at jeg har haft muligheden for, at arbejde sammen med en så dygtig og dynamisk flok mennesker. Mine næsten tre år i Co3 har budt på masser af gode oplevelser og ikke mindst erfaringer, som jeg vil tage med.
<h2>Tea Solutions bliver konkurrent</h2>
Når det er sagt skal jeg så nu forholde mig til den nye situation. Indtil nu har <a title="Tea Solutions" href="http://www.teasolutions.dk/" target="_blank">Tea Solutions</a> fokuseret på udvikling af specialsoftware til web, såvel som desktopapplikationer. Min funktion hos <a title="Tea Solutions" href="http://www.teasolutions.dk/" target="_blank">Tea Solutions</a> bliver webudvikler, hvilket betyder en oprustning af den del af firmaets kompetencer. Det betyder også at <a title="Tea Solutions" href="http://www.teasolutions.dk/" target="_blank">Tea Solutions</a> i høj grad vil blive en konkurrent til Co3.

Den nye konkurrencesituation har stor betydning for mig og mine tidligere produkter og projekter. Alt hvad jeg ved Co3 har lavet til deres kunder tilhører retmæssigt dem, og jeg vil ikke kunne tage det med mig. Det ærgrer mig, men det er det jeg må forholde mig til. Det betyder mere konkret, at alle mine jQuery Plugins ikke er mine mere. Med min tidligere <a title="Christian Søsted Poulsens Blog" href="http://www.sosted.dk/" target="_blank">chef</a> har jeg så aftalt, at jeg skal skrive dem alle om igen fra bunden.
<h2>Omskrivning af jQuery Plugins</h2>
At skulle skrive alle mine jQuery Plugins om igen bliver spændende og de trænger alligevel til det. Meget vand er løbet igennem åen siden de blev lavet, og jeg vil kunne skrive dem mere effektivt, samt optimere hastigheden på dem markant. Jeg tager derfor imod udfordringen med kyshånd. I første omgang skal jeg have skrevet <a title="jQuery Modal window" href="http://rune.gronkjaer.dk/blog/jq-modal-window/" target="_self">jQuery Modal Window</a> om. Den skal nemlig bruges, når flagskibet <a title="jQuery Lightview" href="http://rune.gronkjaer.dk/blog/lightview/" target="_self">jQuery Lightview</a> skal omskrives. Jeg håber på at kunne lave <a title="jQuery Modal window" href="http://rune.gronkjaer.dk/blog/jq-modal-window/" target="_self">jQuery Modal Window</a> så smart og dynamisk at den kan danne rygraden i <a title="jQuery Lightview" href="http://rune.gronkjaer.dk/blog/lightview/" target="_self">jQuery Lightview</a>. Men nu må vi se hvor det vil bære hen.

Derudover har jeg en række plugins, som ikke alle er blevet beskrevet her på bloggen:
<ul>
	<li>Banner shifter (Lavet til at lade indhold skifte med et vist interval)</li>
	<li>Tooltip (Et lille let plugin, som viser noget indhold som tooltip for noget andet indhold)</li>
	<li>Validation (&#8220;Mit&#8221; formular valideringsplugin)</li>
	<li>Scrollarea (Et plugin der laver et område, som kan scrolles med en anden scrollbar end browserens medfødte)</li>
</ul>
Om alle plugins får en tur vil tiden vise. Nogle vil jeg sikkert først få ordnet når jeg får brug for dem.
<h2>Fremtiden med Tea Solutions</h2>
I morgen starter så mit nye arbejdsliv hos <a title="Tea Solutions" href="http://www.teasolutions.dk/" target="_blank">Tea Solutions</a>. Jeg glæder mig enormt til, at udfolde mine evner et nyt sted med mine kamerater. <a title="Tea Solutions" href="http://www.teasolutions.dk/" target="_blank">Tea Solutions</a> er indtil videre et lille firma, som jeg var med til at starte med Morten Vejhe og Anders Burla efter datamatikeruddannelsen. Indtil nu har <a title="Tea Solutions" href="http://www.teasolutions.dk/" target="_blank">Tea Solutions</a>, som sagt mest koncentreret sig om meget avancerede specialløsninger, hvilket passer godt ind i min bog. På webfronten benytter de content management systemet <a title="Umbraco CMS" href="http://umbraco.org/" target="_blank">Umbraco</a>.

<a title="Umbraco CMS" href="http://umbraco.org/" target="_blank">Umbraco</a> er et open source CMS, som blev startet helt tilbage i år 2000. <a title="Umbraco CMS" href="http://umbraco.org/" target="_blank">Umbraco&#8217;s</a> popularitet er de seneste år eksploderet og bliver brugt på tusindvis af websites i hele verden. Jeg glæder mig til at udfordre og blive udfordret af et så lovende system.]]></content:encoded>
			<wfw:commentRss>http://rune.gronkjaer.dk/blog/2010/08/01/nyt-job-hos-tea-solutions-nye-udfordringer/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Sprogversionering af min wordpress blog</title>
		<link>http://rune.gronkjaer.dk/blog/2010/07/17/sprogversionering-af-min-wordpress-blog/</link>
		<comments>http://rune.gronkjaer.dk/blog/2010/07/17/sprogversionering-af-min-wordpress-blog/#comments</comments>
		<pubDate>Sat, 17 Jul 2010 17:43:03 +0000</pubDate>
		<dc:creator>Rune Grønkjær</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[sprog]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[sprogversionering]]></category>

		<guid isPermaLink="false">http://rune.gronkjaer.dk/blog/?p=348</guid>
		<description><![CDATA[Så kan jeg løfte sløret fra en nyhed kun meget få har vidst besked om. Som i nok kan regne ud fra overskriften, så har jeg nu udgivet min blog på engelsk også. I første omgang har jeg oversat alle mine gamle indlæg og sider, så man nu kan læse dem på engelsk også.]]></description>
			<content:encoded><![CDATA[Så kan jeg løfte sløret fra en nyhed kun meget få har vidst besked om. Som i nok kan regne ud fra overskriften, så har jeg nu sprogversioneret min WordPress blog til engelsk. I første omgang har jeg oversat alle mine gamle indlæg og sider, så man nu kan læse dem på engelsk også.

Det betyder at alle mine indlæg fremover vil blive versioneret på begge sprog. Hvorfor så gøre det, hvis man bare kunne nøjes med eksempelvis engelsk, som alle ville kunne forstå? Det og flere andre ting indgik i mine overvejelser, som endte ud i en række gode argumenter.
<ol>
	<li>Som et lille eksperiment.
<ol>
	<li>Jeg vil se hvordan mine engelske indlæg bliver ratet på google i forhold til mine danske.</li>
	<li>Vil jeg kunne skabe mere trafik med en engelsk version? Den danske har indtil nu skabt et yderst begrænset besøgstal.</li>
</ol>
</li>
	<li>Snart vil jeg skulle til at blogge om Content management systemet Umbraco, som har mange udenlandske brugere. De vil ikke få noget ud af min danske blog.</li>
	<li>Jeg vil gerne holde fast i min danske blog, da jeg syntes der er alt for få tekniske blogs på dansk. Sikkert fordi målgruppen er alt for lille.</li>
</ol>
Næste spørgsmål der så skal besvares er, hvordan jeg har sprogversioneret min wordpress blog?

Svaret er ligeså simpelt som det er bøvlet. Jeg har oprettet endnu en WordPress blog på mit domæne. Jeg har godt nok ledt efter et passende plugin, der ville kunne gøre det for mig, men har ikke fundet nogle tilfredsstillende. At have to seperate blogs gør så til gengæld at jeg kan ændre bloggens udseende og statiske tekster alt efter sprogets behov.

I første omgang har jeg kun indsat flag og links mellem de to sprogversioner, så I brugere kan vælge jeres sprog. Det kunne dog være at billedet i toppen senere skal versioneres også. På den engelske version har jeg ikke så mange widgets, som min danske, da jeg fx ikke kan linke til mine danske blogvenners blogs.

Nu vil det så blive spændende at følge udviklingen efter jeg begynder at udgive mine indlæg på en engelsk version også. Næste indlæg bliver sikkert omkring et jQuery plugin til sortering af DOM elementer ud fra forskellige kriterier. Indlægget udkommer så snart jeg får finpudset min kode.

Jeg håber I (Eller nogle engelsklæsende) kommer til at nyde mine indlæg på engelsk og at I ikke flamer mig alt for meget for min dårlige engelske grammatik.]]></content:encoded>
			<wfw:commentRss>http://rune.gronkjaer.dk/blog/2010/07/17/sprogversionering-af-min-wordpress-blog/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>NYT JQuery Modal Window plugin</title>
		<link>http://rune.gronkjaer.dk/blog/2010/07/06/nyt-jquery-modal-window-plugin/</link>
		<comments>http://rune.gronkjaer.dk/blog/2010/07/06/nyt-jquery-modal-window-plugin/#comments</comments>
		<pubDate>Tue, 06 Jul 2010 12:40:09 +0000</pubDate>
		<dc:creator>Rune Grønkjær</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[form]]></category>
		<category><![CDATA[formular]]></category>
		<category><![CDATA[modal]]></category>
		<category><![CDATA[udvidelse]]></category>
		<category><![CDATA[window]]></category>

		<guid isPermaLink="false">http://rune.gronkjaer.dk/blog/?p=300</guid>
		<description><![CDATA[Jesper Holm Damgaard og jeg selv har i længere tid arbejdet på en ny version af mit gamle jQuery modal block plugin, som også bliver brugt i <a href="/blog/lightview/">jQ LightView</a>. Den nye version er kodet op fra bunden og vi har optimeret koden hele vejen igennem. Den kan alt hvad den gamle kunne, bare bedre og på en mere solid måde.
]]></description>
			<content:encoded><![CDATA[Jesper Holm Damgaard og jeg selv har i længere tid arbejdet på en ny version af mit gamle jQuery modal block plugin, som også bliver brugt i <a href="/blog/lightview/">jQ LightView</a>. Den nye version er kodet op fra bunden og vi har optimeret koden hele vejen igennem. Den kan alt hvad den gamle kunne, bare bedre og på en mere solid måde.
<h2>Hvad kan jQuery Modal Window?</h2>
<ul>
	<li>Vise alle slags html indhold i et modal vindue</li>
	<li>Styre placeringen af modal vinduet</li>
	<li>Styre baggrundens/madpapirets farve og gennemsigtighed</li>
	<li>Give adgang til vigtige events der bliver fyret når modalvinduet åbnes eller lukkes</li>
	<li>Give mulighed for at bestemme animationens tid</li>
</ul>
<h2>Hvordan gør den det?</h2>
JQuery Modal Window plugin&#8217;et giver adgang til nogle funktioner, der kan kaldes på alle jQuery objekter/samlinger. Den vil tage det valgte indhold og flytte det i DOM&#8217;en til den modal som bliver lavet til formålet. Det indhold der vises i modal&#8217;en er altså det eksakt samme indhold som det man valgte. Ved at gøre det på den måde vil man på et hvilket som helst tidspunkt kunne ændre på indholdet og ændringerne vil blive bibeholdt.

Før jQuery plugin&#8217;et flytter indholdet vil den indsætte en markør, som benyttes til at flytte indholdet tilbage på plads, når modal vinduet lukkes igen.
<h2>Se jQuery Modal Window i aktion</h2>
<a title="Gå til jQuery Modal Window eksempler" href="http://rune.gronkjaer.dk/blog/jq-modal-window/">Her på siden er en omfattende side med eksempler på nogle af de mange muligheder jQuery Modal Window giver.</a> På siden kan du også downloade en minified version af pluginet og bruge den på din egen side.]]></content:encoded>
			<wfw:commentRss>http://rune.gronkjaer.dk/blog/2010/07/06/nyt-jquery-modal-window-plugin/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>jQ Lightview 2.0 released</title>
		<link>http://rune.gronkjaer.dk/blog/2010/05/06/jq-lightview-2-0-released/</link>
		<comments>http://rune.gronkjaer.dk/blog/2010/05/06/jq-lightview-2-0-released/#comments</comments>
		<pubDate>Thu, 06 May 2010 13:52:37 +0000</pubDate>
		<dc:creator>Rune Grønkjær</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[LightView]]></category>
		<category><![CDATA[LightView 2.0]]></category>
		<category><![CDATA[release]]></category>

		<guid isPermaLink="false">http://rune.gronkjaer.dk/blog/?p=181</guid>
		<description><![CDATA[Så kom den store dag hvor version 2.0 er udkommet.<br /><br />
Den nye version byder på en stor ny feature, som har været ønsket i lang tid. Der er desuden blevet rettet en bug, som også har givet hovedpine for nogle brugere. <a href="http://rune.gronkjaer.dk/blog/lightview">Se eksempler og cases her, eller download den gratis og brug den på dit eget website.</a>
]]></description>
			<content:encoded><![CDATA[Så kom den store dag hvor version 2.0 er udkommet.<br /><br />
Den nye version byder på en stor ny feature, som har været ønsket i lang tid. Der er desuden blevet rettet en bug, som også har givet hovedpine for nogle brugere. <a href="http://rune.gronkjaer.dk/blog/lightview">Se eksempler og cases her, eller download den gratis og brug den på dit eget website.</a>
<h2>Ny feature</h2>
<h3>Problem</h3>
Infoområdet under billedet har være med fra starten og giver mulighed for at indsætte sin egen html, med informationer om billedet, eller hvad man ellers har kunnet finde på at sætte ind. Det har dog kun været muligt at vælge en fast højde for området, som ikke ændresnår billederne bliver større eller mindre. Det har især været et problem hvis billederne har varieret i bredden, da teksten så vil kunne presses sammen og ud af det angivne område.
<h3>Løsning</h3>
Løsningen er blevet en mouseover effekt på informationsområdet, som lader området udvide sig op over billedet. Der måles på indholdets størrelse, så man altid vil kunne få vist hele indholdet. En pil bliver indsat over informationsområdet, når indholdets højde overskrider højden på området.<br /><br />
Til pilen er der lavet en ny grafik, som kan overskrives i en ny setting &#8220;InfoArrowUp&#8221;. Jeg har været nød til at ændre på &#8220;ImageMarginBottom&#8221; setting&#8217;en for at gøre plads til den nye pil. Den er derfor ændret fra 10 til 20 pixels. <a href="http://rune.gronkjaer.dk/blog/lightview/lightview-standard-settings/">Læs om alle settings her.</a>
<h2>Bugfixes</h2>
<h3>vertikal placering af højre/venstre pile</h3>
højrevenstrepilene har været fastlåst med en bestemt top position. Denne position er kun blevet ændret når pilen er blevet vist. Hvis galleriet derfor resizer, fulgte pilenes vertikale position altså ikke med, og de kunne komme til at sidde skævt i forhold til galleriet.]]></content:encoded>
			<wfw:commentRss>http://rune.gronkjaer.dk/blog/2010/05/06/jq-lightview-2-0-released/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>jQLightview 2.0 lige på trapperne</title>
		<link>http://rune.gronkjaer.dk/blog/2010/04/21/jqlightview-2-0-lige-pa-trapperne/</link>
		<comments>http://rune.gronkjaer.dk/blog/2010/04/21/jqlightview-2-0-lige-pa-trapperne/#comments</comments>
		<pubDate>Wed, 21 Apr 2010 20:41:16 +0000</pubDate>
		<dc:creator>Rune Grønkjær</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[LightView]]></category>

		<guid isPermaLink="false">http://rune.gronkjaer.dk/blog/?p=161</guid>
		<description><![CDATA[Jeg arbejder på en splinterny version af jQLightview. Den nye version byder på nogle mindre rettelser og en stor ny feature, der giver mulighed for en variabel størrelse på beskrivelsesfeltet. Den nye feature kommer efter ønske fra Holstebro kunstmuseum, som skal benytte LightView plugin'et på deres site.]]></description>
			<content:encoded><![CDATA[Siden jeg i marts 2009 udviklede version 1.0 af mit LightView er den blevet rettet
og forbedret flere gange og er nu i en solid version 1.5. På tegnebrættet har jeg
en større ændring af galleriet, som betyder at man kan have en variabel størrelse
af beskrivelsesområdet. Det er måske ikke umiddelbart noget, der siger dig noget,
hvis du endnu ikke har set plugin&#8217;et i aktion. Kig dog en smut forbi <a href="http://rune.gronkjaer.dk/blog/lightview/">
  Pluginsiden her på min blog</a> og se flere eksempler. Jeg har nu valgt at dele
mit plugin, så alle kan få glæde af det. Du kan downloade og bruge plugin&#8217;et, som
du lyster.<br /><br />
Rettelserne til jQLightview laves på opfordring fra <a href="http://www.holstebrokunstmuseum.dk">
  Holstebro kunstmuseum</a>, som skal benytte plugin&#8217;et til at vise et stort udpluk
af deres mange kunstværker. <a href="http://www.holstebrokunstmuseum.dk">Holstebro
  kunstmuseum</a> har rigtigt mange informationer om hvert enkelt kunstværk og med
den nuværende jQLightview kan de kun vise en fast mængde tekst. Det laver jeg altså
om på nu.
<h2>
  Hurtigt eksempel</h2>
Her kan du se et eksempel på hvordan jQLightview fungerer med beskrivelser i variende
længde. Nogle af dem er for lange, andre for korte.
<div id="ImageGalleryFullMonty" class="imageGallery">
  <img src="http://rune.gronkjaer.dk/blog/wp-content/BlogPages/javascript_rgLightview/thumbs/aakande-blomst.jpg"
    imagehref="http://rune.gronkjaer.dk/blog/wp-content/BlogPages/javascript_rgLightview/aakande-blomst.jpg"
    href="http://rune.gronkjaer.dk/blog/wp-content/BlogPages/javascript_rgLightview/download/aakande-blomst.jpg"
    type="image" header="Åkandeblomst" description="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent sit amet sapien massa. Fusce vitae lectus elit. Fusce eu est eu erat convallis consectetur. Aliquam interdum, dui eu mattis pretium, nisi metus mollis ipsum, commodo convallis leo elit vel nisi. Nunc in est at nulla imperdiet ornare. Sed quis mauris eget lorem aliquam varius. Suspendisse elementum posuere leo, malesuada posuere risus rutrum nec. Pellentesque vulputate nibh vel nibh molestie vehicula. Nulla aliquam enim semper enim tempor commodo. Morbi dapibus libero a est lobortis auctor. Maecenas congue bibendum metus vel mattis. Suspendisse sapien odio, interdum in ornare vitae, accumsan et quam. Sed tincidunt eleifend aliquam. Donec ut leo eget est volutpat aliquet."
    showinfo="true" />
  <img src="http://rune.gronkjaer.dk/blog/wp-content/BlogPages/javascript_rgLightview/thumbs/brun-og-gul-blomst.jpg"
    imagehref="http://rune.gronkjaer.dk/blog/wp-content/BlogPages/javascript_rgLightview/brun-og-gul-blomst.jpg"
    href="http://rune.gronkjaer.dk/blog/wp-content/BlogPages/javascript_rgLightview/download/brun-og-gul-blomst.jpg"
    type="image" header="Gul og brun blomst" description="Nulla rhoncus, urna et congue iaculis, ligula erat ultrices dolor, eget tempor lacus lorem eu magna. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla ullamcorper, risus sollicitudin blandit ultrices, eros tortor blandit odio, non semper erat ligula et leo. Duis vitae arcu libero, id malesuada velit. Fusce varius molestie nisl, vitae convallis mauris volutpat eget. In hac habitasse platea dictumst."
    showinfo="true" />
  <img src="http://rune.gronkjaer.dk/blog/wp-content/BlogPages/javascript_rgLightview/thumbs/lyseroed-aakande.jpg"
    imagehref="http://rune.gronkjaer.dk/blog/wp-content/BlogPages/javascript_rgLightview/lyseroed-aakande.jpg"
    href="http://rune.gronkjaer.dk/blog/wp-content/BlogPages/javascript_rgLightview/download/lyseroed-aakande.jpg"
    type="image" header="Dråber på blad" description="Integer volutpat augue id nisi gravida scelerisque. Nulla condimentum lobortis neque nec tincidunt. Integer orci eros, scelerisque nec iaculis nec, varius tristique tellus. In vulputate ullamcorper felis, ac sollicitudin nibh varius at. Praesent eu lacinia odio. Cras est nisl, venenatis non ornare ut, semper ac sem. In hac habitasse platea dictumst. Vivamus mi risus, cursus nec volutpat vitae, convallis non justo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed ac nunc vitae lectus tristique luctus."
    showinfo="true" />
  <img src="http://rune.gronkjaer.dk/blog/wp-content/BlogPages/javascript_rgLightview/thumbs/hvid-og-gul-blomst.jpg"
    imagehref="http://rune.gronkjaer.dk/blog/wp-content/BlogPages/javascript_rgLightview/hvid-og-gul-blomst.jpg"
    href="http://rune.gronkjaer.dk/blog/wp-content/BlogPages/javascript_rgLightview/download/hvid-og-gul-blomst.jpg"
    type="image" header="En blomst" description="Curabitur quis malesuada ante. Lorem ipsum dolor sit amet."
    showinfo="true" />
  <img src="http://rune.gronkjaer.dk/blog/wp-content/BlogPages/javascript_rgLightview/thumbs/lilla-aakande.jpg"
    imagehref="http://rune.gronkjaer.dk/blog/wp-content/BlogPages/javascript_rgLightview/lilla-aakande.jpg"
    href="http://rune.gronkjaer.dk/blog/wp-content/BlogPages/javascript_rgLightview/download/lilla-aakande.jpg"
    type="image" header="Lilla åkande" description="Etiam fermentum ornare nisi, ut hendrerit est viverra et. In aliquam eros et odio commodo iaculis. Cras pretium varius velit non laoreet. Cras id diam quis felis rhoncus malesuada id id arcu."
    showinfo="true" />
</div>

<script type="text/javascript" src="http://jscripts.s3.co3.dk/Co3Gallery/jQuery.Co3.Gallery.min.js"></script>

<style type="text/css">
  #Co3Gallery_ImageInformation h5 { font-weight: bold; font-size: 12px; }
  .imageGallery img, #ClickToOpen { cursor: pointer; }
</style>

<script type="text/javascript">
  jQuery(document).ready(function() {
    /*--- Standard galleriet ---*/
    var settings = {
      blockBgColor: "black",
      showImageList: false,
      imageInformationHeight: 95,
      imageInformationTemplate: '<h5>[header]</h5>[description]<br />Størrelse: [width] x [height] og [imagesize] KB<br />Billede [imagenumber] af [numberofimages]<br /><a href="[href]">Download billedet</a>'
    };
    jQuery("#ImageGalleryFullMonty img").CreateGallery(settings);
  });
</script>

]]></content:encoded>
			<wfw:commentRss>http://rune.gronkjaer.dk/blog/2010/04/21/jqlightview-2-0-lige-pa-trapperne/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Javascript Date extension</title>
		<link>http://rune.gronkjaer.dk/blog/2010/04/07/javascript-date-extension/</link>
		<comments>http://rune.gronkjaer.dk/blog/2010/04/07/javascript-date-extension/#comments</comments>
		<pubDate>Wed, 07 Apr 2010 15:36:51 +0000</pubDate>
		<dc:creator>Rune Grønkjær</dc:creator>
				<category><![CDATA[Date]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[regexp]]></category>
		<category><![CDATA[format]]></category>
		<category><![CDATA[getDayName]]></category>
		<category><![CDATA[getMonthName]]></category>
		<category><![CDATA[getWeekNumber]]></category>
		<category><![CDATA[prototype]]></category>
		<category><![CDATA[prototyping]]></category>
		<category><![CDATA[regex]]></category>

		<guid isPermaLink="false">http://rune.gronkjaer.dk/blog/?p=5</guid>
		<description><![CDATA[Javascript Date objektet er nok et af de sværeste at arbejde med, da det for de
uindviede virker/er meget indviklet. Jeg har ofte haft brug for at kunne abstrahere
fra fra denne kompleksitet, med nogle mere enkle metoder. Jeg har derfor skrevet
nogle metoder til Date objektet, der kan give nogle pæne oplysninger om den valgte
dato.]]></description>
			<content:encoded><![CDATA[Javascript Date objektet er nok et af de sværeste at arbejde med, da det for de
uindviede virker/er meget indviklet. Jeg har ofte haft brug for at kunne abstrahere
fra fra denne kompleksitet, med nogle mere enkle metoder. Jeg har derfor skrevet
nogle metoder til Date objektet, der kan give nogle pæne oplysninger om den valgte
dato. For en fuld reference over alle dateobjektets metoder følg dette link til
<a href="http://www.w3schools.com/jsref/jsref_obj_date.asp">w3schools</a>.
<h3>
  .getWeekNumber()</h3>
Ugenummer er ikke noget der benyttes i ret mange andre lande end Danmark. Derfor
understøtter de færreste programmeringssprog ugenumre som standard. GetWeekNumber
metoden sørger for at udregne datoens ugenummer.
<pre class="brush: js">
Date.prototype.getWeekNumber = function() {
  var date = this;
  date = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
  var IsoDayOfWeek = date.getDay() == 0 ? 7 : date.getDay(); // Søndag = 7
  date.setDate(date.getDate() + 4 - IsoDayOfWeek); // Ændre til nærmeste torsdag
  var DayOfYear = (date.getTime() - Date.UTC(date.getFullYear(), 0, 1)) / 864e5;
  var week = Math.floor(DayOfYear / 7) + 1;
  return week;
};

//getWeekNumber ekesmpel
var date = new Date();
jQuery("#UgeTest").html("Denne uges nummer: " + date.getWeekNumber());
</pre>
<h4>Resultatet:</h4>
<div class="result" id="UgeTest">
</div>
<h3>
  .getDayName()</h3>
Ugedagens navn har man ofte brug for, når man arbejder med datoer i det hele taget.
Min getDayName metode returner netop dette og understøtter også forskellige
<pre class="brush: js">
Date.prototype.getDayName = function(language) {
  var days = [], supportetLanguages = ["da-DK", "en-US"];
  //Dansk som standard
  //Denne linie benytter en containsmetode på Arrayobjektet, som ikke er med i native koden.
  language = language &#038;&#038; supportetLanguages.contains(language) ? language : "da-DK";
  
  //dansk
  days["da-DK"] = [];
  days["da-DK"][0] = "Søndag";
  days["da-DK"][1] = "Mandag";
  days["da-DK"][2] = "Tirsdag";
  days["da-DK"][3] = "Onsdag";
  days["da-DK"][4] = "Torsdag";
  days["da-DK"][5] = "Fredag";
  days["da-DK"][6] = "Lørdag";
  //Engelsk
  days["en-US"] = [];
  days["en-US"][0] = "Sunday";
  days["en-US"][1] = "Monday";
  days["en-US"][2] = "Tuesday";
  days["en-US"][3] = "Wedensday";
  days["en-US"][4] = "Thursday";
  days["en-US"][5] = "Friday";
  days["en-US"][6] = "Saturday";

  return days[language][this.getDay()];
};

//getDayName ekesmpel
var date = new Date();
jQuery("#UgedagTest").html(date.getDayName());
</pre>
<h4>Resultatet:</h4>
<div class="result" id="UgedagTest">
</div>
<h3>
  .getMonthName()</h3>
Ligesom ugedagens navn kan det være super praktisk at kunne få månedens navn også.
<pre class="brush: js">
Date.prototype.getMonthName = function(language) {
  var months = [], supportetLanguages = ["da-DK", "en-US"];

  //Dansk som standard
  //Denne linie benytter en containsmetode på Arrayobjektet, som ikke er med i native koden.
  language = language &#038;&#038; supportetLanguages.contains(language) ? language : "da-DK";

  //Dansk
  months["da-DK"] = [];
  months["da-DK"][0] = "Januar";
  months["da-DK"][1] = "Februar";
  months["da-DK"][2] = "Marts";
  months["da-DK"][3] = "April";
  months["da-DK"][4] = "Maj";
  months["da-DK"][5] = "Juni";
  months["da-DK"][6] = "Juli";
  months["da-DK"][7] = "August";
  months["da-DK"][8] = "September";
  months["da-DK"][9] = "Oktober";
  months["da-DK"][10] = "November";
  months["da-DK"][11] = "December";
  //Engelsk
  months["en-US"] = [];
  months["en-US"][0] = "January";
  months["en-US"][1] = "February";
  months["en-US"][2] = "March";
  months["en-US"][3] = "April";
  months["en-US"][4] = "May";
  months["en-US"][5] = "June";
  months["en-US"][6] = "Juli";
  months["en-US"][7] = "August";
  months["en-US"][8] = "September";
  months["en-US"][9] = "Oktober";
  months["en-US"][10] = "November";
  months["en-US"][11] = "December";
  return months[language][this.getMonth()];
};

//getMonthName ekesmpel
var date = new Date();
jQuery("#MaanedNavnTest").html(date.getMonthName());</pre>
<h4>Resultatet:</h4>
<div class="result" id="MaanedNavnTest">
</div>
<h3>
  .format()</h3>
En ægte format metode har javascript Date objektet ikke. Jeg har derfor længe ledt efter en extension, der kan formatere en dato i alle mulige formater. Jeg fandt hvad jeg ledte efter på <a href="http://blog.stevenlevithan.com/archives/date-time-format">Steven Levithans blog</a>, hvor man også kan downloade koden.<br />
Steven Levithans udvidelse til Date objektet er ret vildt. Man kan bruge alle de gængse dato formateringskoder. Se bare på eksemplerne herunder.
<pre class="brush: js">
var now = new Date();
var testTxt = "";
testTxt += '&lt;br /&gt;&lt;br /&gt;now.format("m/dd/yy"):&lt;br /&gt;' + now.format("m/dd/yy");

//Kan også benyttes som en selvstændig metode
testTxt += '&lt;br /&gt;&lt;br /&gt;dateFormat(now, "dddd, mmmm dS, yyyy, h:MM:ss TT")&lt;br /&gt;' + dateFormat(now, "dddd, mmmm dS, yyyy, h:MM:ss TT");

// Du kan benytte een af flere navngivne masker
testTxt += '&lt;br /&gt;&lt;br /&gt;now.format("isoDateTime")&lt;br /&gt;' + now.format("isoDateTime");

// ...Eller tilføje dine egne
dateFormat.masks.hammerTime = 'HH:MM! "Can\'t touch this!"';
testTxt += '&lt;br /&gt;&lt;br /&gt;now.format("hammerTime")&lt;br /&gt;' + now.format("hammerTime");

// Når man benytter den selvstændige dateFormat metode
// kan du også sende en dato med som string, smart
testTxt += '&lt;br /&gt;&lt;br /&gt;dateFormat("Jun 9 2007", "fullDate")&lt;br /&gt;' + dateFormat("Jun 9 2007", "fullDate");

// Bemærk at hvis du ikke inkludere masken, som parameter,
// vil dateFormat.masks.default blive benyttet
testTxt += '&lt;br /&gt;&lt;br /&gt;now.format()&lt;br /&gt;' + now.format();

// Og hvis du ikke inkluderer en dato som parameter,
// bliver dags dato og tid brugt
testTxt += '&lt;br /&gt;&lt;br /&gt;dateFormat()&lt;br /&gt;' + dateFormat();

// Du kan også springe over dato objektet (så længe din maske ikke
// indeholder tal), hvor dags dato og tid igen vil blive benyttet
testTxt += '&lt;br /&gt;&lt;br /&gt;dateFormat("longTime")&lt;br /&gt;' + dateFormat("longTime");

// Du kan også konvertere en lokal tid til UTC tid. For at gøre dette
// kan du sende true med som parameter (her er det ikke lovligt at springe parametre over):
dateFormat(now, "longTime", true);
testTxt += '&lt;br /&gt;&lt;br /&gt;now.format("longTime", true)&lt;br /&gt;' + now.format("longTime", true);

// ...Eller du kan prefixe UTC: til din maske
testTxt += '&lt;br /&gt;&lt;br /&gt;now.format("UTC:h:MM:ss TT Z")&lt;br /&gt;' + now.format("UTC:h:MM:ss TT Z");
jQuery("#StevenLevithan").html(testTxt);
</pre>
<h4>Resultatet:</h4>
<div class="result" id="StevenLevithan">
</div>

<script src="http://rune.gronkjaer.dk/blog/wp-content/BlogPosts/javascript_Extending_Date.js" type="text/javascript"></script>
]]></content:encoded>
			<wfw:commentRss>http://rune.gronkjaer.dk/blog/2010/04/07/javascript-date-extension/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Javascript String extension</title>
		<link>http://rune.gronkjaer.dk/blog/2010/03/28/javascript-string-extension/</link>
		<comments>http://rune.gronkjaer.dk/blog/2010/03/28/javascript-string-extension/#comments</comments>
		<pubDate>Sun, 28 Mar 2010 18:57:14 +0000</pubDate>
		<dc:creator>Rune Grønkjær</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[String]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[regexp]]></category>
		<category><![CDATA[contains]]></category>
		<category><![CDATA[endsWith]]></category>
		<category><![CDATA[format]]></category>
		<category><![CDATA[htmlEntities]]></category>
		<category><![CDATA[prototype]]></category>
		<category><![CDATA[regex]]></category>
		<category><![CDATA[remove]]></category>
		<category><![CDATA[reverse]]></category>
		<category><![CDATA[startsWith]]></category>
		<category><![CDATA[stripTags]]></category>
		<category><![CDATA[toArray]]></category>
		<category><![CDATA[toIntArray]]></category>
		<category><![CDATA[trim]]></category>

		<guid isPermaLink="false">http://rune.gronkjaer.dk/blog/?p=6</guid>
		<description><![CDATA[Denne gang vil jeg skrive om extension af strings. I rigtige programmeringssprog har man normalt en helt masse metoder, man kan kalde på sine strings. I javascript må man selv lave meget af arbejdet. Jeg har over tiden samlet og skrevet en del udvidelser til string objektet, som kan gøre livet nemmere. For en fuld [...]]]></description>
			<content:encoded><![CDATA[Denne gang vil jeg skrive om extension af strings. I rigtige programmeringssprog har man normalt en helt masse metoder, man kan kalde på sine strings. I javascript må man selv lave meget af arbejdet. Jeg har over tiden samlet og skrevet en del udvidelser til string objektet, som kan gøre livet nemmere. For en fuld reference over alle stringobjektets metoder følg dette link til <a href="http://www.w3schools.com/jsref/jsref_obj_string.asp">w3schools</a>.<br /><br />
Alle resultater er udregnet med den rigtige metode og ikke bare hardcoded ind.
<h3>
.trim(), .trimEnd(), trimStart()</h3>
Trim metoder benyttes til at fjerne uønskede mellemrum fra starten og/eller slutningen af sin string

<pre class="brush: js">
//trim fjerner mellemrum både før og efter string'en
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g,""); };
//trimEnd fjerner mellemrum i enden af string'en
String.prototype.trimEnd = function() { return this.replace(/\s+$/, ''); };
//trimStart fjerner mellemrum i starten af string'en
String.prototype.trimStart = function() { return this.replace(/^\s+/, ''); };

//trim eksempel
var trimString = "  Denne string har nogle dumme mellemrum i enderne   ",
    trimTest = jQuery("#TrimTest");
trimTest.html("'" + trimString + "'");
trimTest.html(trimTest.html() + "&lt;br /&gt;'" + trimString.trim() + "'");
trimTest.html(trimTest.html() + "&lt;br /&gt;'" + trimString.trimEnd() + "'");
trimTest.html(trimTest.html() + "&lt;br /&gt;'" + trimString.trimStart() + "'");

</pre>
Resultatet bliver sådan:
<div class="result" id="TrimTest">
</div>

<h3>
.format()</h3>
Med format metoden kan man skifte tokens i teksten ud med argumenter fra metodens parametre.<br />
Rigtige format metoder kan meget mere end det, og måske får jeg lavet understøttelse for noget mere når jeg får behov for det.
<pre class="brush: js">
//En ekstra format funktion til String objektet
//Kan bruges med parametre
String.format = function(text) {
  //Tjek om der er mere end 1 argumenter med som parametre
  if (arguments.length <= 1) {
    //Hvis der kun er een parameter med kan vi bare returnere, da der ikke er noget at formatere
    return text;
  }
  //Vi gør klar til at køre argumenterne igennem
  var tokenCount = arguments.length - 2;
  for (var token = 0; token <= tokenCount; token++) {
    //Der itereres igennem tekstens tokens og erstatter deres plads med argumenterne
    text = text.replace(new RegExp("\\{" + token + "\\}", "gi"), arguments[token + 1]);
  }
  return text;
};

//format eksempel
var formatString = "Hej {0}, har du en god dag? Hilsen {1}";
jQuery("#FormatTest").html("'Inden format: '" + formatString + "'&lt;br /&gt;Efter format: '" + String.format(formatString, "Besøgende", "Rune") + "'");
</pre>
Resultatet bliver sådan:
<div class="result" id="FormatTest">
</div>

<h3>
.reverse()</h3>
Reverse metoden spejlvender string'en, som der jo også står i kommentaren. Brugværdien i den er nok lille... men bare fordi man kan.
<pre class="brush: js">
//Spejlvender string'en.
String.prototype.reverse = function() { 
  return this.split('').reverse().join('');
};

//reverse eksempel
var reverseString = "evian mmh";
jQuery("#ReverseTest").html("Inden reverse: " + reverseString + "&lt;br /&gt;Efter reverse: " + reverseString.reverse());

</pre>
Resultatet bliver sådan:
<div class="result" id="ReverseTest">
</div>

<h3>
.contains()</h3>
I stedet for at skulle bruge den indbyggede indexOf() metode, og få returneret et tal, kan man i stedet bruge contains, som returnere en bool.<br />
Contains metoden her er ydermere case insensitive, hvilket er meget rart. Kan, som dens søskende i tungere programmeringssprog udbygges med flere parametre, såsom case insensitive mm.
<pre class="brush: js">
//Returnerer true hvis teksten findes i string'en
String.prototype.contains = function(text, isCaseSensitive) {
  return !!(new RegExp(text, !isCaseSensitive ? "i" : "" + "g").test(this));
};

//contains eksempel
var containsString = "Den hurtige brune Rune hopper over den dovne hund";
jQuery("#ContainsTest").html(containsString.contains("Brune") + "&lt;br /&gt;" + containsString.contains("Brune", true));
</pre>
Resultatet bliver sådan:
<div class="result" id="ContainsTest">
</div>

<h3>
.endsWidth()</h3>
Endswith gør i bund og grund det samme, som contains. Den kigger dog kun i slutningen at string'en.
<pre class="brush: js">
//Returnerer true hvis teksten findes i slutningen af string'en
String.prototype.endsWidth = function(text, isCaseSensitive) {
  return !!(new RegExp(text + "$", !isCaseSensitive ? "i" : "" + "g").test(this));
};

//endsWidth eksempel
var endsWidthString = "Den hurtige brune Rune hopper over den dovne hund";
jQuery("#EndsWidthTest").html(endsWidthString.endsWidth("Hund") + "&lt;br /&gt;" + endsWidthString.endsWidth("Hund", true));
</pre>
Resultatet bliver sådan:
<div class="result" id="EndsWidthTest">
</div>

<h3>
.startsWidth()</h3>
Startswith gør i bund og grund det samme, som contains. Den kigger dog kun i starten at string'en.
<pre class="brush: js">
//Returnerer true hvis teksten findes i starten af string'en
String.prototype.startsWidth = function(text, isCaseSensitive) {
  return !!(new RegExp("^" + text, !isCaseSensitive ? "i" : "" + "g").test(this));
};

//startsWidth eksempel
var startsWidthString = "Den hurtige brune Rune hopper over den dovne hund"
jQuery("#StartsWidthTest").html(startsWidthString.startsWidth("den") + "&lt;br /&gt;" + startsWidthString.startsWidth("den", true));
</pre>
Resultatet bliver sådan:
<div class="result" id="StartsWidthTest">
</div>

<h3>
.toArray()</h3>
En meget lille og simpel metode der gør det lidt nemmere at lave en string til et array af strings
<pre class="brush: js">
//Returnerer string'en, som array
String.prototype.toArray = function() {
  return this.split('');
}

//toArray eksempel
var toArrayString = "Den hurtige brune Rune hopper over den dovne hund";
jQuery("#ToArrayTest").html(toArrayString + "&lt;br /&gt;" + toArrayString.toArray());
</pre>
Resultatet bliver sådan:
<div class="result" id="ToArrayTest">
</div>

<h3>
.toIntArray()</h3>
ToIntArray metoden laver et array med hver enkelt chars unicode nummer. I eksemplet laver jeg et lille regnestykke for at vise at det bliver til tal.
<pre class="brush: js">
//returnerer string'en, som et array med hver chars unicode integer
String.prototype.toIntArray = function() {
  var returnArray = [];
  for (var i = 0; i < this.length; i++) {
    returnArray.push(this.charCodeAt(i));
  }
  return returnArray;
};

//toIntArray eksempel
var toIntArrayString = "Den hurtige brune Rune hopper over den dovne hund",
    intArray = toIntArrayString.toIntArray();
jQuery("#ToIntArrayTest").html(toIntArrayString + "&lt;br /&gt;" + intArray + "&lt;br /&gt;intArray[2] * intArray[7] = " + (intArray[2] * intArray[7]));
</pre>
Resultatet bliver sådan:
<div class="result" id="ToIntArrayTest">
</div>

<h3>
.remove()</h3>
Remove fungerer ved at fjerne en del af string'en. Den fjerner fra startindexet og length karakterer frem.
<pre class="brush: js">
//Fjerner en stump af string'en fra start og length frem
String.prototype.remove = function(start, length) {
  var s = '';
  if (start > 0)
    s = this.substring(0, start);

  if (start + length < this.length)
    s += this.substring(start + length, this.length);
  return s;
};

//remove eksempel
var removeString = "Den hurtige brune Rune hopper over den dovne hund";
jQuery("#RemoveTest").html(removeString + "&lt;br /&gt;" + removeString.remove(11, 6));
</pre>
Resultatet bliver sådan:
<div class="result" id="RemoveTest">
</div>

<h3>
.htmlEntities()</h3>
Denne metode HTMLEncoder tekstens HTML. Det vil sige at HTML'en ikke vil kunne tolkes, som HTML af browseren.
<pre class="brush: js">
//Htmlencoder teksten
String.prototype.htmlEntities = function() {
  return this.replace(/&#038;/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
};

//htmlEntitiesString eksempel
var htmlEntitiesString = "&lt;div&gt;Den hurtige brune &lt;strong&gt;Rune&lt;/strong&gt; hopper over den dovne hund&lt;/div&gt;";
jQuery("#HtmlEntitiesTest").html(htmlEntitiesString + "&lt;br /&gt;" + htmlEntitiesString.htmlEntities());
</pre>
Resultatet bliver sådan:
<div class="result" id="HtmlEntitiesTest">
</div>

<h3>
.stripTags()</h3>
Denne metode fjerner alle HTML tags i teksten. I eksemplet benytter jeg htmlEntities metoden til at vise at der ikke er fjernet nogen HTML-tags.
<pre class="brush: js">
//returnerer en string uden HTML tags
String.prototype.stripTags = function() {
  return this.replace(/<\/?[^>]+>/gi, '');
};

//stripTags eksempel
var stripTagsString = "&lt;div&gt;Den hurtige brune &lt;strong&gt;Rune&lt;/strong&gt; hopper over den dovne hund&lt;/div&gt;";
jQuery("#StripTagsTest").html(stripTagsString.htmlEntities() + "&lt;br /&gt;" + stripTagsString.stripTags().htmlEntities());
</pre>
Resultatet bliver sådan:
<div class="result" id="StripTagsTest">
</div>

<script src="http://rune.gronkjaer.dk/blog/wp-content/BlogPosts/javascript_Extending_String.js" type="text/javascript"></script>
]]></content:encoded>
			<wfw:commentRss>http://rune.gronkjaer.dk/blog/2010/03/28/javascript-string-extension/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Mit eget wordpress tema</title>
		<link>http://rune.gronkjaer.dk/blog/2010/03/21/mit-eget-wordpress-tema/</link>
		<comments>http://rune.gronkjaer.dk/blog/2010/03/21/mit-eget-wordpress-tema/#comments</comments>
		<pubDate>Sun, 21 Mar 2010 21:21:58 +0000</pubDate>
		<dc:creator>Rune Grønkjær</dc:creator>
				<category><![CDATA[css]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[tema]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[linkedin]]></category>

		<guid isPermaLink="false">http://rune.gronkjaer.dk/blog/?p=31</guid>
		<description><![CDATA[Indtil nu har jeg benyttet mig af et ganske udmærket tema, lavet af l2aelba. Temaet er dog af ældre dato og både html, css og php funktionerne er langt fra optimale. Som webudvikler kan jeg selvfølgelig ikke leve med at html og css på min egen blog ikke er helt perfekte. Som om nogen kan opnå det helt perfekte, men man går selvfølgelig efter det hver gang.]]></description>
			<content:encoded><![CDATA[Indtil nu har jeg benyttet mig af et ganske udmærket tema, lavet af l2aelba. Temaet er dog af ældre dato og både html, css og php funktionerne er langt fra optimale. Som webudvikler kan jeg selvfølgelig ikke leve med at html og css på min egen blog ikke er helt perfekte. Som om nogen kan opnå det helt perfekte, men man går selvfølgelig efter det hver gang.

Et andet problem jeg har haft er vedligeholdelse. Et er at mit nuværende tema er af lidt ældre dato og html og css er kompliseret opbygget. Noget andet er selvfølgelig at jeg ikke selv har lavet det, og endnu er lidt fremmed for wordpress og php. For at kunne rette og forbedre må jeg også vide hvad jeg laver.
<h3>Hvordan?</h3>
Jeg har tænkt mig at benytte en tutorial, for at være sikker på at kunne komme ud i alle hjørnerne af et tema. Efter at have googlet emnet, fandt jeg denne tutorial hos <a title="Themeshaper - Shaping WordPress Themes" href="http://themeshaper.com/wordpress-themes-templates-tutorial/#wrapper" target="_blank">themeshaper</a>. Den ser ret avanceret ud og vil sandsynligvis vise mig alle de ting jeg har brug for at vide.
<h3>Tanker og fakta om min valgte tutorial</h3>
Tutorialen tager mig helt fra bunden af og hjælper mig med en god grundhtml. Den er bygget op i et antal steps, hvor de løbende bliver mere avancerede. Der er nogle supergode forklaringer undervejs der forklarer de forskellige valg man tager. Korte og præcise forklaringer. Dejligt.

En anden ting denne tutorial er meget fokuseret på er SEO. Den sørger for at de vigtigste ting på bloggen, såsom en posttitle også vil blive dominerinde rent SEO mæssigt. Detaljer som hjælp til folk med screenreaders bliver også taget seriøst.
<h3>Det lykkedes</h3>
Efter at have gået igennem tutorialen er jeg nu færdig med mit eget tema og resultatet kan ses her. Rent visuelt er der meget lidt der har ændret sig. Men jeg er nu langt mere tilfreds med min HTML og css her på sitet. Siden er også topoptimeret til at jeg kan ændre i det fremover og med nogle få ændringer i css&#8217;en kan jeg vælte fuldstændig rundt på designet, hvilket er rart at vide.

Ved at optimere css&#8217;en er jeg gået fra lige under 22244 karakterer css kode til 6654. Her har jeg klippet alle kommentarer ud af koden både i før og efterkoden. Hvad HTML&#8217;en angår har jeg fjernet mange overflødige tags og lavet en mere simpel og logisk struktur.
<h3>Konklusion</h3>
Det er relativt let at lave sit eget tema. Men det vil ikke blive noget jeg kommer til at gøre fra bunden ret mange gange. Nu har jeg en god standardopsætning på mit eget site, som jeg kan genbruge på mange andre sites, skulle jeg få brug for det.]]></content:encoded>
			<wfw:commentRss>http://rune.gronkjaer.dk/blog/2010/03/21/mit-eget-wordpress-tema/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
