HAVIT Knowledge Base

Vývoj webových aplikací, .NET, SQL, návrh
Welcome to HAVIT Knowledge Base Sign in | Join | Help
-
Home Články Forums Obrázky Soubory

(D)HTML

Dynamic HTML, XHTML, CSS, client scripts

  • JavaScript: Metoda parseInt vrací nečekané výsledky

    Metoda parseInt vrací celočíselnou hodnotu získanou z řetězce. Metoda toho umí ve skutečnosti více, než je od ní očekáváno - pokud řetězec začíná "0x", považuje se řetězec za zápis čísla v šestnáckové soustavě, pokud začíná nulou, pak za zápis čísla v osmičkové soustavě. Druhým (nepovinným) parametrem můžeme metodě říct, v jaké číselné soustavě je hodnota uvedena. Pokud metoda při zpracování řetězce narazí na nepodporovaný symbol (znak), končí zpracování (což je v dokumentaci popsáno uvedeno jen v příkladu).
    parseInt('abc')       // vrací NaN
    parseInt('8abc')      // vrací 8 - zpracování skončí u nepodporovaného symbolu "a"
    parseInt('0100')      // vrací 64 - nula na začátku říká, že jde o osmičkovou soustavu, v osmičkové soustavě je "100" reprezentací hodnoty 64
    parseInt('08')        // vrací 0 - nula na začátku říká, že jde o osmičkovou soustavu, ta ale nepoužívá symbol 8, na kterém proto skončí zpracování
    parseInt('08', 10)    // vrací 8 - uvedli jsme, že hodnota reprezentuje číslo v desítkové soustavě nepodporovanou mezerou
    parseInt('1 000', 10) // vrací 1 - zpracování skončí

    Pozor proto na zpracování hodnot od uživatele. Pokud není jasné, jak uživatel hodnotu zadá (a to podle mě není jasné nikdy), je potřeba předat metodě parseInt i druhý parameter, jinak se dočkáte stejného překvapení jako já při zpracování času zadaného uživatelem: Vstup "07" vrátí 7, vstup "08" vrátí 0.
    Pozor i na situaci, kdy uživatel zadá formátované číslo - například s oddělovačem tisíců. A takový javascript nemusíme ani psát ručně, stačí použít některý z validátorů (ASP.NET), který používá parseInt.
  • IE: Při použití auto-complete se nevyvolá událost onChange

    Internet Explorer při použití auto-complete nevyvolá na daném prvku (inputu) událost onChange, bug (i když někteří by možná řekli by-design).

    Mimo obskurnějších řešení se dá auto-complete na daném prvku prostě vypnout:

    <input ... autocomplete="off" />
    <asp:TextBox ... autocomplete="off" />
    Případně ho vypnout na celém formuláři:

    <form ... autocomplete="off">...nefunguje bohužel možnost na celém formuláři vypnout a uvnitř na některých prvcích zapnout.

  • Šířka tlačítek v IE (input type="button")

    V Internet Exploreru je docela alchymie vyrobit tlačítko, které je široké stejně jako text na něm.

    <input type="button" value="Text tlačítka" class="button"/>
    <asp:Button ID="MyButton" Text="Text tlačítka" class="button"/>
    Co jinde funguje, v IE selhává:

    .button {
        margin:0;
        padding:0;
    }
    Co však kupodivu pomůže, je nastavení:

    .button{
        padding:0;
        width:auto;
        overflow:visible;
    }

    ...někdy je lepší nebádat, proč tomu tak je.
  • Mozilla FireFox: Nefunguje XHTML-validní image-map

    Následující XHTML-validní image-map v Mozille nechodí:

    <img id="reklama" src=".." width="200" height="600" alt="..." usemap="#mapa" />
    <map id="mapa">
        <area shape="rect" coords="10,110,186,245" alt="..." href="..." target="_blank" >
    </map>
    Mozille nestačí <map id="..."> nýbrž vyžaduje <map name="...">... :-(((

    Demo: http://www.bernzilla.com/bugs/imagemap1.html

  • IE: Workaround na "Click to activate and use the control" (FLASH, atp.)

    Microsoft bohužel prohrál jednu patentovou právní bitvu ohledně zobrazování objektů deklarovaných elementy OBJECT a EMBED, a tak musel upravit Internet Explorer tak, že nespouští tyto objekty automaticky, nýbrž vyžaduje pro jejich spuštění kliknutí tlačíkem myši - "Click to activate and use the control". Do Internet Exploreru 6 se Vám toto "vylepšení" dostane jednou z aktualizací přes Windows Update, Internet Explorer 7 ho má od počátku.

    Naštěstí se celý problém týká pouze OBJECT a EMBED elementů, které jsou umístěny přímo v HTML kódu, resp. v hlavním HTML souboru stránky (včetně skriptů). OBJECT a EMBED objekty, které jsou zavedeny skriptem umístěným v samostatném souboru, fungují normálně bez klikání. Snadno si to můžete ověřit, pokud si vytvoříte samostatný .js soubor s obsahem

    document.getElementById('myFlash').innerHTML = '<object ...';

    a do stránky ho pak umístíte odkazem

    </div id="myFlash">
    <script type="text/jscript" src="test.js"></script>

    Pokud byste skript document.write() umístili přímo do stránky, nikoliv do samostatného .js souboru, pak by zůstal požadavek "Click to activate..."

    Jednoduchý workaround

    Na netu je k nalezení spousta připravených skriptů, které umožňují umisťovat FLASH objekty do stránek právě způsoby obdobnými, jako je výše uvedený. Existuje však jednoduchý fígl, který můžete aplikovat i na již existující stránky bez větších změn.

    Stačí vytvořit samostatný ie-flash-activate.js soubor s obsahem:

    objects = document.getElementsByTagName("object");
    for (var i = 0; i < objects.length; i++)
    {
        objects[i].outerHTML = objects[i].outerHTML;
    }
    a do stránky za poslední element <object> umístíte odkaz na něj:

    <script type="text/jscript" src="ie-flash-activate.js"></script>...a je to.

    Výše uvedený jednoduchý skript v podstatě přesvědčí IE, že jsou elementy <OBJECT> vkládány externím skriptem a ten u nich nebude vyžadovat "Click to activate...". Podstatné je, že výše uvedený skriptík musí být v jiném souboru, mimo stránku!

    Funguje to i v IE7.

  • IE7: Vlastní vyhledávání - Search Provider - OpenSearch

    O možnosti přidání vlastního vyhledávání do Internet Exploreru 7 psal už dávno Michal Altair Valášek v článku "Jak přidat vyhledávání na stránkách do IE 7.0", nebudu ho tu tedy opakovat a úvodní informace najde každý tam.

    Doplňuji pouze, že existuje také možnost vytvoření linku, který daný search provider "nainstaluje", resp. existuje JScript funkce AddSearchProvider, která IE řekne, že má nějaký search provider nainstalovat:

    <a href="#" onclick="window.external.AddSearchProvider('/mySearch.xml')">My Search</a>

    Další související články a odkazy:

  • mailto: Příprava mailů pro poštovního klienta včetně cc, bcc, subject a body

    I při vývoji webových aplikací se občas setkáme s výstředním požadavkem, kdy je potřeba, aby aplikace "generovala maily pro Outlook" (či jakéhokoliv poštovního klienta). Obchodníci prostě aplikacím nevěří, chtějí si mail před odesláním upravit, připojit vlastní podpis a mít ho ve vlastní Odeslané poště.

    Obvykle chtějí "kliknu tady na to tlačítko a objeví se mi nový předvyplněný mail v Outlooku"... :-))
    (Nebudu tu teď hodnotit, do jaké míry je to vhodné, spolehlivé, ...)

    Jednou z možných cest, jak výsledku dosáhnout, je použít HTML element

    <a href=mailto:jmeno@prijmeni.cz>Tlačítko</a>

    ...asi nikoho nepřekvapuje, že takovýto odkaz vytvoří na klientu nový mail pro odeslání na zadanou adresu.

    Ne každý však ví, že takovýto odkaz lze odekorovat tak, že mimo adresy příjemce předáme poštovnímu klientovi i Cc, Bcc, Subject, Body, či dokonce libovolnou hodnotu do hlavičky mailu. Není to kupodivu nic proprietarního, nýbrž to vyplývá z RFC 2368. Jednotlivé hlavičky najdete v RFC 822.

    Můžeme tak například vytvořit bohatší odkaz:

    <a href="mailto:infobot@example.com?subject=current-issue&body=current-issue&cc=jmeno@prijmeni.cz">Tlačítko</a>

    Ještě jeden drobný zádrhel - jak nakódovat mezery, konce řádek, či dokonce češtinu. V zásadě bychom měli encodovat URL podle RFC 1738, nicméně v praxi to tak jednoduché není, protože např. v ASP.NET si se samotnými HttpUtility.UrlEncode(), ani HttpUtility.UrlPathEncode() nevystačíme:

    • mezerníky musíme převést na %20, nikoliv na + (to sice dělá UrlPathEncode(), ale ten zase neřeší konce řádek) ,
    • konce řádek musíme převést na %0D%0A, z praxe stačí i %0A (UrlEncode() prozměnu kóduje mezery na +),
    • ...atp. i další speciální znaky.

    Takže nakonec to může odkaz vypadat nějak takto:

    <a href="mailto:?Subject=Nab%eddka%20%e8.%20&Body=Pos%edl%e1m%20nab%eddku%0a%0aCENA%20%3d%201%a0114%20(111%2c40%2fks)">Tlačítko</a>

    přičemž v ASP.NET lze odkaz emitovat třeba takto:

    TlacitkoHL.NavigateUrl = String.Format(
    "mailto:{0}?Body={1}",
    email,
    HttpUtility.UrlEncode("tělo\nzprávy", Encoding.GetEncoding(1250)).Replace("+", "%20")
    );
    Ještě zajímavý postřeh - přestože samotná HTML stránka je třeba v kódování utf-8, je potřeba mailto URL odkaz encodovat do win-1250. Zřejmě je to o tom, že browser předá URL v nezměněné podobě poštovnímu klientovi (např. Outlooku) a informace o encodingu tam nikde mezi nimi neproběhne. Moc pěkné to není. Pokud byste k tomu někdo měl přesnější informace, uvítám je v komentáři. Mě to takhle funguje všude, kde to potřebuji, takže nemám teď motivaci ani čas nad tím dál bádat... ;-)
  • onBeforeUnload - Potvrzovací dialog před odchodem ze stránky

    V browseru, na stránkách, kde dochází k editaci záznamů, či jiné aktivitě, kterou je potřeba zakončit uložením či volbou nějakého tlačítka, se nám může hodit využít události onBeforeUnload k zobrazení potvrzovacího dialogu s dotazem, zde si uživatel opravdu přeje stránku opustit.

    <html>
    <head>
       <script type="text/jscript">
          // inicializace  
          g_blnCheckUnload = true;     
          function RunOnBeforeUnload()
          {
             if (g_blnCheckUnload)
             {
                window.event.returnValue = 'Text, který bude přidán do confirmačního dialogu';
             }
          }
          function bypassCheck()
          { 
             g_blnCheckUnload  = false; 
          }
       </script>
    </head>
    <body onBeforeUnload="RunOnBeforeUnload();">
       <a href="http://www.havit.cz">dotaz zobrazen</a>
       <a href="http://www.havit.eu" onClick="bypassCheck">dotaz nezobrazen</a>
    </body>
    </html>

    Událost onBeforeUnload se volá nejenom na odkazech a tlačítkách, ale i při zavírání okna prohlížeče a prakticky veškerých událostech, kde by mělo dojít k opuštění stránky.

    Funguje to minimálně v Internet Exploreru a FireFoxu.

    Modifikace s hlídáním změn

    Nakonec se mi podařilo rozchodit i rozumnou podobu výše uvedeného, kdy je potvrzovací dotaz zobrazen jen při změně formulářových dat (a je tedy potřeba změny uložit):

    <html>
    <head>
       <script type="text/jscript">
          // inicializace  
          g_blnCheckUnload = false;     
          function RunOnBeforeUnload()
          {
             if (g_blnCheckUnload)
             {
                window.event.returnValue = 'Text, který bude přidán do confirmačního dialogu';
             }
          }
          function bypassCheck()
          { 
             g_blnCheckUnload  = false; 
          }
          function setupCheck()
          {
             g_blnCheckUnload  = true; 
          }
          registerEvents()
          {
             for (i = 0; i < document.forms[0].elements.length; i++)
             {
                document.forms[0].elements[i].onchange = setupCheck;
             }
          }
       </script>
    </head>
    <body onLoad="registerEvents();" onBeforeUnload="RunOnBeforeUnload();">
       <form ...>
          <input .../>
          ...
       </form>
       <a href="http://www.havit.cz">dotaz zobrazen, jsou-li změny</a>
       <a href="http://www.havit.eu" onClick="bypassCheck">dotaz nezobrazen</a>
    </body>
    </html>

    ...další vylepšování je samozřejmě možné.

  • Tisk dlouhých tabulek - záhlaví a zápatí na každé stránce

    Poměrně neznámým fíglem lze v některých browserech zajistit, aby se při tisku dlouhých tabulek, které se nevejdou na jednu stránku, vytiskly určité jejich řádky na každé stránce (záhlaví a zápatí).

    Stačí využít sekce tabulky thead a tfoot a nastavit jim ty správné styly.

    ...
    <style type="text/css">
       thead {display: table-header-group;}
       tfoot {display: table-footer-group;}
    </style>
    ...
    <table>
       <thead>
          <tr>
             <td>Hlavička 1</td>
             <td>Hlavička 2</td>
          </tr>
       </thead>
       <tbody>
          <tr>
             <td>123</td>
             <td>456</td>
          </tr>
          ...
       </tbody>
       <tfoot>
          <tr>
             <td>Patička 1</td>
             <td>Patička 2</td>
          </tr>
       </tfoot>
    </table>

    Odzkoušeno to mám pozitivně v Internet Exploreru 6 a Mozille FF 1.0.7, Opera 8.54 negativní.

    Svůj prohlížeč si můžete ověřit náhledem tisku k jednoduché ukázce:

    Tisk-tabulky-hlavicka-paticka.htm

  • Velikost okna browseru univerzálně

    V jednotlivých prohlížečích se informace o aktuální velikosti okna zjišťuje dost různě, je tedy nutno použít určitou kaskádu pro "univerzální" (alespoň trochu) vyhodnocení:

    var winWidth, winHeight, d=document;
    if (typeof window.innerWidth!='undefined')
    {
       winWidth = window.innerWidth;
       winHeight = window.innerHeight;
    }
       else
    {
       if (d.documentElement && )typeof d.documentElement.clientWidth != 'undefined') && (d.documentElement.clientWidth != 0))
       {
           winWidth = d.documentElement.clientWidth;
           winHeight = d.documentElement.clientHeight;
       }
       else
       {
           if (d.body && (typeof d.body.clientWidth != 'undefined'))
           {
               winWidth = d.body.clientWidth;
               winHeight = d.body.clientHeight;
           }
       }
    }
  • CSS: Vertikální centrování

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
    <html>
    <head>
       <title>Vertikální centrování</title>
       <style>
          .greenBorder {border: 1px solid green;} /* nepodstatný styl */
       </style>
    </head>
    <body>
       <div class="greenBorder" style="display: table; height: 400px; _position: relative; overflow: hidden;">
          <div style=" _position: absolute; _top: 50%;display: table-cell; vertical-align: middle;">
             <div class="greenBorder" style=" _position: relative; _top: -50%">
                libovolný prvek<br>
                libovolné výšky<br>
                a libovolného obsahu<br>
                zůstává vertikálně vystředěný
             </div>
          </div>
       </div>
    </body>
    </html>
    Zdroj: JakPsatWeb.cz
    Funguje i s jinými DOCTYPE, vyzkoušeno např. s HTML 4.01 Transitional s loose.dtd.

     

  • background-position - Opera a Mozilla některá zadání ignorují

    V některých starších Mozillách a snad ve všech Operách je problém, že tyto prohlížeče nesnáší určité kombinace zadání hodnot background-position. Konkrétně je problém v kombinaci keywordu a číselného zadání:

    background-position: center 22px;  /* !!! nejde keyword pixels !!! */
    background-position: 50% 22px;     /* takhle to jde */
    background-position: top 50%;      /* !!! nejde keyword a procenta !!!*/
    background-position: 0% 50%;       /* takhle to jde */

    Naštěstí jdou všechny keywords převést na procenta, jak je výše naznačeno, takže no problem...

  • Pozicování obrázkových bulletů - ul, li

    S pozicování obrázkových bulettů použitých jako list-style-image je děsnej opruz, každý prohlížeč to interpretuje jinak a spolehlivě to snad ani nejde.

    Je mnohem jednodušší dát list-style-type:none a obrázkové bulettky udělat jako správně pozicované pozadí li:
    ul { list-style-type: none; }
    li
    {
       background-image: url(...);
       background-repeat: no-repeat;
       background-position: 0 5px;
       padding-left: 10px;
    }

  • Mozilla: nefunguje window.navigate('url')

    Mozilla navigate('url') nepodporuje.

    Místo toho je potřeba použít standardní

    window.location.href = 'url';

    ...což funguje i v IE.

  • Peekaboo bug v Internet Exploreru 6

    Jedná se o poměrně pozoruhodný renderovací bug, který se projeví v tu nejméně vhodnou chvíli, a to tak, že nám po stránce poskakují objekty z místa na místo, obvykle při přecházení myší přes nějaký link (hover). Souvisí s float objekty a někdy není úplně jednoduché se ho zbavit.

    Některá doporučení říkají, že se má experimentovat s volbou

    position: relative;

    nicméně mě se nejvíce osvědčilo nastavení rozměru height poskakujícího prvku. Aplikoval jsem to navíc přes podtržítkový filtr (pravidlo se díky jinému bugu aplikuje jen v IE), takže nakonec prostě

    _height: 0;

    Obecně pomáhá různé šachování s rozměrovými vlastnostnostmi - width, height, line-height, atp.

    posted 24. dubna 2006 0:57 by Robert Haken | 1 Comments
    Filed under: