Detectarea prezenței plug-in-urilor în browser


Plug-in-urile pun la dispoziția programatorului de pagini web o gamă largă de opțiuni ce permit includerea de conținut media cum ar fi sunete, filme și animație. Problema care apare cu aceste plug-in-uri este că nu putem fi siguri dacă utilizatorul are instalat un anumit plug-in de care aveți nevoie pentru a rula o melodie de exemplu. JavaScript vă poate ajuta în această privință verificând lista de plug-in-uri instalate pe calculatorul utilizatorului și în cazul în care nu este instalat un anumit plug-in se poate redirecta automat pagina către plug-in-ul respectiv. Scriptul de mai jos testează prezența unuia dintre cele mai folosite plug-in-uri, Flash Player:


Cod:

<body>
<
script language="Javascript" type="text/javascript">
<!--
if (
navigator.plugins["Shockwave Flash"])
    {
    
document.write('<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" 
codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" 
width="100" height="80" id="test" align="middle"><param name="allowScriptAccess" 
value="sameDomain" \/><param name="movie" value="content/images/test.swf" \/>
<param name="loop" value="false" \/><param name="quality" value="high" \/>
<param name="bgcolor" value="#ffffff" \/><embed src="content/images/test.swf" 
loop="false" quality="high" bgcolor="#ffffff" width="100" height="80" name="test" 
align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" 
pluginspage="http://www.macromedia.com/go/getflashplayer" \/><\/object>'
)
    }
else
    {
    
document.write("<img src='content/images/test.gif' alt='airport' width='414' height='300' \/>")
    }
-->
</script>
</body>


Să explic puțin în continuare ce se întâmplă în codul menționat mai sus.

if (navigator.plugins["Shockwave Flash"])
{


În acest caz se verifică dacă în vectorul navigator.plugins este conținut numele "Shockwave Flash"; în caz afirmativ, testul returnează TRUE. Dacă numele comparat diferă oricât de puțin, testul va returna FALSE

document.write('<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" width="100" height="80" id="test" align="middle"><param name="allowScriptAccess" value="sameDomain" \/><param name="movie" value="content\/images\/test.swf" \/><param name="loop" value="false" \/><param name="quality" value="high" \/><param name="bgcolor" value="#ffffff" \/><embed src="content\/images\/test.swf" loop="false" quality="high" bgcolor="#ffffff" width="100" height="80" name="test" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" \/><\/object>')
}


În cazul în care verificarea returnează TRUE, scriptul scrie o bucată de cod HTML în fereastra document. Pentru acest tip de fișier sunt necesari toți parametrii tagului <object>, precum classid, codebase și param. Parametrul value cuprinde numele fișierului și este content/images/test.swf. Pentru introducerea de filme Flash în pagina web se folosesc tag-urile <embed>și <object>

Atenție!
Cum am mai specificat și în alte tutoriale, pentru a rula corect scripturile din JavaScript trebuie scrise corect, în cazul de față tot ce este inclus in document.write trebuie să se afle pe un singur rând altfel nu va funcționa scriptul.

else
{
document.write("<img src='content\/images\/test.gif' alt='airport' width='414' height='300' \/>")
}


În cazul în care verificarea va returna FALSE se înlocuieste filmul Flash cu o imagine.

Este bine să luați în considerare și posibilitatea ca utilizatorul să aibă dezactivat JavaScript și în acest caz să afișati totuși imaginea prin adăugarea codului de mai jos:


Cod:

<noscript>
<
img src='content/images/test.gif' alt='airport' width='100' height='80' />
</
noscript>


Atenție!
Acest script caută un plug-in în funcție de numele său. Dacă numele se modifică, va trebui să modificați scriptul astfel încât căutarea să se facă după noul nume.

Probabil ați observat că în interiorul scriptului tagul de închidere se termină cu secvența \/> în loc de secvența normală />
Motivul este faptul că JavaScript trebuie împiedicat să creadă că încercăm să închidem tagul <script>. Plasând un simbol backslash înaintea slash-ului spunem interpretorului JavaScript să ignore caracterul care urmează, acțiune cunoscută formal drept eludarea caracterului.


Utilizatea unei bucle pentru a verifica prezența plug-in-urilor

În exemplul anterior se verifica prezența unui anumit plug-in. Dacă însă dorim să căutăm orice versiune a plug-in-ului, scriptul anterior nu ne este de folos. Pentru acest lucru avem nevoie de o structură repetitivă, care să ne permită efectuarea unei acțiuni de un număr specificat de ori. O astfel de structură repetitivă este "for". Acest tip de buclă folosește un contor, care este o variabilă ce are o valoare inițială (de obicei 0) și se termină o dată cu satisfacerea unui test condițional din interiorul structurii. Scriptul de mai jos arată cum e construită o asemenea structură repetitivă pentru a verifica dacă printre plug-in-urile browserului se află Apple QuickTime.


Cod:

<head>
<
title>Test</title>
<
script language="Javascript" type="text/javascript">
<!-- 
avemQT false
for (i=0i<navigator.plugins.lengthi++)
    {
    if (
navigator.plugins[i].name.indexOf("QuickTime") >= 0)
        {
        
avemQT true
        
}
    }
-->
</script>

</head>
<
body>
<
script language="Javascript" type="text/javascript">
<!--
if (
avemQT)
    {
    
document.write('<embed src="content/images/test.mov" width="100" height="80"><\/embed>')
    }
else
    {
    
document.write('<img src="content/images/test.jpg" alt="test" width="100" height="80" \/>')
    }
-->
</script>

</body>


După cum observați, scriptul este compus din două părți, o parte în secțiunea <head> și unul în corpul paginii. Scriptul din <head> verifică prezența plug-in-ului QuickTime, în timp ce partea din secțiunea <body> afișează în browser în funcție de rezultat, un filmuleț de tip mov sau o poză jpg.
Să încerc în continuare să vă explic ce se întâmplă prin script.

avemQT = false

Se inițializează o variabilă de tip boolean sau logică, pe nume avemQT. O variabilă booleană poate lua exclusiv una dintre valorile adevarat (true) sau fals (false).

for (i=0; i<navigator.plugins.length; i++)
{

Aceasta este linia de început a structurii repetitive. Variabila i este folosită pe post de contor cu valoarea inițială 0. Delimitarea cu punct și virgulă denotă prezența unei alte instrucțiuni pe aceeași linie. În continuare, dacă i este mai mic decât numărul de plug-in-uri, se incrementează i cu 1. Obiectul navigator.plugins.length ne oferă numărul total de plug-in-uri instalate. În continuare, operatorul ++ este folosit pentru a incrementa valoarea lui i cu o unitate.

if (navigator.plugins[i].name.indexOf("QuickTime") >= 0)
{

Această linie începe cu o instrucțiune condițională plasată în interiorul buclei. Vectorul navigator.plugins[i] folosește parantezele drepte pentru a indica faptul că testul se adresează plug-in-ului aflat în poziția i. Metoda indexOf() întoarce poziția la care șirul de caractere "QuickTime" a fost identificat (în cazul în care este identificat) în navigator.plugins[i].name Dacă șirul de caractere nu a fost găsit, valoarea returnată este -1. Dacă el este însă prezent, valoarea returnată este poziția la care începe șirul.

Atenție!
În JavaScript, numărătoarea se începe de la 0, nu de la 1. Primul caracter este situat pe poziția 0, următorul pe poziția 1 și tot asa. Valoarea reală poate fi obținută efectiv numai prin verificarea valorii atributului length (lungime). Toate celelalte metode de lucru cu șirurile de caractere sunt bazate pe numărătoarea pornind de la 0.

avemQT = true

Dacă testul este satisfăcut, variabila avemQT ia valoarea "adevărat".
În continuare, în secțiunea <body> se găsește condiția

if (avemQT)
{

Care se traduce astfel:
Dacă variabila avemQT are valoarea true, execută linia următoare dintre acolade, respectiv

document.write('<embed src="content/images/test.mov" width="100" height="80"><\/embed>")
}

Linie care de fapt afișează filmul în browser. Mai departe, linia

else
{
document.write('<img src="content/images/test.jpg" alt="test" width="100" height="80" \/>')
}

Se traduce astfel:
Dacă testul nu este trecut (false), atunci se afișează în locul filmului o poză.

Să zicem că în continuare dorim să afișăm în browser toate plug-in-urile instalate în browser. Pentru aceasta folosim codul următor:


Cod:

<body>
<
script language="Javascript" type="text/javascript">
<!--
if (
navigator.plugins && navigator.plugins.length 0)
    {
    
document.write('Acest browser are urmatoarele plug-in-uri instalate: <table cellspacing="4" cellpadding="4">')
    
document.write('<tr><th bgcolor="#CCCCCC">Nume<\/th>
<th bgcolor="#CCCCCC">Fisier<\/th><th bgcolor="#CCCCCC">Descriere<\/th><\/tr>'
)
    for (
i=0i<navigator.plugins.lengthi++)
        {
        
acestPlugin navigator.plugins[i]
        
document.write('<tr valign="top"><td bgcolor="#CCCCCC">' acestPlugin.name)
        
document.write('<\/td><td bgcolor="#CCCCCC">' acestPlugin.filename)
        
document.write('<\/td><td bgcolor="#CCCCCC">' acestPlugin.description '<\/td><\/tr>')
        }
    
document.write('<\/table>')
    }
else
    {
    
document.write('Interpretorul JavaScript nu a gasit nici un plug-in')
    }
-->
</script>
</body>


Utilizarea dublului & (ampersand) indică faptul că ambele valori trebuie să fie adevărate pentru a se trece la execuția codului.

Exemplul arătat mai sus implică cunoașterea anterioară a numelui obiectelor pe care urmează să le afișăm. Uneori, acest lucru nu este posibil, și pentru asta putem utiliza un tip de structură repetitivă for/in pentru a afișa toate proprietățile obiectelor, indiferent de tipul acestora. Bucla for/in enumeră toate proprietățile unui obiect specificat.


Cod:

<body>
<
script language="Javascript" type="text/javascript">
<!--
if (
navigator.plugins && navigator.plugins.length 0)
    {
    
document.write('Acest browser are urmatoarele plug-in-uri instalate:')    
    for (
i=0i<navigator.plugins.lengthi++)
        {        
        
document.write('<br \/>')
        
acestPlugin navigator.plugins[i]
        for (
j in acestPlugin)
            {
            
document.write(': ' acestPlugin[j] + '<br \/>')        
            }
        }
    }
else
    {
    
document.write('Interpretorul JavaScript nu a gasit nici un plug-in')
    }
-->
</script>

</body>


Similar exemplului anterior, variabila acestPlugin are valoarea plug-in-ului curent, cel pe care il procesăm în momentul respectiv. În loc să scriem, de exemplu, acestPlugin.filename, folosim o buclă de tipul for/in pentru a parcurge toate proprietățile obiectului acestPlugin. Deoarece variabila i este deja folosită în bucla exterioară, se folosește variabila j, care la fiecare trecere prin buclă ia valoarea numelui următoarei proprietăți a obiectului acestPlugin. Este important să vedeți că j nu conține un număr, spre deosebire de i, este un șir de caractere, deși îndeplinește rolul de variabilă contor.

Atenție!
Este important să știți că aceste scripturi nu funcționează pe Internet Explorer din Windows din cauza părții de cod responsabilă de lucrul cu plug-in-urile, aceasta nefiind "înțeleasă" de browser. Internet Explorer include obiectul plug-in, doar că acesta este lipsit de conținut. În schimb pe Internet explorer de pe Mac funționează. De ce? Ar trebui să îi întrebați direct pe programatorii de la Microsoft...