Autor Zpráva
pepan
Profil *
Ahoj, chtěl jsem se zeptat, jestli se dá udělat refresh "jen určité" části stránky. Mám pomocí PHP udělaný skript, který zobrazuje graf (doba od začátku nějaké akce). Jde o kombinaci PHP a CSS a já bych potřeboval, přibližně každou minutu aktualizovat ten graf a ne celou stránku (kvůli dlouhému načítání a přesnosti počítadla). Díky
los
Profil *
Ak je to obrázok a má nastavené, aby sa nekešoval, tak by malo stačiť len znova nastaviť zdroj (var img = document.getElementById("obrazok"); img.src = img.src;).

Ak to nie je len obrázok, tak zadaj do Google: Ajax.
carlik
Profil *
obrázek to bohužel není, je to, tabulka, ve které se mění velikost barvy pozadí... konkrétně tady .... S tím googlem je mi to jasné, ale nevím co mám konkrétně hledat...
pepan
Profil *
ještě něco k tomu, na té stránce je použit meta tag refresh po 5-ti vteřinách, čemuž se chci právě vyhnout... Další možnost, která mě teď napadla by byla iframe, ale tomu se raději chci také vyhnout
Petroff
Profil
Právě pro tohle se hodí javascript a ne PHP. Pokud ovšem potřebuješ v realném čase komunikovat se serverem tak asi buď čistokrevný AJAX nebo snazší (a nikoliv asynchronní) způsob komunikace. Mám tu jednu ukázku, není to složité:

Dynamické načítání obsahu do HTML z aplikace přes JavaScript http://www.chose.cz/weblog/index.php/dynamicke-nacitani-obsahu-pres-ja vascript/

<script type="text/javascript">
var vystup = document.getElementById('vystup');

function stahniData(akce) {

// odmazeme stary skript, pokud existoval
var hlavicka = document.getElementsByTagName('head')[0];
var dataLoader = document.getElementById('scriptLoader');
if(dataLoader) hlavicka.removeChild(dataLoader);

// vytvorime novy element script
script = document.createElement('script');
script.id = 'scriptLoader';
script.src = 'javascript-rpc.php?akce='+akce+'&r='+Math.random();

// POZOR, DULEZITE!! Skript musime vlozit do stranky
// pomoci DOM - appendChild()
// Ihned po vlozeni prohlizec stahne skript a spusti jej
x = document.getElementsByTagName('head')[0];
x.appendChild(script);

return false;
}

function vypisText(txt) {
// nejsnazsi cesta, vlozime novy kod ke staremu na konec
vystup.innerHTML += txt;
}

function chyba(txt) {
// obycejny alert s hlaskou
alert(txt);
return true;
}

function vymazData() {
// v jednoduchem cyklu smazeme vsechny elementy v prvku vystup
while(vystup.hasChildNodes()) vystup.removeChild(vystup.childNodes[0]);
return false;
}

stahniData('dolly');
</script>

Celé kouzlo je pouze ve správném využití DOM a především funkce createElement(). Doporučuji prostudovat příklad na samotatné stránce http://www.chose.cz/priklady/javascript-rpc/
Tento způsob načítání dat funguje spolehlivě ve všech verzích IE, Gecko a Opeře. Jediné problémy jsou v prohlížečích na jádře KHTML (Konqueror, Safari), kde nedojde ke stažení dynamicky vytvořeného elementu script.
Petroff
Profil
Můšeš uvést konkrétní použití (anebo jde fakt jen o to vyslat jednou za čas 1 číslo a převést ho na width:3% a současně tamtéž zapsat) ?
No nejdřív si to sprav => máš tam sice:

.graph .bar span { position: absolute; left: 1em; }
</style>
<div class="graph"><strong class="bar" style="width: 3%;">3%</strong></div>

ale ten span (počítám že ho tam máš na to číslo 3%) vůbec nepoužíváš a tak ti v IE6 barva obklopí celé číslo 3%.Je to díky tomu, že se width:3% roztáhne na šířku celého textu.
TAKHLE TO FUNGUJE I V IE6:
<div class="graph"><strong class="bar" style="width: 3%;"><span>3%</span></strong></div>
pepan
Profil *
Jde přesně o to, aby se to číslo u width ( = proměnná v PHP ) aktualizovalo, protože pokud by měl příchozí návštěvník stránku, na které ten graf bude, jen zobrazenou a nepřecházel by na jiné nebo pokud by nepoužil refresh, tak by ten graf byl celou dobu stejný...
Petroff
Profil
Takhle vypadá ten tvůj ukazatel aktualizovaný pouze javaskriptem:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Graf</title>
<script type="text/javascript">
window.onload=function(){
var
counter=0,
step = 200; /* KROK O 1% (v milisekundách) */
/********************************************************************/
function nastav(width) /* NAPŘ. nastav(55) nastaví ukazatel na 55% */
{
el = document.getElementById("out");
el.innerHTML = width+"%";
el.style.width = width+"%";
el.parentNode.style.width = width+"%";
}
/********************************************************************/
function update(){nastav(counter); counter = ++counter%101 }
setInterval(update,step);
}
</script>
</head>
<body>
<style>
.graph {
position: relative;
width: 200px;
margin: 1em;
padding:1px;
border: 1px solid black;
color: red;
font: bold 14px sans-serif;
}
.graph strong {
position: absolute;
left: 0.5ex;
margin-left: 80%;
}
.graph div {
position: relative;
background: #B1D632;
height: 3ex;
line-height: 3ex;
}
</style>

<div class="graph"><div><strong id="out"></strong></div></div>
<br />
<div class="graph"><div style="width: 1%"><strong style="width: 1%"> 1%</strong></div></div>
<div class="graph"><div style="width: 99%"><strong style="width: 99%"> 99%</strong></div></div>
</body>
</html>


Nastavil jsem vysokou rychlost: krok +1% ~ 200ms kvůli toho, aby sis mohl prohlídnout na ukazateli celý rozsah 0-100%
Klíčová je funkce nastav(procenta)
Pokud jde o jakousi časomíru (jsem to tak pochopil), tak stačí vhodně nastavit proměnnou STEP (1minuta: step=60000) a hotovo.
Pokud potřebuješ data ze serveru, tak ponecháme:
styly + funkci nastav() + xhtml řádek: <div class="graph"><div><strong id="out"></strong></div></div>
a pokračujeme...
pepepa
Profil *
a nedalo by se to nejak skombinovat s PHPkem?
Mam totiz takovyhle zdrojak (ty promenny kdy akce zacina a konci potom budu tahat z databaze)...

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Refresh" content="5" />
<title>Graf</title>
</head>
<body bgcolor="">
<style>
.graph {
position: relative; /* IE is dumb */
width: 200px;
border: 1px solid black;
padding: 1px;
color: black;
}
.graph .bar {
display: block;
position: relative;
background: #B1D632;
text-align: center;
color: red;
height: 2em;
line-height: 2em;
}
.graph .bar span { position: absolute; left: 1em; }
</style>

<?php
// parametry zacatku akce - hodiny, minuty, mesic a rok
$hod = 21;
$min = 22;
$mesic = 9;
$den = 29;
$rok = 2007;

// parametry konce akce - hodiny, minuty, mesic a rok
$hod_k = 13;
$min_k = 00;
$mesic_k = 9;
$den_k = 31;
$rok_k = 2007;

$cas_ted = mktime();
$cas_zacatek = mktime($hod, $min, 0, $mesic, $den, $rok); // upravit - $hod, $min, 0, $mesic, $den, $rok
$cas_konec = mktime($hod_k, $min_k, 0, $mesic_k, $den_k, $rok_k); // $hod_k, $min_k, 0, $mesic_k, $den_k, $rok_k

$cas_ted = mktime();
$d_sec = $cas_zacatek - $cas_ted;
$d_day = floor($d_sec/86400); // zaokrouhli dny na cela cisla
$d_sec -= $d_day * 86400;
$d_hrs = floor($d_sec/3600); // zaokrouhli hodiny na cela cisla
$d_sec -= $d_hrs * 3600;
$d_min = floor($d_sec/60); // zaokrouhli minuty na cela cisla
$d_sec -= $d_min * 60;


$procenta = round(100*(1-($cas_konec - $cas_ted)/($cas_konec - $cas_zacatek)));

if ( $cas_ted < $cas_zacatek) // vypise hlasku (akce nezacala)
print "Akce zacíná za za $d_day dní, $d_hrs hodin, $d_min minut, $d_sec vterin."; // hlaska, ktera se vypise pred zacatkem akce
elseif ($cas_ted > $cas_zacatek && $cas_ted < $cas_konec) // akce zacala
echo'<div class="graph"><strong class="bar" style="width: '.$procenta.'%;">'.$procenta.'%</strong></div>';
else // akce skoncila
print "Akce skoncila."; // hlaska, ktera se vypise po skonceni akce
?>

</body>
</html>
pepan
Profil *
pomůže mi prosím někdo??
Petroff
Profil
Promiń, až dnes jsem si přečetl tvůj poslední příspěvek, něco takového jsem očekával, takže to určitě snadno půjde.
Jinak - pustil si ten můj kód ? Vyhovuje ti ta grafická úprava ?
Popíšu ti jak to bude fungovat (až to sesmolím).
Na stránce bude trvale (součást HTML stránky):
- styly
- informační okénko hned na začátku: <p id="inf"></p> .......pěkně ho ostyluj
- funkce pro zápis do tohoto okénka: <script> function zapis(txt){document.getElementById("inf").innerHTML=txt;}</script>
Na stránce nebude (funkční):
<meta http-equiv="Refresh" content="5" />
(respektive bude kvůli uživatelům bez JS, ale pokud je javascript zapnutý, bude to zrušeno->předvedu)
====================================================================== ============================================
Pokud akce:
(1) ještě nezačala
------------------------
=> echo "<script> var vterin_do_akce=XXXX [.....následuje script[No.1] který sepíšu.....]</script>"
<Činnost scriptu>
<1a> Do info-okénka začne každou vteřinu psát aktualizovaný text:
zapis("Akce zacíná za "+ days + " dní , " + hrs + " hodin , " + mins + " minut a " + secs + " vterin.")
<1b> PO DOBĚHNUTÍ ČEKÁNÍ (vterin_do_akce=0) NAČTE STRÁNKU: windows.location.reload()
Pokud akce:
(2) probíhá
---------------------
=> echo "<script> var vterin_ubehlo=XXXX, vterin_celkem=YYYY [.....následuje script[No.2] pouze upravím ten z minulého příspěvku...]</script>"
=> echo "<div class="graph"><div><strong id="out"></strong></div></div>"
<Činnost scriptu>
<2a> Do info-okénka zapíše:zapis("Akce probíhá....viz ukazatel průběhu/NEBO TAK NĚJAK/")
<2b> Zavolá funkci nastav(procenta) a opakuje každou vteřinu, aktualizovaná hodnota je: procenta= Math.round(vterin_ubehlo/vterin_celkem)
<2c> PO DOBĚHNUTÍ UKAZATELE NA 100% (vterin_ubehlo==vterin_celkem) NAČTE STRÁNKU: windows.location.reload()
Pokud akce:
(3) skončena
---------------------
To už si udělej jak chceš, ale protože <p id="inf"></p> je stálý prvek na této stránce a JS funkce k zápisu taky,
použij ho(ji) k výpisu sdělení o ukončení akce.
Takhle:
echo "<script> zapis("....akce skončila......")</script>"

NAPIŠ JESTLI JSI PRO A PUSTÍM SE DO TOHO (otázka hodiny,max.dvou)
TY BYS MUSEL VYROBIT V PHP VÝPOČET (POPŘ. PŘEVEDENÍ NA VTEŘINY) HODNOT: vterin_do_akce, akce-ubehlo, akce-celkem
pepepa
Profil *
Ahoj, určitě bych zájem měl, jen nevím, kdy se k tomu dostanu, ale počítám tak nejpozději zítra večer nebo v pátek ráno, s těmi výpočty to určitě nebude problém... Jo a ta grafická úprava vyhovuje. Předem díky
Petroff
Profil
No zjistil jsem, že do zítra (max pozítři) se zbavím starých restů a budu mít čas(a klid!).
pepepa
Profil *
Petroff : Ok, tak snad zitra, dneska na to cas mit nebudu, protoze jsem ve skole do 8 a pak jedu z Plzne na Tabor, takze bych mel cas, ale az pozde vecer, coz asi nebude mit cenu
Petroff
Profil
Tak jsem doma a můžu se do toho pustit.
1 URL adresa .... 1 dokument (zdroják)na serveru.....ale 3 možné podoby (to obstará PHP )
Nejdřív udělám skript č.1 = ve zdrojáku to bude toto:
<?PHP.........
$cas_ted = mktime();
$cas_zacatek =......;
$cas_konec = .......;
$cas_interval= $cas_ted - $cas_zacatek;
if ( $cas_interval < 0 ) // nacte script 1 (akce nezacala)
print "<script> var do_akce=-($cas_interval); ......</script>" elseif...... ?>


[sice php neznám, ale všiml jsem si že jsou 2 funkce k zápisu - echo a print - a že print umí zapsat přímo hodnotu proměnné]
Můžeš mi sdělit co se přesně zapíše ?
(hodnota proměnné bude např. $cas_interval=-1234): print "..... var do_akce=-($cas_interval);.....";
Jde mi o to že na výrazu: var do_akce=--1234; by JS hodil chybu, kdežto var do_akce=-(-1234)je v pořádku ]
Petroff
Profil
Narazil jsem na problém: umístil jsem na stránku <meta http-equiv="Refresh" content="10" /> aby uživatel bez JS mohl mít aspoň nějak aktualizovanou stránku, a přestože JS spolehlivě tento tag odstraní, tak s křížkem po funuse (dojde k refreši)
Vychází mi jediné řešení (kromě nápadu se na uživatele bez JS vykašlat) = mít 2 verze stránky:

A.http://strankaA.html - to je ta, kterou v současné době máš a do které se přidá řádek <script type="text/javascript">window.location="http://strankaB.html"</script>
Tento kód pokud funguje JS načte verzi B

B.http://strankaB.html - čistě JS verze kterou vyrábíme

Takže pokud budou 2 verze, nepřijde nic z PHP co máš nazdar
los
Profil *
IMHO nahrávať znovu stránku (location.reload) v prípade prechodu z jedného stavu do druhého je zbytočné (klient z toho nezíska nič nové). Rovnako zbytočný sa mi zdá pravidelný refresh pre používateľov bez podpory JavaScriptu (kto nepodporuje JavaScript, zrejme očakáva, že sa mu nebudú informácie dynamicky aktualizovať).

Spravil by som to tak, že celá tá vec by bola v div id=msg a JavaScriptom by sa obnovoval jeho obsah.

Jednoduchý príklad, ktorý si môžeš upraviť podľa svojich predstáv:
http://los.php5.cz/jpw/time.php
Petroff
Profil
No vidíš, vykašlal jsem se na synchronizaci v klíčových momentech, stránka trochu nakynula (jen maličko) ale zato se značně zredukuje PHP režie, pokud nebude stránka pro uživ. bez js. Ale já bych ji klidně udělal, je to maličkost navíc.
Vlastně se části výpočtu se dají libovolně přesouvat z js do php a naopak (tedy ty inicializační). JS pracuje s vteřinami, tak ať PHP dodá 2 vstupní hodnoty = je to oboustranně idealní.

los
kto nepodporuje JavaScript, zrejme očakáva, že sa mu nebudú informácie dynamicky aktualizovať
Dovoluji si nesouhlasit. Mnozí to mají z důvodů bezpečnostních a že pak musí oželet dynamické aspekty u stránek s JS je důsledek (nikoli účel).

malé upozornění - nastav si správný <meta....charset=...> já v poslední době už používám jen utf-8 !!!!
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Graf</title>
<script type="text/javascript">
//
// TADY POUŽÍT:
//_<_?_PHP_
var counter=-10 ; /* << ČAS_ZAČÁTKU_AKCE - ČAS_AKTUALNÍ (S) */
var delka_akce=30; /* << TRVÁNÍ_AKCE(S) */
// _?_>_
//
var krok = 1; /* v sekundách */
var takt;
var obsluha;
var eGraf,eGD;
var eText;
var veta;
/********************************************************************* **************************/
function zobraz_graf(ano){ document.getElementById("grDisp").style.display=ano?"block":"none" }
/********************************************************************* **************************/
function rozepis_cas(t){
var txt="",act;
function pridej_txt(vterin,j1,j234,j5){
var tvar,tmp;
if (tmp=Math.floor(t/vterin)){
act=tmp+" "+(tmp==1?j1:tmp>4?j5:j234);
t%=vterin;
txt+=(txt?(t?", ":" a "):"")+tmp+" "+(tmp==1?j1:tmp>4?j5:j234);
}
}
pridej_txt(24*3600,"den","dny","dnů");
pridej_txt(3600,"hodina","hodiny","hodin");
pridej_txt(60,"minuta","minuty","minut");
pridej_txt(1,"vteřina","vteřiny","vteřin");
return txt;
}
/********************************************************************* **************************/
function zapis_text(txt) { eText.innerHTML = txt }
function zapis_graf(width)
{
width=Math.round(width);
eGraf.innerHTML = width+"%";
eGraf.style.width = width+"%";
eGraf.parentNode.style.width = width+"%";
}
/********************************************************************* ********************************/
function obsluha(){
var cas=counter++;
if (cas<0) { zapis_text("Do začátku akce zbývá: "+rozepis_cas(-cas)); return }
if (cas<1) { zobraz_graf(true); zapis_text("Akce už začala. Její průběh monitoruje grafický displej.") }
if (counter>delka_akce) po_akci(); else zapis_graf(cas/delka_akce*100);
}
/********************************************************************* *********************************/
function po_akci()
{
if (takt) clearInterval(takt);
zobraz_graf(false);
zapis_text("Akce skončila.")
}
/********************************************************************/
window.onload=function(){
zobraz_graf(false);
eGD = document.getElementById("grDisp");
eGraf = document.getElementById("doGrafu");
eText = document.getElementById("doTextu");
if (counter>delka_akce) { po_akci(); return }
if (counter<0) zobraz_graf(false);
takt=setInterval(obsluha,1000*krok);
obsluha();
}
</script>
</head>
<body>
<style>
#grDisp {
position: relative;
width: 200px;
margin: 2em auto 0 -100px;
padding:1px;
border: 1px solid black;
color: red;
font: bold 14px sans-serif;
}
#grDisp strong {
position: absolute;
left: 0.5ex;
margin-left: 80%;
}
#grDisp div {
position: relative;
background: #B1D632;
height: 3ex;
line-height: 3ex;
}
.loctxt {
border-top: 1px solid navy;
border-bottom: 1px solid navy;
padding-left:50%;
margin: 3em auto;

height: 32px;
}
#doTextu {
width:600px;
padding: 0;
margin: 0;
margin-left:-250px;
color: navy;
font: bold 16px/32px Tahoma,san-serif;
}
</style>
<div class="loctxt"><p id="doTextu"></p>
<div id="grDisp"><div><strong id="doGrafu"></strong></div></div>
</body>
</html>
Petroff
Profil
loshttp://los.php5.cz/jpw/time.php
Naprosto souhlasím,že vygenerovat i HTML prvky v JS je idealní.
Na druhou stranu, stejně tam bude ten php, proč ho nevyužít - jen by trochu nakynul o to vkládání několika tagů (co se tyka počtu bytů, tak těch by bylo víc v js kódu).
Nějak ti nefunguje gr.display (prohlíženo v IE7).

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0