ugrás a tartalomhoz

jQuery bind DOM változásra

s_volenszki · 2009. Ápr. 21. (K), 14.45
Sziasztok!

Egy weboldalon, utólag, ajax-szal injektált (appendChild) div tartalmára kell stílusokat aggatnom. Ismerem az azonosítókat, kizárólag abban akadtam el, hogy hogyan tudok jQuery-vel a DOM változására eseményt kreálni!

Segítsetek egy kicsit, merre kutakodjak?
 
1

css osztály? callback?

gex · 2009. Ápr. 21. (K), 15.02
(lehet hogy jobban járnál ha az eredeti problémádra kérdeznél rá, nem az általad elképzelt megoldás közben felmerültre)

miért nem jó, ha különböző classokat adsz az elemeknek, amiket a css fájlban definiálsz? ha ez nem felel meg valamiért akkor miért nem jó egy callback függvény, ami az ajax kérés visszatérése után fut le?

firefoxban vannak dom-események, de ezek ie-ben biztosan nem fognak működni, így semelyik js framwork-ben sem. megkerülni settimeoutos folyamatos figyeléssel tudnád, de az egy kicsit talán pazarló lehet.
2

Távoli a szkript.

s_volenszki · 2009. Ápr. 21. (K), 15.15
Akkor az eredeti probléma:

Van egy weboldal, ahova egy távol szkript (én nem tudom szerkeszteni, de ismerem a tartalmát, hiszen a távoli cím be van illesztve a html kódba) ajax-szal injektál (appendChild) egy div-et.

Ennek a div-nek a megjelenését szabom testre (keret szín, betűméret, betűszín stb.). A dekoráló rutinom már kész, működik is, azonban nem automatikusan.

Az a cél, hogy a DOM bővülésére, ez a dekoráló függvény lefusson.
3

még mindig css

gex · 2009. Ápr. 21. (K), 15.33
Ennek a div-nek a megjelenését szabom testre (keret szín, betűméret, betűszín stb.).
css?

szerk: guglival pedig ezt találtam:
mozilla, OTOH, supports DOM Mutation Events which tell us all of those things and more, bug given that there's no reliable and/or cheap way to emulate those notifications on other browsers you're kind of up a creek.
5

Részleteiben...

s_volenszki · 2009. Ápr. 21. (K), 16.07
Igen, css.

Az elemek, amiket dekorálnom kell, nem rendelkeznek egyedi azonosítóval (mindegyik div), és sajnálatosan a legkülső konténer sem azonosítható, hogy azt mondhatnám css-el hogy:

#maincontainer div{
   ...
}
"B" terv:
Ismerem azokat a funkciókat a távoli szkriptből, amik az injektálást végzik. Lehetne a dokumentumra olyan megfigyelőket akasztani, amik ezen függvények lefutását figyelik?
7

változhat

gex · 2009. Ápr. 21. (K), 16.17
biztosan jó okod van rá, hogy ne te szolgáld ki azt a js fájlt, viszont így az bármikor meg is változhat, azoknak a függvényeknek a neveivel együtt.

egyébként szerintem nem is nagyon tudnál egy függvényhívásra eseményt akasztani.
11

child selectorokkal sem?

gex · 2009. Ápr. 21. (K), 19.21
body>div>div>div kiválasztóval sem lehet megoldani? ha többre is illeszkedik, akkor azokat kiütheted egy body>div>div>div.mas (vagy body>div>div.mas>div) szaballyal. a child selectorok már úgyis csak ie6-ban nem működnek, viszont az már úgysem kell. :) (a funkció használható marad csak nem lesz olyan szép)

és talán egyszerűbb is, mint a live query-s megoldás.

szerk: a külső script mi alapján végzi a beillesztést? ha ő megtalálja azt, hogy hova kell beszúni az eredményt akkor te is meg fogod. css-sel is, js-sel is.
12

Hova illeszti be?

s_volenszki · 2009. Ápr. 21. (K), 21.29
A külső szkript így injektál:

...
TargetDiv = document.createElement("div");
var html = "<div style = \"width:351px;height:20px;border:solid 1px #043A75;\">...
...
TargetDiv .innerHTML = html;
...
Így aztán többnyire a </body> elé kerül közvetlenül.
14

megoldás 1

gex · 2009. Ápr. 21. (K), 21.57
http://dev.gex.hu/css-feladvany-5/

win alatt ff, chrome, opera, safari jó. ie6-7-8 nem jó. firebuggal töröld az utolsó div-et, az előtte lévő már nem lesz piros.
15

Megoldás 1

s_volenszki · 2009. Ápr. 21. (K), 22.06
Valóban működik! Kár, hogy nem érti az összes böngésző (IE 6-7-8).
10

Nem látom át teljesen

Ustak · 2009. Ápr. 21. (K), 18.40
de ha jól értem van egy script ami beszúr ajaxal egy divben diveket.
Az ajaxnak van callbackja, erre nem lehet eseményt akasztani?
A diveknek nincs azonosítójuk, de a saját részeden nem érsz el egy divet (-vagy bármilyen elemet- melybe majd a div belekerül melybe a div belekerül melybe az ajax beszúrja a divet:-)) aminek egyedi azonosítót tudsz adni és alapul szolgálhat a css-hez?
Fontos a beszúrt elemek struktúrája? Esetleg egyedi azonosítókat tudnál adni nekik a callbackban ha egy ciklussal megszámolod a beszúrt elemeket, és azonosítód adsz nekik (div1 div2 stb)
Vagy teljesen rosszul látom a dolgot?
13

Felépítés

s_volenszki · 2009. Ápr. 21. (K), 21.38
Ahogyan azt már feljebb is írtam, a külső szkriptet nem tudom szerkeszteni, azonban garantáltan nem változik.

A beillesztett struktúra kb. így néz ki:

<div>
   <div id="header">Tartalom</div>
   <div></div>
   <div>
      <div></div>
      <div></div>
   </div>
   <div></div>
</div>
A legelső div, ami a fő konténer, az a TargetDiv = document.createElement("div") eljárással keletkezik.

jQuery-vel kidolgoztam már az azonosítást, így minden egyes szükséges div-et meg tudok szólítani, ezzel nincs is probléma! Kidekorálni már kitudom az injektált tartalmat, a gond az, hogy ennek a bizonyos kidekorálásnak automatikusan kellene bekövetkeznie akkor, mikor a document.createElement("div")-et kitölti tartalommal a TargetDiv.innerHTML = html;

Van egy eseményem, ami az ajax request callback függvénye, a HandleResponse, az jó lenne, ha erre tudnék akasztani egy megfigyelőt.
16

megoldás 2

gex · 2009. Ápr. 21. (K), 22.12
na hát csak ott van egy id... ;) Poetro belinkelte neked a live query-t. azzal tudsz valami ilyesmit csinálni:

$('div#header').livequery(function() {
    // meghívod a this parent node-jára a függvényed, vagy ide eleve a te függvényed kerül
});
nem próbáltam, de elvileg mennie kell. ne legyen több header id-jú div, de ugye ez alap dolog.

aztán persze lehet hogy most már én sem látom a fától az erdőt és van sokkal egyszerűbb megoldás. :)
17

Nem teljesen értem.

s_volenszki · 2009. Ápr. 22. (Sze), 11.37
Köszönöm a kitartó segítségeteket, azonban még mindig nem teljesen értem.

Ha azt teszem, amit mondasz:

$('div#header').livequery(function() {
            alert('');
});
Akkor a megjelenésnél nem következik be semmi, azonban ha megnyomom a dekoráló gombomat, akkor lefut az alert('');!

Tovább elemeztem a helyzetet:

A legkülső befoglaló div így jön létre (a távoli szkriptből):

Main_Container = document.createElement("div");
document.body.appendChild(Main_Container);
Main_Container.innerHTML = '<div id="header">...</div>';
Ezért aztán a livequery nem ugrik rá, mikor elkészül, ami valószínüleg azért van, mert a div nem jQuery-vel van létrhehozva. Ha csinálok egy minta szkriptet, ami szimulálja a teljes folyamatot a távoli szkript nélkül, és az inner htmlt felváltom jQuery-s add-val, akkor működik a livequery:

Main_Container = document.createElement("div");
document.body.appendChild(Main_Container);
$(Main_Container).add("div").attr("id", "header");
Tehát a gond ott van, hogy az egyetlen azonosítható div-em innerHTML-el injektálódik az oldalba, így nincs rá hatással a livequery.

Hogyan tovább?

ps.:
Egyébként tárgyalok a gyártóval, bele is egyezett a dekorálásba, sőt megígérte, hogy a következő fejlesztésbe belevesznek egy egyedi dekorációs callback függvényt, viszont az lehet akár egy év is!
18

én ez(eke)t tenném

gex · 2009. Ápr. 22. (Sze), 12.24
1. azt mondtad hogy nem változik a js. letölteném, módosítanám egy callback függvénnyel és én szolgálnám ki. persze csak ha nincs cross-domain kommunikációs probléma.
2. közölném a megrendelővel hogy a script készítői egyelőre nem támogatják a dekorálást
2.a. szóval keressünk erre egy másik scriptet
2.b. de itt a css-es megoldás ami a látogatók nagy részét lefedi. conditional commentben pedig meghívnék egy kis js-t, ami másodpercenként figyeli, hogy az utolsó div-nek még mindig footer-e az id-ja. amint nincs footer id kapna egy másik id-t, amire már tudnék css-t írni. ezzel lefedném az ie-ket is, viszont nem terhelném a többi böngészővel érkező látogatót.
3. felháborodott levelet írnék
3.a. a microsoftnak a last-child kiválasztó hiánya miatt
3.b. majdnem mindenkinek a dom-manipuláló események hiánya miatt

van ami vicc és van ami hipotetikus (nem ismerjük még mindig a pontos részleteket, azaz mi ez a script, mit csinál, kiváltható-e másikkal).

szerk: én a css-es megoldást tartom a legtisztábbnak (ez megjelenítés, azaz a css dolga), így a gyártónak is azt javasolnám, hogy a callback függvény helyett (ami később persze jó lehet rengeteg más dologra is) előbb egy egyedi azonosítót adjanak a generált divnek. az nem lenne olyan nagy feladat és lehet hogy nem kéne egy évet várni rá.
20

Cross domain kommunikáció

s_volenszki · 2009. Ápr. 22. (Sze), 12.55
Sajnos a kommunikációból nem lehet kizárni azt a szervert, ahonnan a szkript érkezik.

Ez egy olyan alkalmazás, amitől egy webes felületen megjelenő ablakba beírt üzenet valós időben jut el egy adminisztrátorhoz és az adminisztrátor válaszolni is tud rá.

Mint egy privát szoba chat-en, csak ez browser kliensről OS-re telepített programba egy közvetítő szerver segítségével.
4

jQuery live

Poetro · 2009. Ápr. 21. (K), 16.03
A live() függvényt szerintem pont neked találták ki, vagy Live Query
6

semmi köze a dom-hoz

gex · 2009. Ápr. 21. (K), 16.09
a live függvénynek semmi köze a dom-hoz. még nem létező elemekre is lehet vele eseményt akasztani, de mint azt az általad belinkelt doksiban is írják:
Possible event values: click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, keydown, keypress, keyup
8

Live Query

Poetro · 2009. Ápr. 21. (K), 16.44
A Live Query-ben nincs ilyen korlátozás, sőt nem csak eseményeket akaszthatsz rájuk, hanem akármit.
Live Query also has the ability to fire a function (callback) when it matches a new element and another function (callback) for when an element is no longer matched. This provides ultimate flexibility and untold use-cases.
9

nem ugyanaz

gex · 2009. Ápr. 21. (K), 17.28
igazad van a live() és live query különbségeinek nem néztem utána. és ezzel tényleg megoldható, bár kicsit körülményes és a konkrét esettől függően erőforrásigényes is lehet.
19

globalis Ajax callback

carstepPCE · 2009. Ápr. 22. (Sze), 12.37
Hali,

en megprobalnak egy callback fuggvenyt irni az (osszes) Ajax hivasra es a vegrehajtando hivas urljet szurve dekoralnam ki a visszajovo adatot, hozzaillesztve a megfelelo css osztalyokat. Termeszetesen ha nem tul surun valtozik a visszajovo tartalom es nem iframe / cross-domain esetrol van szo.

-cs-
Sanyi
21

ez jó

gex · 2009. Ápr. 22. (Sze), 13.01
nem is tudtam hogy van ilyen.

szerk: pedig prototype-ban is van.
22

Kifejtenéd bővebben?

s_volenszki · 2009. Ápr. 22. (Sze), 13.03
Elképzelhető létrehozni egy olyan megfigyelőt, ami minden ajax kérést észlel?
23

ajaxPool

carstepPCE · 2009. Ápr. 22. (Sze), 13.20
esetleg ezen a teren is korulnezhettek, hatha segitseget jelent. En magam nem sokat foglalkoztam eddig ilyenekkel, csak elmeleti fejtegetesre emlexem, ami megragadta a figyelmem.

-cs-
Sanyi

szerk: a golbalis ajaxot, extjs eseten hasznaltam sikerrel, most kijott az MIT liszenszes valtozat, hatha benne van ez a lehetoseg, de szerintem, ahogy gex is irta minden fuggvenykonyvtarban van ilyenre lehetoseg.

szerk2: arra hasznaltam, hogy loadereket mutassak az oldalon, amig fut az ajax :), majd a callback hivasban eltuntettem
24

Fától az erdőt...

s_volenszki · 2009. Ápr. 24. (P), 09.57
Nem fogjátok elhinni, de megcsináltam. Annyira egyszerű, hogy szinte fájdalmas!

Fejtegettem a szkriptet ami távolról jön és a következőt találtam:

Mikor az ajax hívás sikeresen végbemegy, megépíti az alkalmazás az ablakot, létrehozza a node-ot és beleteszi az innerHTML-jébe, de a dokumentumhoz még nem append-eli. Ezen a ponton a megérkezett adatokra ráereszt az alkalmazás egy logikai ellenőrző függvényt, ami azt vizsgálja, hogy minden visszatérési érték megfelelő formátumú-e. Ha minden rendben van beteszi az értékeket az arra fenntartott szövegmezőbe és append-eli a node-ot.

Na ezt a függvényt elegánsan kimásoltam a távoli szkriptből, a szkript include-olása után adtam neki null értéket, és újradefiniáltam úgy, hogya benne van az én egyedi függvényhívásom!

Remekül működik!