-
03-11-2012, 14:41 #1Member
- Registered
- 28/07/02
- Location
- Gent
- Posts
- 2,195
- iTrader
- 19 (91%)
- Mentioned
- 0 Post(s)
- Reputation
- 0/144
background change naar gelang woord in div
Hallo allemaal. ben met klein projectje bezig en zou graag de achtergrond van mijn website veranderen afhankelijk van een woord in een div.
De div background bevat een src attribuut waar bijvoorbeeld img/snow.jpg moet inkomen als er in een onderliggende div een <p>het gaat sneeuwen</p> staat, waar ik dus moet gaan uitzoeken of het woord sneeuw in die p tag bestaat.
Extra moeilijkheid, waar ik niet uitgeraak. Die div zijn inhoud veranderd naarmate je op verschillende links buiten de div duwt. Dus ik heb 4 links, en deze gaan info genereren in de DIV (info). naar gelang ik op link 1 duw kan dit dus de woorden "het gaat morgen regenen" geven, waar ik dan dus een regen background wil. Ik kan op voorhand niet weten welke link wat gaat geven, wordt door API gegenereerd.no votes
-
-
03-11-2012, 15:35 #2
Als je met jquery wil werken;
:contains() Selector – jQuery API
Dit impliceert wel dat je weet (of toch ongeveer, je kan bijvoorbeeld ook checken op kernwoorden) welke text er zou moeten komen in je div.no votes
-
05-11-2012, 15:11 #3Deactivated user
- Registered
- 14/08/10
- Location
- Diest
- Posts
- 2,419
- iTrader
- 1 (100%)
- Mentioned
- 0 Post(s)
- Reputation
- 8/16
Edit this Fiddle - jsFiddle
Code:$("textarea").keyup(function() { var body = $("body"), val= $("textarea").val(); if(val.indexOf("sneeuw") >= 0) { body.css("background", "url('http://wallpapers.leovacity.be/images/Sneeuw_bomen_wallpaper.jpg')"); } else if(val.indexOf("zon") >= 0) { body.css("background", "url('http://4.bp.blogspot.com/-61a-UQDaLjY/TscS7yhLObI/AAAAAAAAAa0/iRrh7_vwZt4/s1600/sunshine-wallpaper-10-759118.jpg')"); } else if(val.indexOf("regen") >= 0) { body.css("background", "url('http://wallpaperstate.org/wp-content/gallery/wallpaper_rain_11/wallpaper_8358.jpg')"); } else { body.css("background", "none"); } });no votes
-
05-11-2012, 15:27 #4
$("body") ieder keer evallen is nutteloos en een dure operatie. Dus best die buiten de scope van de keyup handling zetten. Over het algemeen is gans bovenstaand voorbeeld een heel intensief ding dat beter vroeg geoptimaliseerd wordt.
Bij elke keyup ga je een DOM manipulatie toepassen, of die nu nodig is of niet. Je bent beter af van die buiten de event handler te cachen en enkel bij verandering van de background value de manipulatie te doen.
In dit geval gaat het nu waarschijnlijk wel gewoon om een kort voorbeeld ter illustratie, maar dit soort gruwelijke frontend code heb ik dus al vaak mogen opkuisen. jQuery (of gelijk welk ander DOM manipulation framework) heeft voor heel wat webdesigners een nieuwe wereld doen opengaan, maar tegelijk snappen ze niet hoeveel achterliggende code al die easy-peasy function calls met zich meebrengen.
En dan zijn ze verwonderd dat volgende zaken gebeuren: "mijn website crasht op smartphone", "de browser geeft trage script warning", "de browser blokkeert". De code was heel gelijkaardig aan bovenstaand voorbeeld trouwens, enkel nog een "each" loop over een lijst met 100 items per pagina waar aan elk van die list items een event gehangen werd, waar de inhoud van de velden genomen werd, op bepaalde keywords werd gecontroleerd, etc.
En trouwens, wat met een omschrijving in de zin van: "Heel de dag enorm veel regen, maar toch zeker vijf minuten een straaltje zon". De achtergrond zou een zonnige dag geven ;-)Last edited by bealzebub; 05-11-2012 at 15:32. Reason: indexOf en condition fallthrough
no votes
-
05-11-2012, 15:56 #5Deactivated user
- Registered
- 14/08/10
- Location
- Diest
- Posts
- 2,419
- iTrader
- 1 (100%)
- Mentioned
- 0 Post(s)
- Reputation
- 8/16
^ Zoals je zegt is het maar een startpunt. Een voorbeeld. Ik dacht: die jongen krijgt hier geen antwoord dus ik zal snel eens een voorbeeld schrijven.
Ik veronderstel dat je bedoelt $("textarea") continu checken, maar de andere mogelijkheid was .change gebruiken. Daar voelde niet juist aan omdat een gebruiker dan 'uit' de textarea moet gaan voor er een verandering optreedt. Aangezien het hier een kleine test case is (ervan uitgaande dat er weinig andere functies gedraaid moeten worden en dat een gebruiker maar een a twee zinnen schrijft) is dit volgens mij de snelste en meest effectieve manier.
Ja, dat laatste ben ik me van bewust. Dat is echter niet mijn probleem, dat kan de TS zelf wel oplossen veronderstel ik (iets als else if zon && regen | wisselvallig).
Feel free om zelf een beter voorbeeld te schrijven natuurlijk.no votes
-
05-11-2012, 17:34 #6Member
- Registered
- 28/07/02
- Location
- Gent
- Posts
- 2,195
- iTrader
- 19 (91%)
- Mentioned
- 0 Post(s)
- Reputation
- 0/144
Yow lieve mensen. Merci voor de hulp en ik heb het in orde gekregen. Mijn begin voorbeeld was wat aan de vage kant en er was niet direct een kant en klare oplossing voor te vinden. Het grote probleem in mijn geval was dat ik nergens kon achterhalen waar hij mijn div juist opvulde. Na wat opzoek werk te hebben gedaan heb ik die api (weather api van yahoo) gevonden en daar de mooie broncode in gevonden waar ik dus duidelijk zag wanneer en hoe hij mijn divs vulde met welke tekst. heb daarin zelf een stukje Jquery in geplakt die bij het maken van de div de bijpassende achtergrond image gaat meegeven.
Het ging steeds om kernwoorden dus het voorbeeld van [quote]En trouwens, wat met een omschrijving in de zin van: "Heel de dag enorm veel regen, maar toch zeker vijf minuten een straaltje zon". De achtergrond zou een zonnige dag geven ;-)
/quote] was niet van toepassing.
Soit ik ben nog verre van een echte programmeur, maar door zo een kleine dingen te doen leer ik toch steeds bij. En nogmaals merci voor de aangebode hulp.no votes
-
05-11-2012, 18:09 #7
Dit is ruwweg hoe ik het zou doen (is nu wel rap rap op een klein kwartierke gedaan, dus is nog wat ruimte voor verbetering). De code gaat van de veronderstelling uit dat het eerste keyword dat ie tegenkomt ook het belangrijkste is. Alhoewel regex iets trager is dan indexOf, zal het in het grote plaatje performanter zijn dan een ganse lijst if else condities (en ook makkelijker te onderhouden).
En BramVroy, zeker geen kritiek op jouw code hoor, het is in elk geval een stuk minder WTF dan de mijne als je er de eerste keer naar kijkt
Link naar downloadbare syntax colored code als Gist op Github
Code:<!doctype html> <head> <title>Achtergrond instellen ahv eerste keyword</title> <style type="text/css"> body { height: 100%; background: #e0e0e0 no-repeat center center fixed; background-size: cover; -webkit-background-size: cover; -moz-background-size: cover; } form { width: 80%; margin: 50px auto; } textarea { width: 100%; height: 40px; background-color: #fff; border: 1px solid #cccccc; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; -moz-transition: border linear 0.2s, box-shadow linear 0.2s; -o-transition: border linear 0.2s, box-shadow linear 0.2s; transition: border linear 0.2s, box-shadow linear 0.2s; font-size: 14px; line-height: 20px; color: #555555; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } textarea:focus { border-color: rgba(82, 168, 236, 0.8); outline: 0; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); } input[type="submit"] { display: none; } </style> </head> <body> <form action="#no-javascript-fallback-url"> <textarea name="weer-waarde" cols="30" rows="10" placeholder="Geef hier het huidige weer in…"></textarea> <input type="submit" /> </form> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script> <script type="text/javascript"> // Alles mooi in een wrapper steken en jQuery beschikbaar maken (function($) { "use strict"; // Vermijd global namespace vervuiling // In dit object kan je de woorden definiëren en de url naar de image die voor // dat woord moet geladen worden, gemakkelijker om nieuwe zaken toe te voegen var config = { "sneeuw": "http://wallpapers.leovacity.be/images/Sneeuw_bomen_wallpaper.jpg", "zon": "http://4.bp.blogspot.com/-61a-UQDaLjY/TscS7yhLObI/AAAAAAAAAa0/iRrh7_vwZt4/s1600/sunshine-wallpaper-10-759118.jpg", "regen": "http://wallpaperstate.org/wp-content/gallery/wallpaper_rain_11/wallpaper_8358.jpg", "bliksem": "http://people.ee.duke.edu/~zc/pic/lightning.jpg", "wind": "http://exploringweather.com/windstorm.jpg" }; // Laat ons alle afbeeldingen in de achtergrond preloaden (non-blocking) // Hoeft niet, maar zal sneller achtergrond veranderen for(var key in config) { var img = new Image(); img.src = config[key]; } $(document).ready(function() { var body = $('body'); // Evalueer eenmalig, toch altijd hetzelfde var textarea = $('textarea'); // Evalueer eenmalig, toch altijd hetzelfde var regex = Object.keys(config).join("|"); // Regex search op de keys van config var previousBackground; // Functie om de background te veranderen, enkel als het om een nieuwe background gaat var setBackground = function(value) { var currentBackground; // Background string genereren if(value) { currentBackground = 'url("'+config[value[0]]+'")'; } else { currentBackground = "none"; } // Enkel DOM manipuleren als ie niet overeenkomt met wat er al is if(currentBackground !== previousBackground) { body.css("background-image", currentBackground); } // En voor de volgende keer de huidige waarde instellen previousBackground = currentBackground; } // Event handling van keyup in textarea textarea.on("keyup", function() { var val = textarea.val(); // Value nemen, textarea is al jQuery extended // Laat ons van de veronderstelling uitgaan dat het belangrijkste woord vooraan staat // Voorbeelden: // Regen, daarna zon // Smeltende sneeuw, na de middag piept de zon door de wolken setBackground(val.match(regex)); }); textarea.focus(); }); }(jQuery)); </script> </body>Last edited by bealzebub; 05-11-2012 at 18:12. Reason: Overbodige code weghalen
no votes
-
09-11-2012, 00:29 #8Deactivated user
- Registered
- 14/08/10
- Location
- Diest
- Posts
- 2,419
- iTrader
- 1 (100%)
- Mentioned
- 0 Post(s)
- Reputation
- 8/16
Onder de indruk maar toch met twijfels. Waarom zou dit sneller zijn, aangezien je zelf toch bij elke keyUp enkele if-statements callt? Oké, als er nu echt 20 of meer mogelijkheden waren, maar 5? Dan lijkt me een if/else-if zeker zo snel (merkbaar).
Daarnaast even een vraagje: waarom is er volgens jou een verschil tussen dit:
en dit:Code:var body = $('body'); var textarea = $('textarea');
Hier even een topic erover: Declaring Multiple Variables in JavaScript - Stack OverflowCode:var body = $('body'), textarea = $('textarea');
Voor de rest: heel degelijk voorbeeld. Nice.no votes
-
09-11-2012, 11:19 #9
Het is niet slecht van code voor nu te schrijven, maar een beetje nadenken over code voor later is zeker niet slecht.
Zal het op 5 mogelijkheden sneller zijn? Nah, prolly not. Zal het veel geheugenefficiënter zijn met 5 mogelijkheden? Nah. Maar in de 12 jaar die ik professioneel met code bezig ben heb ik me al talloze keren de momenten beklaagd waarop ik zei: "Dat zal toch nooit zoveel gebruikt worden, code is nie goe, maar zorgen voor morgen"
Nu, ik wou alleen maar duidelijk maken dat je goed moet beseffen wat bepaalde code doet in je browser. Javascript engines zijn veel sneller geworden dan vroeger, en ze zijn juist zoveel sneller omwille van de manier waarop ze je code kunnen optimalizeren voor ze effectief wordt uitgevoerd.
Als je bijvoorbeeld binnen die keyup handler telkens $('blabla') aanroept, moet je ook beseffen wat dat doet: op het einde van de handler wordt die variable gedereferenced en klaargezet voor garbage collection. Daarna voorzie je een nieuw stukje geheugen voor identiek hetzelfde als wat je er juist voor hebt weggegooid.
Bovendien moet je ook beseffen dat die $('blabla') vergelijkbaar is met één of meerdere personen uit een mensenmassa zoeken en die met een zak patatten van 10 kilo opzadelen die ze overal moeten meedragen. Je wil vermijden dat je code ieder keer zegt: "en zet die zak patatten nu neer, ga terug naar je plaats, k ga je dan wel weer zoeken, opnieuw een zak patatten geven, …".
Ivm die regex vs. een if elsif cascade: regex is trager dan indexOf. Dat is gewoon zo. Maar 1 x regex evaluatie t.o.v. bv. 20 indexOf evaluaties (als ie in die background none van jou moet terechtkomen) is dan weer niet meer trager. Jouw code zal bij elke nieuwe case trager worden, de mijne niet. Bovendien heeft het feit dat ik de handling van de background in een aparte function aanroep het voordeel dat de browser daarop kan optimalizeren.
Dan de background setting function zelf. Ook hier weer een beetje gelijkaardig aan die zak patatten van een beetje terug. Strings vergelijken is supersnel, de jQuery .css(iets) functie is een DOM operatie en is echt wel trager.
Soit, het is gewoon beroepsmisvorming ondertussen denk ik dat ik bij alles wat ik van code lees (en zeker clientside code) constant zit te denken over wat dat eigenlijk voor de compiler of engine inhoudt. Sorry zunne
Tweede variable had ik pas later nog naar de main script body gehaald
En had nie veel zin om alles nog eens na te lezen… Maar je hebt gelijk, naar readability toe is het iets mooier van t op jouw manier te doen. In execution maakt het totaal niets uit natuurlijk.
Thx, is wel eens fun van iets kleins te doen ipv de massive codebase waar ik ganse dagen mee bezig ben
En "gewone" Javascript brengt herinneringen naar boven, tegenwoordig is het bij ons allemaal Coffeescript (super precompiler taal, maar zorg dat je gewone JS door en door snapt als je ermee begint).
no votes

