Viitaten tuohon, kun julkaisin täällä Putkassa aiemmin tuolla "Nettisivujen teko" -keskustelu-osastolla julkaisin simppelin HMTL -värivalitsimen lyhyellä johdannolla suoran linkin kotisivuilleni ATK-ohjelmiini, mistä saa ladattua ajettavan JRE-tiedoston ja startti.bat -tiedoston Windows -ympäristöön ja suora linkki kotisivuilleni, josta löytyy ohjeet ja kuvankaappaus ja suora ilmainen latauslinkki tuohon HTML-värivalitsimeeni, niin viestiavaukseni poiki "jalski" -nimimerkin tiedustelun, että miksi en pistäisi lähdekoodia jakoon, ja tämä viittasi tuohon aiemmin täällä aloittamaani keskusteluun "Python -GUI -kehityskehyksistä, ja lupasin tänään iltapäivällä vastatessani "jalski" -nimimerkin tiedusteluun, että kävi alunperin mielessä pistää koodi tänne, vaikka se nyt ei ihan priimatavaraa olekaan. Pistän nyt sen tänne esille,
En tiedä vertailusta, mutta tämä ohjelma nyt kirjoitettu Java-kielellä versiolla 8 käyttäen, ja aiemmin olen julkaissut tämän ajettavana JRE-tiedostona. Varmaan joku jo tai ainakin mahdollisesti joku ennen pitkää decomplierilla, eli uudelleenkääntäjällä saa tästä jonkinlaisen koodin ihmisen ymmärrettävään muotoon, jos lataa tuon ohjelman tuolta kotisivuiltani, kun niitä pilvessäkin koodin uudelleenkääntäjiä on jo olemassa ihan tasokkaitakin, mutta tässä seuraavassa on se alkuperäinen lähdekoodi, jonka kirjoitin puhtaaseen dokumenttiin.
import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.*; import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class HTMLColorChooser extends JFrame implements ChangeListener, ActionListener { //Constructor public HTMLColorChooser() { super("HTMLColorChooser"); setSize(800,600); setDefaultCloseOperation(EXIT_ON_CLOSE); resultColor.setEditable(false); colorButton.setEnabled(true); colorButton.addActionListener(this); ohje.setText("Valitse palkeista (R,G,B) arvot 0-255, ja näet HTML-värikoodin hexana ja klikkaamalla väripainiketta kopioit värikoodin leikepöydälle myöhempää käyttöä varten."); initSlider(); initLabels(); initFields(); layOut(); } //Other methods //Initing components to super class JFrame //Labels public void initLabels() { String[] color = {"Red","Green","Blue"}; for (int x=0;x<textLabels.length;x++) { textLabels[x] = new JLabel("" +color[x]); } } //initSlider(); public void initSlider() { for (int x=0;x<sliders.length;x++) { sliders[x] = new JSlider(0,255); sliders[x].addChangeListener(this); } } //initFields public void initFields() { for (int x=0;x<textFields.length;x++) { textFields[x] = new JTextField(3); textFields[x].setEditable(false); } } //Layouting to JFrame public void layOut() { super.setLayout(new FlowLayout()); for (int x=0;x<sliders.length;x++) { add(textLabels[x]); add(textFields[x]); add(sliders[x]); add(resultColor); add(colorButton); add(ohje); } } //Attributes private static JSlider[] sliders = new JSlider[3]; private static JLabel[] textLabels = new JLabel[3]; private static JTextField resultColor = new JTextField("Result Color #hex"); private static JTextField[] textFields = new JTextField[3]; private JButton colorButton = new JButton(""); private JLabel ohje = new JLabel(); //main -method public static void main(String[] args) { new HTMLColorChooser().setVisible(true); } //Overriding interfaces for listeners @Override public void stateChanged(ChangeEvent e) { int valueR = sliders[0].getValue(),valueG=sliders[1].getValue(),valueB = sliders[2].getValue(); textFields[0].setText("" +valueR); textFields[1].setText("" +valueG); textFields[2].setText("" +valueB); String hexR = Integer.toHexString(valueR); String hexG = Integer.toHexString(valueG); String hexB = Integer.toHexString(valueB); String hex = hexR + hexG + hexB; resultColor.setText("#"+hex); colorButton.setBackground(new Color(sliders[0].getValue(),sliders[1].getValue(),sliders[2].getValue())); } @Override public void actionPerformed(ActionEvent e) { int valueR = sliders[0].getValue(),valueG=sliders[1].getValue(),valueB = sliders[2].getValue(); String hexR = Integer.toHexString(valueR); String hexG = Integer.toHexString(valueG); String hexB = Integer.toHexString(valueB); String hex = "#"+hexR + hexG + hexB; // TODO Auto-generated method stub Toolkit.getDefaultToolkit() .getSystemClipboard() .setContents( new StringSelection(hex), null ); } }
Tässä vertailun ja huvin vuoksi 8th:lla kirjoiteltu Nuklear pohjaisella käyttöliittymällä toteutettu vastaavan toiminnallisuuden toteuttava ohjelma.
needs nk/gui needs nk/widgets needs nk/sliders 22 font:system font:new "font1" font:atlas! drop : hexcolor? \ -- s ["red", "green", "blue"] nk:get "#%02x%02x%02x" s:strfmt ; : color? -- a ["red", "green", "blue"] nk:get 255 a:push ; : new-win { name: "main", title: "HTML Color Picker", wide: 440, high: 200, resizable: false, bg: "white" } nk:win ; : main-render { bg: "white", flags: [ @nk:WINDOW_NO_SCROLLBAR ], padding: [4,4], red: 0, green: 0, blue: 0 } nk:begin null { margin: 4, rows: [32, 32, 32, 8, 32], cols: [0.15, 0.4, 0.15, 0.3], cgap: 8, rgap: 8 } nk:layout-grid-begin \ Red 0 1 0 1 nk:grid nk:rect>local nk:grid-push "Red:" nk:TEXT_LEFT "black" nk:label-colored 0 1 1 1 nk:grid nk:rect>local nk:grid-push 0 255 1 "red" nk:slider-int 0 1 2 1 nk:grid dup 1 2 "black" nk:stroke-rect nk:rect>local nk:grid-push "red" nk:get >s nk:TEXT_CENTERED "black" nk:label-colored \ Green 1 1 0 1 nk:grid nk:rect>local nk:grid-push "Green:" nk:TEXT_LEFT "black" nk:label-colored 1 1 1 1 nk:grid nk:rect>local nk:grid-push 0 255 1 "green" nk:slider-int 1 1 2 1 nk:grid dup 1 2 "black" nk:stroke-rect nk:rect>local nk:grid-push "green" nk:get >s nk:TEXT_CENTERED "black" nk:label-colored \ Blue 2 1 0 1 nk:grid nk:rect>local nk:grid-push "Blue:" nk:TEXT_LEFT "black" nk:label-colored 2 1 1 1 nk:grid nk:rect>local nk:grid-push 0 255 1 "blue" nk:slider-int 2 1 2 1 nk:grid dup 1 2 "black" nk:stroke-rect nk:rect>local nk:grid-push "blue" nk:get >s nk:TEXT_CENTERED "black" nk:label-colored \ Color rect 0 3 3 1 nk:grid 8 nk:rect-shrink dup 1 color? nk:fill-rect 1 2 "black" nk:stroke-rect \ Hex color 4 1 3 1 nk:grid dup 1 2 "black" nk:stroke-rect nk:rect>local nk:grid-push hexcolor? 8 nk:EDIT_FIELD nk:PLUGIN_FILTER_DEFAULT nk:edit-string 2drop nk:layout-grid-end nk:end ; : app:main new-win ' main-render -1 nk:render-loop ;
Tässä jonkinlainen esitys HTML5/Javascript, vaikka voisi olla aiheellista tyyliarkki-muotoilulla CSS3-laatien jos tuo palkit vaihtaisi väriä aina sen mukaan, ja sitten pitäisi olla jokin demoruutu, että käyttäjä näkisi valmiin värin ennen napin klikkausta, josta saa sitten hexana ja suluissa valitut arvot
Koodini HTML5/Javascript:illä, vaatii vielä tuunausta ja CSS3-arkin muotoilua
<!DOCTYPE html> <html> <head><title>HTML - color -picker</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <h1>HTML - color -picker </h1> <form> <input type="range" min="0" max="255" value="50" class="slider" id="redRange"><p>Red Value: <span id="redSV"></span></p> <br> <input type="range" min="0" max="255" value="50" class="slider" id="greenRange"><p>Green Value: <span id="greenSV"></span></p> <br> <input type="range" min="0" max="255" value="50" class="slider" id="blueRange"><p>Blue Value: <span id="blueSV"></span></p> <button onclick="aja()">Color - pick!</button> </form> <p id="demo">Current color: Hello hairy world!</p> <script> //toHex function toHex(rgb) { var hex = Number(rgb).toString(16); if (hex.length < 2) { hex = "0" + hex; } return hex; }; //Variables from form var outputR = document.getElementById("redSV"); var outputG = document.getElementById("greenSV"); var outputB = document.getElementById("blueSV"); redRange.oninput = function() { outputR.innerHTML = this.value; } greenRange.oninput = function() { outputG.innerHTML = this.value; } blueRange.oninput = function() { outputB.innerHTML = this.value; } //function to run function aja() { var sliderR = document.getElementById("redRange"); var sliderG = document.getElementById("greenRange"); var sliderB = document.getElementById("blueRange"); var rHex = toHex(sliderR.value); var gHex = toHex(sliderG.value); var bHex = toHex(sliderB.value); var full = rHex+gHex+bHex; alert('#' +full +' (R:'+sliderR.value+', G:'+sliderG.value +', B:'+ sliderB.value+')'); }; </script> </body> </html>
Jos muuttaisi tuon HTML-lomakkeen tälläiseksi:
<form> <input type="range" min="0" max="255" value="50" class="slider" id="redRange" onchange="aja()"><p>Red Value: <span id="redSV"></span></p> <br> <input type="range" min="0" max="255" value="50" class="slider" id="greenRange" onchange="aja()"><p>Green Value: <span id="greenSV"></span></p> <br> <input type="range" min="0" max="255" value="50" class="slider" id="blueRange" onchange="aja()"><p>Blue Value: <span id="blueSV"></span></p> <br> Output: <input type="text" name="outputDemo" value="Lorem ipsum"> </form>
pitäisi tuon demonstraatio-tekstikentän väri muuttaa taustaväri sellaiseksi, jonka käyttäjä valitsee, ja sitten mitenkäs tuo mikä vastavärillä sitten teksti, tai akateemisen logiikan kautta negaatio tuosta valitusta väristä, vai onko se mirror colour, peiliväri, vastaväri se on, niin sitten voisi tulostaa napin painamisen jälkeen tekstin värin ja taustavärin heksana ruudulle sen lisäksi, että reaaliajassa muuttuu tuo lorem ipsumin tekstiväri taustavärin vastaväriksi ja kyseisen tekstikentän taustavärit.
Voisi tänään ottaa asiakasi valmistaa tämä ohjelma valmiiksi, ja julkaista kotisivuillani tämän HTML-värivalitsimen, että voisi selaimessa suoraan saada nuo arvot, niin ei tarvitse tuota Java-ohjelmaa välttämättä ladata, kun tänään olen taas moneen päivään selvin päin eneimmäistä päivää, illemmalla voisi kuluttaa tämän ohjelmointiin aikaa.
Mitenkä ajattelit toteuttaa settings puolen jottei tarvitse säädellä joka kerta uudestaan?
No tässä jonkinlainen ratkaisu, miten olisi onload -funktiolla tuossa ennen onchangea. Tämä vastaväri tuotti hieman päävaivaa, mutta tässä lopullinen koodi.
<!DOCTYPE html> <html> <head><title>HTML - color -picker</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <h1>HTML - color -picker </h1> <form> <input type="range" min="0" max="255" value="50" class="slider" id="redRange" onload="current()" onchange="aja()"><p>Red Value: <span id="redSV"></span></p> <br> <input type="range" min="0" max="255" value="50" class="slider" id="greenRange" onload="current()" onchange="aja()"><p>Green Value: <span id="greenSV"></span></p> <br> <input type="range" min="0" max="255" value="50" class="slider" id="blueRange" onload="current()" onchange="aja()"><p>Blue Value: <span id="blueSV"></span></p> <br> Output: <input type="text" id="demo" name="outputDemo" value="Lorem ipsum"> </form> <br> <p id="rgb"> <br> <p id="hexD"> <br> <p id="oppC"> <script> //toHex function toHex(rgb) { var hex = Number(rgb).toString(16); if (hex.length < 2) { hex = "0" + hex; } return hex; }; function invertColor(hex) { if (hex.indexOf('#') === 0) { hex = hex.slice(1); } // convert 3-digit hex to 6-digits. if (hex.length === 3) { hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]; } if (hex.length !== 6) { throw new Error('Invalid HEX color.'); } // invert color components var r = (255 - parseInt(hex.slice(0, 2), 16)).toString(16), g = (255 - parseInt(hex.slice(2, 4), 16)).toString(16), b = (255 - parseInt(hex.slice(4, 6), 16)).toString(16); // pad each with zeros and return return '#' + padZero(r) + padZero(g) + padZero(b); } function padZero(str, len) { len = len || 2; var zeros = new Array(len).join('0'); return (zeros + str).slice(-len); } //Variables from form var outputR = document.getElementById("redSV"); var outputG = document.getElementById("greenSV"); var outputB = document.getElementById("blueSV"); function currentValue() { document.getElementById("redRange").innerHTML =outputR.value; } redRange.oninput = function() { outputR.innerHTML = this.value; } greenRange.oninput = function() { outputG.innerHTML = this.value; } blueRange.oninput = function() { outputB.innerHTML = this.value; } //function to run function aja() { var sliderR = document.getElementById("redRange"); var sliderG = document.getElementById("greenRange"); var sliderB = document.getElementById("blueRange"); var whiteC = toHex(0)+toHex(0)+toHex(0); var rHex = toHex(sliderR.value); var gHex = toHex(sliderG.value); var bHex = toHex(sliderB.value); var full = rHex+gHex+bHex; var oppR = invertColor(full); document.getElementById("demo").style.backgroundColor = '#'+full; document.getElementById("demo").style.color = oppR; document.getElementById("rgb").innerHTML = 'RGB-code:(' +'R:'+sliderR.value+', G:'+sliderG.value +', B:'+ sliderB.value+')'; document.getElementById("hexD").innerHTML = 'Hex-Code: ' +'#' +full; document.getElementById("oppC").innerHTML = 'Oppsite color: ' + oppR; //alert('#' +full +' (R:'+sliderR.value+', G:'+sliderG.value +', B:'+ sliderB.value+')'); }; </script> </body> </html>
Nyt ei oikein selvinnyt; vastasitko itsellesi vai kenelle?
Vai meinasitko, että hoitelet asetus asiat (GetSettings/SaveSettings) onload tapahtumassa???
En tiedä asetuksista, mutta julkaisin edes jotenkin toimivan verkkoselaimella toimivan sovelluksen kotisivuillani ja tässä on suora linkki.
Hyvin toimii väsäämäsi värivalitsin. Mutta mitä hyötyä moisesta viritelmästä on mahdolliselle käyttäjälle mikäli asetuksia ei voi tallentaa, kun niitä muutetaan eikä siis tallennettuja asetuksia noutaa kun sivu ladataan? Olisi varsin mielekästä ettei mieleisiään väriasetuksia tarvitsisi säätää joka kerta uudestaan.
Tsekkaa tämä
http://diveintohtml5.info/storage.html
neosofta kirjoitti:
(17.11.2021 18:46:27): Hyvin toimii väsäämäsi värivalitsin. Mutta...
Kiitos linkkivinkistä! On mulla tohon kehitysideoita vielä, radio-buttonitkin voisi lisätä, että käyttäjä saa valita, valitseeko taustavärin, vai bodyn tekstivärin, ja sitten sen mukaan, kumman on valinnut niistä radiobuttoneista, niin ohjelma tekee sitten sen mukaan.
Tuo asetuksien tallentaminen mulle uutta, mutta tänään keskityn Lars Keplerin Hypnotisoija-romaanin lukemiseen illalla, joten loppuviikon aikana voisi tutustua tuohon tarjoamaasi dokumentti-lähteeseen ja ottaa haltuun uutta.
Oli vähän JavaScript -haussa, kun paljoa sitä tullut käytettyä www-ohjelmointikurssin jälkeen, jonka suoritin 2016 loka/marraskuussa, mutta pistin nyt vielä obfuscaattorin läpi tuon JavaScript-koodin, vaikka koodissa nyt mitään salaista olekaan, eikä kyseisellä ohjelmalla tuskin kukaan mitään rahaa pystyy tekemään, ainakaan itse keksi, mihin tuota voisi myydä, ei mihinkään, niin olkoon nyt sitten tuolla ilmaiseksi saatavilla.
Aika yksinkertaiselta vaikuttaa tuo localStorage, tai session, mutta localStoragea kannattee käyttää istunnon sijaan, eikä mitään arkaluonteista dataa kannata turvallisuusyistä tallentaa tuohon paikalliseen muistiin.
Jotenkin en tajua, miten käytännössä mihin kohtaan, tai järjestyksessä pitäisi lisätä tuo setItem, ja sitten se objektin nouto getItemillä, tässä nyt aja() -metodini, mitä kutsutaan tuolla kun käyttäjä tekee jonkin muutoksen noihin värivalintoihin jostain noista slideristä.
function aja() { if (typeof(Storage) !== "undefined") { localStorage.setItem('red', document.getElementById("redRange").value); localStorage.setItem('green',document.getElementById("greenRange").value); localStorage.setItem('blue', document.getElementById("blueRange").value); } var rHex = toHex(localStorage.getItem('red')); var gHex = toHex(localStorage.getItem('green')); var bHex = toHex(localStorage.getItem('blue')); var full = rHex+gHex+bHex; var oppR = invertColor(full); var pick = document.querySelector('input[name="userColorPick"]:checked').value; if (pick =="Background") { document.getElementById("demo").style.backgroundColor = '#'+full; document.getElementById("demo").style.color = oppR; document.getElementById("rgb").innerHTML = 'RGB-code:(' +'R:'+sliderR.value+', G:'+sliderG.value +', B:'+ sliderB.value+')'; document.getElementById("hexD").innerHTML = 'Hex-Code: ' +'#' +full; document.getElementById("oppC").innerHTML = 'Opposite color: ' + oppR; } if (pick == "Text") { document.getElementById("demo").style.backgroundColor = oppR; document.getElementById("demo").style.color = '#'+full; document.getElementById("rgb").innerHTML = 'RGB-code:(' +'R:'+sliderR.value+', G:'+sliderG.value +', B:'+ sliderB.value+')'; document.getElementById("hexD").innerHTML = 'Hex-Code: ' +oppR; document.getElementById("oppC").innerHTML = 'Opposite color: ' + full; } };
Jotenkin hämärää, kun kokeilin alert():illa, niin saan tallennettua käyttäjän valitsemat arvot localStorage-olion setItem -metodikutsulla, mutta sitten kun kokeilin, että latasin verkkoselaimella jonkin URL-resurssin, esimerkiksi tämän OHjelmointiputkan keskustelun, ja palaan ohjelmaani selaimen "Edellinen sivu" -painikkeella, niin siinä kohtaa taas arvot ovat alkutekijöissaan, vaikka tuossa localStoragessa tiedot on pysyviä pitäisi olla, vaikkakin paikallisesti tallennetut tiedot ovat domain-kohtaisia. Toisin kuin tuossa storageSessionissa.
Ehkä yritän väärässä paikkaa palauttaa noita tietoja, tuo let -avainsana oli ratkaiseva tuohon datan palautukseen. Ehkä pitäisi tuonne html-pohjaan lisätä noiden liukuimien slidereittein tagiin onload -parametri, ja ohjelmoida funktio "loadSettings", niin vaikka value-arvossa on HTML-dokumentissa 0 se lähtöarvo kaikissa noissa, mutta jos siinä kohtaa, kun selain lataa tuon sliderin, niin tuolta loadSettings -dokumentista arvo muutetaan tietokoneen muistissa oleviin arvoihin.
Siinä vain se porsaanreikä, tai bugi, että ohjelma pitäisi vähintään kerran ajaa, koska tallennus tapahtuu ensimmäisen ajokerran jälkeen.
Mitä tuossa hakukoneellakin katsoin, mitä sieltä löytyy tuosta HTML5 Javascript storageSessionista, ja luin nuo sinun neosofta linkkaamasi lähteet, niin ei tuo nyt mitään rakettitieteilijän tutkintoa vaadi, että ymmärtää tuon periaatteen ja käytön.
Kyllä vielä tämän viikonlopun aikana runnon ohjelman toimintakuntoon ja julkaisen sen sitten kun se toimii. Samalla päivitän tuon kirjoitusvirheen tuossa opposite color, kun välistä puuttuu yksi o, mutta tuo nyt ei liity tekniikan toimimattomuuteen.
pistän nyt tänne esille vähän koodia tästä, jos joku osaisi auttaa eteenpäin, kun yritin tuota HTML-dokumentin muokkausta, ja ohjelmoin tuon loadSettings() -funktion, mutta ei vain toimi, aina palautuu arvot alku-nollaan.
Tässä nyt .html -tiedostoni
<!DOCTYPE html> <html> <head><title>HTML - color -picker</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body id="demo"> <h1>HTML - color -picker </h1> <p>Choose your Red, Green and Blue values and this page body shows you results in run and gives a hex values for colours.</p> <form> <br> <input type="radio" name="userColorPick" value="Background" checked onchange="aja()">Background</input> <br> <input type="radio" name="userColorPick" value="Text" onchange="aja()">Text</input> <br> <input type="range" min="0" max="255" value="loadSettings()" class="slider" id="redRange" onchange="loadSettings()"><p>Red Value: <span id="redSV"></span></p> <br> <input type="range" min="0" max="255" value="loadSettings()" class="slider" id="greenRange" onchange="loadSettings()"><p>Green Value: <span id="greenSV"></span></p> <br> <input type="range" min="0" max="255" value="loadSettings()" class="slider" id="blueRange" onchange="loadSettings()"><p>Blue Value: <span id="blueSV"></span></p> </form> <br> <p id="rgb"> <br> <p id="hexD"> <br> <p id="oppC"> <hr size="2"> published 17.11.2021 <script src="htmlcolorpicker.js"></script> </body> </html>
Tässä sitten osa tuosta scriptistäni, globaalisti nuo muuttujat ilman, että minkään funktion sisällä ole, niin nuo arvot näkyviin, ja samalla myös tuo localStorage.setItem -tallennus. ja loadSettings() sekä aja() -funktiot
//Variables from form document.getElementById("redSV").innerHTML = document.getElementById("redRange").value; localStorage.setItem('redS',document.getElementById("redRange").value); document.getElementById("greenSV").innerHTML = document.getElementById("greenRange").value; localStorage.setItem('greeN',document.getElementById("greenRange").value); document.getElementById("blueSV").innerHTML = document.getElementById("blueRange").value; localStorage.setItem('bluE',document.getElementById("blueRange").value); //function to run function loadSettings() { if (typeof(Storage) !== "undefined") { let red =localStorage.getItem(redS); let green =localStorage.getItem(greeN); let blue =localStorage.getItem(bluE); document.getElementById("redSV").innerHTML = red; document.getElementById("greenSV").innerHTML = green; document.getElementById("blueSV").innerHTML = blue; aja(); } } function aja() { var red = document.getElementById("redRange").value; var green = document.getElementById("greenRange").value; var blue = document.getElementById("blueRange").value; var rHex = toHex(red); var gHex = toHex(green); var bHex = toHex(blue); var full = rHex+gHex+bHex; var oppR = invertColor(full); var pick = document.querySelector('input[name="userColorPick"]:checked').value; if (pick ==="Background"){ document.getElementById("demo").style.backgroundColor = '#'+full; document.getElementById("demo").style.color = oppR; document.getElementById("rgb").innerHTML = 'RGB-code:(' +'R:'+red+', G:'+green +', B:'+ blue+')'; document.getElementById("hexD").innerHTML = 'Hex-Code: ' +'#' +full; document.getElementById("oppC").innerHTML = 'Opposite color: ' + oppR; } if (pick === "Text") { document.getElementById("demo").style.backgroundColor = oppR; document.getElementById("demo").style.color = '#'+full; document.getElementById("rgb").innerHTML = 'RGB-code:(' +'R:'+red+', G:'+green +', B:'+ blue+')'; document.getElementById("hexD").innerHTML = 'Hex-Code: ' +oppR; document.getElementById("oppC").innerHTML = 'Opposite color: #' + full; } };
Voi olla, että tuossa html-dokumentissani on useassakin paikassa ylimääräisiä parametreja noissa hilavitkuttimissa tuolla lomakkeen sisällä tai vääriä parametreja, mutta uskoakseni ratkaisu ei liene liian kaukana tästä. Kyllä nyt varmaan vielä huomiseen sunnuntain iltaan mennessä äkkään tämän, jollen aiemminkin, jos joku nyt osaa auttaa tai antaa ratkaisevan vihjeen.
Voi olla noissa muuttujien näkyvyydessäkin jotain häikkää, että siitä syystä ei toimi, kun aika paljon samankaltaisen nimen omaavia muuttujia, niin jos kaikki noi väriasetteluun liittyvät muuttujat määrittelisi globaaleiksi muuttujiksi, niin ainakin koodin luettavuus voisi selkeytyä. Senkin voisi selvittää selaimessa debuggaamalla tämän ohjelman.
Yksi asia, minkä tajusin alkuvaiheessa jo Javascriptillä ohjelmoinnissa aikanaan, kun tutustuin syvemmälle tässä kielessä, niin Javascriptin ohjelmakoodin ylläpitämisestä voi tulla aika painajaista, jos ylläpidettävä tai koodi, jota pitäisi hallinnoida, niin on laaja, ja etenkin, jos muuttujia ja samankaltaisen nimen omaavia muuttujia on paljon, niin siinä alkaa pitkässä juoksussa kärsimään mielenterveysongelmista helposti. No, ei tämä ohjelma nyt mikään laaja ole, vähän voisi tosin selkiyttää tuota muuttujien määrittelyä ja niiden näkyvyyttä.
Olisikohan oheisessa mitään logiikkaa:
function checkMySettings(key, value) // * jos käytät taulukkoparametreja { if (typeof(Storage) !== "undefined") { // * voit pukata luupissa if(window.localStorage.getItem(key) === "undefined" || window.localStorage.getItem(key) === null) { window.localStorage.setItem(key, value); } else { if(value !== window.localStorage.getItem(key)) { // valmis update toiminto window.localStorage.setItem(key, value); } } } else { alert('Selaimesi ei tue Storage objektia'); } }
Joskus tää kulkee kännissä ihan kivasti, mutta nyt meinaa tökkiä...
Vois tulla tosiaan vähän siistmpää koodia, jos käyttäisi noissa avain-arvo-pareissa taulukkomuuttujia.
luuppaus ihan hyvä idea for-silmukassa käydä ne läpi.
Tuossa else-lohkossa jos käyttäjän selain ei tue noita Storage-objekteja, niin ohjelma voisi toimia samalla tavalla, mitä nykyisin, että sitä kuitenkin pystyy käyttämään, vaikka selain ei tukisikaan, niin sitten saavuttaa 100% selainyhteensopivuuden. Mitä katsoin tuota selainyhteensopivuustaulukkoa, niin kyllä moderneista selaimista aika hyvä tuki jo löytyykin, ja loput selaimista varmaan tulevissa selainpäivitysversioissakin alkaa tukemaan.
Tuossahan dokumentissa, minkä jaoit aiemmin ohjeistuksena, niin kerrottiin, että mitään kovin kriittisesti salaista tietoa kannata tallentaa muistiin, insecure, mutta tämä väri-kokonaistyyppi muuttuja nyt mitään sellaista tietoa olekaan, että sen voi kyllä tallentaa.
Sellainen huomio muuten, että tämä localStorage ja sessionStorage rinnastetaan vissiin evästeisiin, että jos tekee tietosuojapolitiikan sivuille, mitä ei nyt tässä tapauksessa, kun toimin puhtaasti epäkaupallisin tarkoitusperin, niin tarvitse laatia, mutta monella yrityksellä noissa verkkopalveluiden tietosuojaselosteissa mainittu, jos sivusto käyttää perinteisten cookies, evästeiden sijaan tai lisäksi tätä localStoragea, tuollainen tuli vastaan, kun katselin suomen kielelläkin hakukoneelta tästä aiheesta.
Taitaa mennä yömyöhäksi tämän ohjelman viimeistely. Maanantaina tulee takuueläke tilille, joka tietää perinteisesti vapaapäivää tietokoneharrastuksesta poislukien ehkä rahapeliviihde, niin selvin päin itse olen tämän viikonlopun nyt ollut, sitten maanantaina voi hyvin mielin hakea sen pullon kirkasta pitkäripaisesta, kun nyt tämän ohjelma-casen saisi loppuunkäsitellyksi ihan julkaisuun saakka.
Voin mainita kiitoksena crediteissä "Ohjelmointiputka-aktiivi neosoftan" viitaten apuun tässä tiedon paikallisessa tallennuskoodissa.
lisäsin silmukkarakenteeseen tuon checkMySettings(key,value), jossa käytän syöteparametreina kolmialkioisia taulukoita.
function checkMySettings(key, value) // * jos käytät taulukkoparametreja { if (typeof(Storage) !== "undefined") { // * voit pukata luupissa for (let i = 0; i < key.length; i++) { if(window.localStorage.getItem(key[i]) === "undefined" || window.localStorage.getItem(key[i]) === null) { window.localStorage.setItem(key[i], value[i]); } else { if(value !== window.localStorage.getItem(key[i])) { // valmis update toiminto window.localStorage.setItem(key[i], value[i]); } } } } else { alert('Selaimesi ei tue Storage objektia'); } }
Mutta sitten taas en tajua, sama ongelma, mikä oli aiemminkin tänään, että en tiedä, missä kohtaa kutsua metodia, kaikki nuo on muutosliipasimia tuolla html-dokumentissa, jossa sitten käyttäjän muuttaessa arvoa, aja() -metodia kutsutaan, ja nyt se näyttää tältä:
//function to run function aja() { const key = ["red","green","blue"]; const value = [parseInt(document.getElementById("redRange").value),parseInt(document.getElementById("greenRange").value), parseInt(document.getElementById("blueRange").value)]; checkMySettings(key,value); let r = localStorage.getItem("red"); let g = localStorage.getItem("green"); let b = localStorage.getItem("blue"); document.getElementById("redSV").innerHTML = r; document.getElementById("greenSV").innerHTML = g; document.getElementById("blueSV").innerHTML = b; var rHex = this.toHex(r); var gHex = this.toHex(g); var bHex = this.toHex(b); var full = '#' +rHex+gHex+bHex; var opposite = this.invertColor(full); pick = document.querySelector('input[name="userColorPick"]:checked').value; if (pick ==="Background"){ document.getElementById("demo").style.backgroundColor = full; document.getElementById("demo").style.color = opposite; document.getElementById("rgb").innerHTML = 'RGB-code:(' +'R:'+r+', G:'+g +', B:'+ b+')'; document.getElementById("hexD").innerHTML = 'Hex-Code: ' +'#' +full; document.getElementById("oppC").innerHTML = 'Opposite color: ' + opposite; } if (pick === "Text") { document.getElementById("demo").style.backgroundColor = opposite; document.getElementById("demo").style.color = full; document.getElementById("rgb").innerHTML = 'RGB-code:(' +'R:'+r+', G:'+g +', B:'+ b+')'; document.getElementById("hexD").innerHTML = 'Hex-Code: ' +opposite; document.getElementById("oppC").innerHTML = 'Opposite color: #' + full; } };
Yleensä näin vaikeaa jonkin koodirivin järjestyksen johtopäätelmän teko ollut, mihin kohtaa ohjelmaa sijoittaisi tuon asetusten tarkistusmetodin, että sitten selain muistaisi käyttäjän tai ohjelmaan palaavan asiakkaan edelliset arvot säilyisivät noissa liukuimissa.
Jere Sumell kirjoitti:
Yleensä näin vaikeaa jonkin koodirivin järjestyksen johtopäätelmän teko ollut, mihin kohtaa ohjelmaa sijoittaisi tuon asetusten tarkistusmetodin, että sitten selain muistaisi käyttäjän tai ohjelmaan palaavan asiakkaan edelliset arvot säilyisivät noissa liukuimissa.
Jotenkin tuntuu, että teet asiasta vaikeamman kuin tarvitsisi, mihin tarvitaan checkMySettings() funktiota?
Mikset vaan aina käytä localStorage objektia tietojen tallentamiseen ja lukemiseen? Eikös JavaScriptillä voi käyttää ternary operaattoria asettamaan näppärästi oletusarvo, jos kyseisellä avaimella ei ole mitään vielä tallennettuna?
Neosofta tuon checkMySettings() -metodin esitti ensin, niin täydensin lauantai-illan vieton tiimellyksessä siihen tuon iteroinnin. Voihan tuollekin metodille jotain käyttöä jossain tilanteessa olla, mutta hienoa, että otit osaa keskusteluun "jalski", on totta, että ei käynyt ihan mielessä, vaikka JavaScriptissäkin on tuo ternary operaattori, kun Javassa olen joskus käyttänyt sitä, mutta vähemmän, voisin tosiaan kokeilla sitä, kun mainitsit sen, ja /* -kommentointitagien väliin vaikka tuon asetusten tarkistusfunktion.
Loggaan itseni ulos nyt täältä putkasta, ja katson koodia vielä, palaan asiaan viimeistään huomenna sunnuntaina aamulla tai myöhemmin tänään.
Hyvä pistää kaikki känniläisen piikkiin 🎅, mutta väännetään nyt sitten yksinkertaistettu malli rautalangasta:
skeidaa.html
<html> <head> <title>Skeidaa</title> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta charset="UTF-8"/> <script src="http://code.jquery.com/jquery-latest.min.js"></script> <script src="skeidaa.js"></script> </head> <body> <div class="slidecontainer"> <input type="range" min="1" max="100" value="50" class="slider" id="myRange" onchange="setMySettings(this.id,this.value)"> </div> </body> </html>
skeidaa.js
/* DWYFW LICENCE (Do Whatever You Fucking Want) */ $(document).ready(function () { getMySettings('myRange'); }); function getMySettings(key) { if (typeof(Storage) !== "undefined") { if(window.localStorage.getItem(key) !== "undefined" && window.localStorage.getItem(key) !== null) { document.getElementById(key).setAttribute('value', window.localStorage.getItem(key)); } else { window.localStorage.setItem(key, document.getElementById(key).getAttribute('value')); } } else { document.body.innerHTML = "<p align='center'>Selaimesi ei tue Storage objektia, värisäädöt eivät tallennu</p>" + document.body.innerHTML; } } function setMySettings(key, value) { if (typeof(Storage) !== "undefined") { window.localStorage.setItem(key, value); } } // Tänne voi sitten aivan itsekseen lisätä funktion,jolla värit // oikeasti muutetaan ja pohtia mihin väliin lykätä funktiokutsu(t) // (iterointi hoituu kätevästi $(document).ready funktion sisällä)
Toivottavasti koette valaistumisen
P.S. Oksensin 🤢
Aamulla, kun katsoin koodiasi eiliseltä illalta, taisi vielä olla jotain <center> -asemointitageja skeida-hooteemmällässäsi ja piittui tuo html5 doctype määrittely tuolta alusta muistaakseni.
Viinanhuuruisen putkaillan jälkeen, kun koodin jälkeen kerroit oksentaneesi, kiva, kun palasit korjaamaan vähän nykyaikaisempaan muotoon, vaikka HTML5-standardikaan vielä ole tälläkään hetkellä taida olla ihan lopullisesti valmistunut, nykyään enää olitko alunperin oksentanut sen takia, kun vaikutti joltain HTML3 -versiolta tuo esityksesi. Nykyään enää harvoin törmää edes nelosversion html-esitysdokumenttiin 2021, vaikka joskus tietenkin vanhentunuttakin tekniikkaa tulee vielä jostain syystä vastaan.
Noita <div align="center-left-right"> ei enää HTML5-määrittelyssä ole, nelosessa ne taisi vielä olla. <table>:lle on jotain käyttöä vielä nykyäänkin, vaikka enää ei olla aikoihin verkkosivujen asemointia hoidettu, kuten joskus 1990-luvun lopun world wide west -hulluina vuosina varmaan joka toinen vähintään sivuista oli täynnä tuolla taulukko-menetelmällä laadittuja esityksiä. Nykyään hoidetaan ne tyylikkäästi CSS3-tyyliarkissa, jossa siinäkin saa suhteutettua prosentteja käyttäen sijainnin asiakkaan näyttöpäätteen mukaan oikeissa mittasuhteissa näkyväksi, kuten varmaan hyvin tiedät.
Alkeellisin HTML-versio -esitys, johon olen törmännyt, mikä sijaitsee yhä world wide webissa julkisesti, jos olette käyneet Helsingin Yliopiston palvelimella sijaitsevalla tietojenkäsittelytieteen kunniatohtori Linus Torvaldsin käyntikorttia katsomassa. Se on varmaan jotain HTML1:stä, ja varmaan ssh-pääteyhteydellä ohjelmoitu vi-editorilla vartissa sinne. Tosin kyseisen sivuston informatiivisuus on niin hyvää tasoa, että ehkä se nyt Linuksen kaltaiselle kulta-aivot omaavalle tietokoneinsinöörille annetaan anteeksi, että ihan priimaa ei joka tekniikan osalta tarvitse hyödyntää edes julkisissa dokumenteissa ja esityksissä.
Tekniikka niin pitkälle vielä kehittynyt, että keskustelupalstoille saisi jonkinlaisen alkometri-liitännäisen asennettua, joka ottaisi promillelukemat koneelle datana tietokoneeseen asennetun alkometrin ja anturin avulla, ja sitten esimerkiksi keskustelupalstan moderaattorit ja ylläpitäjät voisivat liitännäisen asetuksista säätää promillerajan, jolloin sen ylittyessä kirjoitusoikeus evättäisiin kunnes foorumin jäsen on taas kirjoituskunnossa. Varmaan Facebook olisi kiinnostunut myös ostamaan tällaisen järjestelmän.
No, leikki leikkinä, kiitos neosofta, kyllä annan sinulle creditit suuresta avustasi, vaikka en ole vielä modifioinut ja implementoinut esitystäsi toimintakuntoon toimimaan omassa sovelluksessani. Sunnuntai-ilta on vielä nuori.
Nyt sain kuntoon ohjelmani!
Tässä vielä suora linkki, vaikka kerran tuli jo mainittua.
Nyt ei liene enää mitään kehiteltävää tuossa, tämän casen voi sulkea tähän, kun sain tuon toimimaan tuon värivalintojen tallenuksen ja palauttamisen.
Käytin lopulta tuota neosoftan sinun eilen lauantaina esittämääsi jQuery/JavaScript -esitystäsi lisäten tuon silmukan tuonne ready() -funktioon.
Laitoin sivun alalaitaan sanallisen suuren kiitokseni neosofta -nimimerkille tänne Ohjelmointiputkan keskusteluaktiiville ja kaverille, kun olit suureksi avuksi, kun esittelit minulle tuon HTML5:n tukeman Storage -objektit.
Ei kaikki nyt sentään ihan niin yksinkertaista ole, kuin luulisi - taisi unohtua toi värien takaisinhaku jos vaikka päivittää sivun. Elikä onchange event ei siis laukea (fire) jos arvo muutetaan koodista käsin.
TROUBLESHOOTING:
Huomasin, että ulkoiselta palvelimelta ladattaessa säädinskeida toimi IE11 perusasetuksilla kun klikkasi OK:ta alalaitaan ilmestyvässä Näytä koko sisältö - laatikossa. Edge ei suostunut ulkoiselta palvelimelta ladattaessa suorittamaan $(document).ready() funktiota (3rd party script) millään asetuksilla vaikka sallin asetuksissa melkeinpä kaiken mahdollisen paskan. Latasin sitten viimein selaimella koko http://code.jquery.com/jquery-latest.min.js tiedoston koneelleni, pukkasin tiedoston serverille ja muutin HTML skeidan rivin:
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
muotoon:
<script src="jquery-latest.min.js"></script>
ja nyt homma pelittää aivan mahtavasti Edgessä, IE11:sta (IE ei kysele enää perusasetuksilla mitään) sekä Chromessa (systerin). Muita selaimia en aio edes testata.
neosofta kirjoitti:
pelittää aivan mahtavasti Edgessä, IE11:sta
Skeidauksen MM-kisat 🍿 👏 🥇
🎅 Saisikohan pelkästään noi emojit säädettyä ruskeiksi tolla Jere Sumell'in värivirityksellä?
neosofta kirjoitti:
Ei kaikki nyt sentään ihan niin yksinkertaista ole, kuin luulisi - taisi unohtua toi värien takaisinhaku jos vaikka päivittää sivun. Elikä onchange event ei siis laukea (fire) jos arvo muutetaan koodista käsin.
Joo, pitää ohjelmoida eventlistener -metodi.
Totakaan en saanut toimimaan, kun kokeilin sivuslta poistumista jQuerylla, ni
window.onbeforeunload = function(){ //Tähän kohtaan muuttujien tallentaminen localStorage.setItem() -metodilla };
Mäkin join tänään mäyräkoiran olutta, mut en oo humalassa kirjoittanut tänne, enkä ohjelmoniut kännissä tota värivalitsin-härpäkettä lainkaan, mut tuossa voisi olla jotain teknologia-start-up -yritysideaa tuossa alkometriliitännäisessä näille keskustelupalstojen ylläpitäjille. Pitäisi vain ensin valmistaa prototyyppi, jotta sitten on jotain konkreettista esittää, kun lähtee pitämään myyntipuhetta pääomasijoittajille rahoitusmarkkinoilla sen bisneksen osalta.
Voisi olla aika lailla turhaa "kuunnella" jotain eventtiä, jos sitä ei liipaista ja tässä tapauksessa myöskin silloin kun se manuaalisesti liipaistaan. Eli miksi ihmeessä vääntää yksinkertainen ja toimiva monelle mutkalle.
Eli siis vielä kerran rautalankaa:
//non_rocket_science.js $(document).ready(function () { getMySettings('myRange'); }); function getMySettings(key) { // jos Storage on tuettu... if (typeof(Storage) !== "undefined") { // ja localStorage objektiin on asetettu // key parametria vastaava avain/arvo pari if(window.localStorage.getItem(key) !== "undefined" && window.localStorage.getItem(key) !== null) { // haetaan tallennettu arvo ja asetetan ko. elementin value parametrin arvoksi. // *** HUOM tämä ei liipaise elementin onchange tapahtumaa document.getElementById(key).setAttribute('value', window.localStorage.getItem(key)); } else { // muussa tapauksessa asetetaan ja samalla tallennetaan ko. elementin // value parametrin arvo localStorage objektiin avain/arvo parina... window.localStorage.setItem(key, document.getElementById(key).getAttribute('value')); } } else { // jos Storage objektia ei tueta ilmoitetaan siitä käyttäjälle. document.body.innerHTML = "<p align='center'>Selaimesi ei tue Storage objektia, värisäädöt eivät tallennu</p>" + document.body.innerHTML; } // *** joten tänne on laitettava funktiokutsu jota käytetään silloin // kun ko. elementin onchange tapahtuma laukaistaan manuaalisesti. //(esim. värejä voi vaihdella vaikka attribuutin arvo ei tallentuisikaan) setColor(key, document.getElementById(key).getAttribute('value')); } function setMySettings(key, value) { if (typeof(Storage) !== "undefined") { // täällä päivitetään säätimen arvo eikä sitä // tarvitse missään muualla enää päivittää!!! window.localStorage.setItem(key, value); } setColor(key, value); } function setColor(key, value) { // here you can do whatever you fucking want // ( with or without the given parameters ) }
ja vielä lopuksi: homma siis toimii mikäli lataat jquery-latest.min.js tiedoston ja pukkaat sen serverillesi (ei vaikuta silloin kuten ns. 3rd party script ja näin välttyy selaimen asetusten säätelyltä)
neosofta kirjoitti:
// HUOM: Rivi 13 alkuperäisessä koodissa: if(window.localStorage.getItem(key) !== "undefined" && window.localStorage.getItem(key) !== null)
Kannattaa opetella JS:n alkeet ennen tällaisia ylimielisiä purkauksia. Nolaat vain itsesi.
Ei ole mitään järkeä verrata localStoragesta luettua arvoa merkkijonoon "undefined" tässä kohtaa. Yritit kai tarkistaa, ettei palautettu arvo ole undefined mutta teit sen väärin. Oli miten oli, niin kyseinen tarkistus on joka tapauksessa väärin, koska localStorage.getItem palauttaa arvon null, kun avainta ei löydy storagesta.
Joo, no en testannus muilla selaimilla, kuin uusimmalla Firefoxilla, kun itse en käytä muita selaimia.
Latasin palvelimelle tuon jQuery.js -kirjaston "./jquery-3.6.0.min" -tiedoston, niin nyt värivalinnat tosiaan säilyy, vaikka kävisi aivan jossain muualla välillä, ja palaa sitten. Aiemminhan kun tuon haki tuolta ulkoisesti jquey.comista tuon kirjaston käyttöön, niin sovellus ei mielestäni muistanut värejä, jos kävi jollain muulla domainalueella välillä. Nyt tilanne on korjattu!
Ulkoisessa jQuery-haussa on se hyvä puoli, että ei tarvitse itse stressata päivityksistä, mutta eipä kai niistä tarvitse välittää paljon muutoinkaan, kun tuo ohjelma toimii nyt tuolla 3.6.0-min versiolla, niin voihan sitä pitää palvelimella, eikä välttämättä tarvitse uusinta versiota, jollei sitten tee jotain sellaisia js-muutoksia, jotka ovat vain uudemmissa versioissa.
🎅
muuskanuikku kirjoitti:
mitä kirjoitti...
Oli miten oli, jos nyt tulikin varmuuden maksimoinnissa pikku ylilyönti niin homma ei tökkää järjettömyyteen vaan toimii.
@Jere Summell
Värivalintojen säilymisen kannalta voisi olla ehkä tarpeellista säilöä myöskin yhden radionappulan value, toinen sitten pukataan haettaessa luonnollisesti päinvastaiseksi (tapahtumahan ei laukea silloin kun arvo lykätään koodista käsin). Toisekseen jokainenhan taaplaa tyylillään,
<script src="./jquery-3.6.0.min"></script>
mutta viittaako tuo kenties johonkin tiedostoon? Yrittäessäni ladata tiedostoa https://jeresumell.munsivu.fi/ohjelmat/jquery-3.6.0.min.js toimi, toinen ei eli
Server Error 404 Page Not Found This page either doesn't exist, or it moved somewhere else.
(minulla nämä JS:n alkeet hieman hukassa...kossusta huolimatta logiikka toimii ehkä paremmin)
P.S Jyrkästi vastustan alkometri ajatustasi, ja toivon ettet koe yllä olevaa vain ylimieliseksi purkaukseksi 🎅
null|undefined|false tsekit menevät helpoiten if (foo) { bar(); } metodilla.
Lisäksi typeof(Storage) tsekkaus on vähän höhlä:
https://caniuse.com/namevalue-storage
Kolmanneksi jos haluaa käyttää localstoragea kannattaisi tallentaa kaikki jsoniin ja sieltä sitten haeskella arvoja avaimilla. Ei tule helvetisti localstorage itemejä kertalaakista vaan kaikki ovat siististi yhdessä avainparissa.
Mutta mistä minä mitään tiedän
Aivan mahtavaa, asiantuntijat tulivat viimeinkin mukaan kehiin! json.stringify could indeed be a good option but will it help if the basic logic does not work? Toisaalta tässä tapauksessa 3 (max. 4) key,value paria localStorage objektissa ei liene niin kovin helvetisti (yhtä kerrallaanhan vain päivitellään kun säädellään). Mielestäni kevyempi ratkaisu päivityksen kannalta kuin json stringin muokkailu joka vitun välissä, no makuasia.
Innolla odotan, että metabolix tulee ja typistää koko JS -skeidan max. pariin riviin niin ettei vain rivinvaihdot katoa.
neosofta kirjoitti:
(23.11.2021 11:12:53): @Jere Summell Värivalintojen...
Tuohan on ./ -syntaksi ihan perusteita, kun puhutaan hakemistohierarkiassa liikkumisessa ja toimiessa.
. viittaa samaan hakemistoon, ja sitten taas .. hakemistohierarikassa yhtä kerrosta ylemmäksi.
Jos ajattelet DOS/Windows/Linux ympäristössä komentoja
dir
ls -a
, niin tiedostolistauksissa on ensimmäisenä nuo viittaukset samalle tasolle, ja yhtä tasoa ylemmäs
sitten
cd .
Hakemistopolku, jossa kohemnto annetaan ja käyttäjä sijaitsee, pysyy samana,
mutta
cd ..
hakemisto vaihtuu astetta ylemmäs, ja käyttäjän sijainti muuttu siten, että pääsee suoraan siellä operoimaan.
kokeile vielä vaikka "ls -a ./" -unix/linux-ympäristossa. tulostuu näyttopäätteelle sen hakemiston koko tiedostolistaus, jossa käyttäjä sijaitsee sillä hetkellä.
eli tuo "<script src="./jquery-3.6.0.min"></script>" viittaa nimenomaan osoitteeseen https://jeresumell.munsivu.fi/ohjelmat/jquery-3.6.0.min.js
koska olen tallentanut nuo kaikki kolme tiedostoa tuonne ohjelmat -alikansioon.
Eli ei ole olemassa mitään toista tiedostoa, sama, vaikka olisin jättänyt tuon ./ tuosta alusta pois, siltikin se olisi toiminut, mutta pistin sen nyt siihen.
../jquery-3.6.0.min olisi yrittänyt ladata ja etsiä tuota js-kirjastotiedostoa tuolta oman kotihakemistoni juuresta, tai ../../jquery-3.6.0.min vielä ylempää, eli paikasta, johon minulla ei ole edes lukuoikeuksia.
cd /
tarkoittaa hakemistosijaintipolun vaihtamista koko järjestelmän juurihakemistoon.
Esim Linux-järjestelmässä ei kannata empiirisesti kokeilla rekursiivista tietojenpoistoa juurihakemiston osalta
rm -r /
järjestelmää ei saa palautettua enää sen jälkeen muuta kuin uudelleenasentamalla.
Lättäsin ton sun HTML jutun työpöydälleni ja muutin URL:t osoittamaan servullesi niin homma toimii säätimien osalta loistavasti eli ne 'säilyttää' arvonsa, radionapit eivät ja valitut värit katoava jos navigoin muualle - palaan takaisin, päivitän sivun tai jos suljen selaimen ja avaan selaimen/sivun uudelleen. Värit eivät palaudu automaattisesti vaan pitää kilkata ensin vaikkapa radionappia!
<!DOCTYPE html> <html> <head><title>HTML-color-picker:Never anymore need to solve opponecy color problem again yourself!</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta charset="UTF-8"/> <script src="https://jeresumell.munsivu.fi/ohjelmat/jquery-3.6.0.min.js"></script> </head> <body id="demo"> <h1>HTML - color -picker</h1> <p>Choose your Red, Green and Blue values and this page body shows you results in run and gives a hex values for colours.This application is programmed to remember your picks even if you leave page and come back.</p> <form> <br> <input type="radio" name="userColorPick" value="Background" checked onchange="aja()">Background</input> <br> <input type="radio" name="userColorPick" value="Text" onchange="aja()">Text</input> <br> <input type="range" min="0" max="255" value="0" class="slider" id="redRange" onchange="aja()"><p><b>Red Value</b>: <span id="redSV"></span></p> <br> <input type="range" min="0" max="255" value="0" class="slider" id="greenRange" onchange="aja()"><p><b>Green Value</b>: <span id="greenSV"></span></p> <br> <input type="range" min="0" max="255" value="0" class="slider" id="blueRange" onchange="aja()"><p><b>Blue Value</b>: <span id="blueSV"></span></p> </form> <p id="rgb"> <br> <p id="hexD"> <br> <p id="oppC"> <hr size="2"> <i>published 17.11.2021 (First version)</i> <br> <i>updated 21.11.2021 (Second version)</i> <br> <b>This page is using HTML5 supported localStorage Objects now. <br> Thanks for active and fellow Programming forum discussion mate nicknamed <i>"neosofta (who confused me so much I had difficult to get this work finished)"</i>@ <a href="https://www.ohjelmointiputka.net">Ohjelmointiputka</a> <br> -Finnish-origin non-commerical progamming society for his help to introduce myself to Storage objects in HTML5 and coding tips with them.</b> <script src="https://jeresumell.munsivu.fi/ohjelmat/colorPicker.js"></script> </body> </html>
elikä sun pitää kutsua $(document).ready funktio kierroksessa jossain välissä sitä värinsäätöfunkkaria (aika loppupuolella, luulisin) tai yrittää jotain tämän tapaista $("#element").trigger("onclick"); elementti vois olla vaikka jompikumpi radionapeista koska mikään eventti ei laukea kun arvot vain asetetaan koodista.
Käyttäjän näkökulmasta en välitä hölkäsen pöläystä servereillä olevista kansiorakennelmista, ainoastaan toimivuus kiinnostaa.
neosofta kirjoitti:
(23.11.2021 12:42:35): Aivan mahtavaa, asiantuntijat tulivat...
No jos noin päin vittua ajattelit koodin kirjoittaa niin tokihan se varmasti vähän hidastaa selainta, mutta ei nyt niin hirveästi moderneilla vempaimilla. Tosin ei kannata kirjoittaa paskaa koodia.
Käyttäjä kirjoitti:
No jos noin päin vittua ajattelit koodin kirjoittaa...
En ajatellut kirjoittaa vaan kirjoitin jo. Jos pari hassua riviä koodia (kirjoitettu päin vittua tai ei, mutta toimivaa) mielestäsi hidastaa selainta jollain merkittävällä tavalla niin... you can do whatever you fucking want, so simple is that!
neosofta kirjoitti:
(23.11.2021 14:23:10): Lättäsin ton sun HTML jutun työpöydälleni ja...
On totta, että radio buttonin arvoa ei tallenneta missään kohtaan muistiin. En tiedä, millä selaimella kokeilit tuota, kun värit katosivat, kun eilen illalla havaitsin, että ne katoavat, mutta sitten aamulla, kun vaihdoin tuolta ulkoisesta lähteestä paikalliseen jQuery-kirjasto tiedoston käyttöön, niin Firefoxilla muisti värit, kun kävin välillä Googlen etusivulla, ja palasin takaisin tuonne verkko-osoitteeseeni, missä tuo verkkosovellukseni sijaitsee.
Sittenhän värit taas vaihtuu, kun käyttäjä valitsee jomman kumman radio buttonin arvon.Kaipa asian voisi korjata, että radio buttonin arvokin tallennetaan. Mutta ei tänään.
En sitä millään muotoa ylimieliseksi vuodatukseksi tulkinnut, en totta puhuen ihan sataprosenttisen tarkoitusperin tuota alkometri-ideaa esittänyt, kunhan tuli mieleen, kun totesit itse, että kännissä sujuu tämä foorumille koodin pistäminen, ja varmaan usealla on sama tilanne jollain muulla keskustelupalstalla, tai facebookissa, että kirjoittaa kaikenlaista ehkä ohi suunkin humalassa.
En totta puhuen itsekään ole sen kannalla, että keskustelupalstojen ylläpitäjät saisivat mahdollisuuden kontrolloida foorumille kirjoittajien päihtymystilaa tai rajata kirjoittamista sen perusteella.
Joo, elikä veivasin Jeren colorPicker.js tiedoston online JS beautyfier'in läpi...
var _0x1a3a29 = _0x326b; (function(_0x29fff4, _0x159470) { var _0x234426 = _0x326b, _0x1d4826 = _0x29fff4(); while (!![]) { try { var _0x377bf3 = -parseInt(_0x234426(0x110)) / 0x1 * (parseInt(_0x234426(0x106)) / 0x2) + -parseInt(_0x234426(0x11f)) / 0x3 + -parseInt(_0x234426(0x103)) / 0x4 + -parseInt(_0x234426(0x10c)) / 0x5 + -parseInt(_0x234426(0x104)) / 0x6 * (parseInt(_0x234426(0x128)) / 0x7) + parseInt(_0x234426(0x10b)) / 0x8 * (-parseInt(_0x234426(0x125)) / 0x9) + parseInt(_0x234426(0x119)) / 0xa; if (_0x377bf3 === _0x159470) break; else _0x1d4826['push'](_0x1d4826['shift']()); } catch (_0x7e9c0d) { _0x1d4826['push'](_0x1d4826['shift']()); } } }(_0x49d6, 0xd766c), $(document)[_0x1a3a29(0xfd)](function() { var _0x2bf184 = _0x1a3a29; const _0x3ea530 = [_0x2bf184(0xff), _0x2bf184(0x111), _0x2bf184(0x113)]; for (let _0x290d18 = 0x0; _0x290d18 < _0x3ea530['length']; _0x290d18++) { getMySettings(_0x3ea530[_0x290d18]); } // document.getElementById("radio1").onchange(); // *** lisäsin tämän aja(); //EDIT *** vaihdoin tähän niin ei tarvitse edes radionapin id:tä })); function save() { var _0x426ee2 = _0x1a3a29; window[_0x426ee2(0x127)]['setMySettings'](_0x426ee2(0xff), r), window[_0x426ee2(0x127)][_0x426ee2(0x115)](_0x426ee2(0x111), g), window['localStorage'][_0x426ee2(0x115)](_0x426ee2(0x113), b); } function getMySettings(_0x343c16) { var _0x489030 = _0x1a3a29; typeof Storage !== 'undefined' ? window[_0x489030(0x127)]['getItem'](_0x343c16) !== _0x489030(0x116) && window['localStorage'][_0x489030(0x105)](_0x343c16) !== null ? document['getElementById'](_0x343c16)[_0x489030(0x117)]('value', window[_0x489030(0x127)]['getItem'](_0x343c16)) : localStorage[_0x489030(0x129)](_0x343c16[i], document['getElementById'](_0x343c16)[_0x489030(0xfe)]('value')) : alert('Your\x20Browser\x20does\x20not\x20supoort\x20localStorage\x20-objects'); } function setMySettings(_0x921bb5, _0x345022) { var _0x3a408e = _0x1a3a29; typeof Storage !== _0x3a408e(0x116) && window[_0x3a408e(0x127)]['setItem'](_0x921bb5, _0x345022); } function toHex(_0x34f3bc) { var _0x57ca74 = _0x1a3a29, _0x2e17d3 = Number(_0x34f3bc)['toString'](0x10); return _0x2e17d3[_0x57ca74(0x101)] < 0x2 && (_0x2e17d3 = '0' + _0x2e17d3), _0x2e17d3; } function invertColor(_0x1c0a28) { var _0x559041 = _0x1a3a29; _0x1c0a28['indexOf']('#') === 0x0 && (_0x1c0a28 = _0x1c0a28[_0x559041(0x11b)](0x1)); _0x1c0a28[_0x559041(0x101)] === 0x3 && (_0x1c0a28 = _0x1c0a28[0x0] + _0x1c0a28[0x0] + _0x1c0a28[0x1] + _0x1c0a28[0x1] + _0x1c0a28[0x2] + _0x1c0a28[0x2]); if (_0x1c0a28[_0x559041(0x101)] !== 0x6) throw new Error('Invalid\x20HEX\x20color.'); var _0x3de53c = (0xff - parseInt(_0x1c0a28[_0x559041(0x11b)](0x0, 0x2), 0x10))[_0x559041(0x10e)](0x10), _0x485362 = (0xff - parseInt(_0x1c0a28['slice'](0x2, 0x4), 0x10))['toString'](0x10), _0xc7fd9e = (0xff - parseInt(_0x1c0a28['slice'](0x4, 0x6), 0x10))[_0x559041(0x10e)](0x10); return '#' + padZero(_0x3de53c) + padZero(_0x485362) + padZero(_0xc7fd9e); } function padZero(_0x597d7d, _0x4d6613) { _0x4d6613 = _0x4d6613 || 0x2; var _0x30d187 = new Array(_0x4d6613)['join']('0'); return (_0x30d187 + _0x597d7d)['slice'](-_0x4d6613); } function _0x326b(_0x3138f6, _0x377976) { var _0x49d65e = _0x49d6(); return _0x326b = function(_0x326b0c, _0x217889) { _0x326b0c = _0x326b0c - 0xfc; var _0x5da561 = _0x49d65e[_0x326b0c]; return _0x5da561; }, _0x326b(_0x3138f6, _0x377976); } function aja() { var _0x5e7fe4 = _0x1a3a29, _0xc86fd1 = document[_0x5e7fe4(0x124)]('redRange')[_0x5e7fe4(0x10f)]; window[_0x5e7fe4(0x127)]['setItem']('redRange', _0xc86fd1); var _0x15a853 = document[_0x5e7fe4(0x124)]('greenRange')[_0x5e7fe4(0x10f)]; window[_0x5e7fe4(0x127)][_0x5e7fe4(0x129)]('greenRange', _0x15a853); var _0x6ae2f4 = document[_0x5e7fe4(0x124)](_0x5e7fe4(0x113))[_0x5e7fe4(0x10f)]; window[_0x5e7fe4(0x127)][_0x5e7fe4(0x129)](_0x5e7fe4(0x113), _0x6ae2f4), document['getElementById'](_0x5e7fe4(0x11e))[_0x5e7fe4(0x109)] = _0xc86fd1, document[_0x5e7fe4(0x124)]('greenSV')[_0x5e7fe4(0x109)] = _0x15a853, document[_0x5e7fe4(0x124)](_0x5e7fe4(0x120))[_0x5e7fe4(0x109)] = _0x6ae2f4; var _0x5a2773 = this[_0x5e7fe4(0x10d)](_0xc86fd1), _0x43582a = this['toHex'](_0x15a853), _0x5187ff = this[_0x5e7fe4(0x10d)](_0x6ae2f4), _0x593820 = '#' + _0x5a2773 + _0x43582a + _0x5187ff, _0x410056 = this[_0x5e7fe4(0x10a)](_0x593820); pick = document[_0x5e7fe4(0x107)](_0x5e7fe4(0x11d))[_0x5e7fe4(0x10f)], pick === 'Background' && (document[_0x5e7fe4(0x124)](_0x5e7fe4(0xfc))['style'][_0x5e7fe4(0x121)] = _0x593820, document['getElementById']('demo')[_0x5e7fe4(0x11a)]['color'] = _0x410056, document[_0x5e7fe4(0x124)](_0x5e7fe4(0x126))[_0x5e7fe4(0x109)] = _0x5e7fe4(0x123) + 'R:' + _0xc86fd1 + _0x5e7fe4(0x102) + _0x15a853 + _0x5e7fe4(0x100) + _0x6ae2f4 + ')', document[_0x5e7fe4(0x124)]('hexD')[_0x5e7fe4(0x109)] = _0x5e7fe4(0x11c) + _0x593820, document[_0x5e7fe4(0x124)](_0x5e7fe4(0x118))[_0x5e7fe4(0x109)] = _0x5e7fe4(0x114) + _0x410056), pick === 'Text' && (document['getElementById'](_0x5e7fe4(0xfc))[_0x5e7fe4(0x11a)]['backgroundColor'] = _0x410056, document[_0x5e7fe4(0x124)]('demo')['style'][_0x5e7fe4(0x108)] = _0x593820, document[_0x5e7fe4(0x124)](_0x5e7fe4(0x126))['innerHTML'] = 'RGB-code:(' + 'R:' + _0xc86fd1 + ',\x20G:' + _0x15a853 + _0x5e7fe4(0x100) + _0x6ae2f4 + ')', document[_0x5e7fe4(0x124)](_0x5e7fe4(0x112))[_0x5e7fe4(0x109)] = _0x5e7fe4(0x11c) + _0x410056, document[_0x5e7fe4(0x124)](_0x5e7fe4(0x118))[_0x5e7fe4(0x109)] = _0x5e7fe4(0x122) + _0x593820); } function _0x49d6() { var _0x5a4ed9 = ['getElementById', '45ovSMCt', 'rgb', 'localStorage', '7ALyYjc', 'setItem', 'demo', 'ready', 'getAttribute', 'redRange', ',\x20B:', 'length', ',\x20G:', '6809436OQWbjI', '10440774DWjHXq', 'getItem', '26jToNKX', 'querySelector', 'color', 'innerHTML', 'invertColor', '1825256gIqCEF', '5797000ocVPiZ', 'toHex', 'toString', 'value', '121685BgPzwB', 'greenRange', 'hexD', 'blueRange', 'Opposite\x20color:\x20', 'setMySettings', 'undefined', 'setAttribute', 'oppC', '87482770pfoVpX', 'style', 'slice', 'Hex-Code:\x20', 'input[name=\x22userColorPick\x22]:checked', 'redSV', '1624245ZkCjdY', 'blueSV', 'backgroundColor', 'Opposite\x20color:', 'RGB-code:(']; _0x49d6 = function() { return _0x5a4ed9; }; return _0x49d6(); };
<!-- *** HTML:ssä lisäsin tohon radionappiin id:n --> <input type="radio" id="radio1" name="userColorPick" value="Background" onchange="aja()">Text</input>
ja homma alkoi pelittämään kokolailla kuten oli suunnitelmana.
Siis: Jeren colorPicker toimii kuten pitääkin ja meikäläisen päin vittua ideoima JavaScript -skeida toimi kaikesta huolimatta niin kuin pitääkin eli synkronointiin tarvittiin vain yksinkertainen "köyhänmiehen provider".
@Jere
Don't forget this:
Thanks for active and fellow Programming forum discussion mate nicknamed "neosofta (who got me so confused I had difficult to get this 'skeida' finished)"
Et minua lainkaan asattanut hämmennyksen tielle noissa sinun ehdotuksissasi tai koodivinkeissäsi, hienoa, että otit tuon Storage-olion käytön esille, se oli uusi minulle. Ja lopultahan asia tuli kuntoon ja sinä olit osallisena myös edesauttamassa ohjelman kuntoon saamista.
En nyt enää sinne taida mitään lisää, voi olla, että en lisää raiobuttonien tallennustakaan, mielestäni tämä ohjelmisto on aika lailla valmis ja käyttötarkoitukseensa yksinkertainen käyttää ja riittävän toimiva.
Joo, kuten täällä joku mainitsikin niin ei sinne localStorage objektiin kannata mitenkään ylettömästi skeidaa lykätä.
Seuraavana putka-yhteistyö ja avunanto projektina voisi harkita esim. mitä kaikkea skeidaa saakaan pukattua käyttäjän koneelle using IndexedDB 🎅
before mark the case closed
Voisi olla ehkä syytä ajatella, kuinka helppoa on ohittaa jopa ns. modernin selaimen (esim. Edge) yksi perusasetus ja käytännössä sallia ns. kolmannen osapuolen sisältö vain pukkaamalla kulloinkin kyseessä oleva 3rd party script samalle palvelimelle, kuin itse sivu. Joka siis mahdollistaa kaman pukkaamisen käyttäjän koneelle hänen tietämättä siitä hölkäsen pöläystä. Yksi ainoa tähän keskusteluun osallistunut asiantuntija otti 'epäsuorasti' kantaa tähän puoleen, joka on minun mielestäni kuitenkin melko tärkeä pointti (muut vain kitisivät jostain turhista tsekkauksista; fucking morons).
neosofta kirjoitti:
(24.11.2021 15:17:39): before mark the case closed ...
Tarkoitatko, että palvelimelle olisi fyysinen pääsy tai kenellä vaan oikeudet palvelimelle? Siinä tapauksessa peli nyt on muutenkin menetetty...
Onko JavaScriptillä muuten mitään mahdollisuutta tehdä eval() funktiosta tietoturvallisempaa?
🎅 Kuinkas onnistuitkin injektoimaan käsitteen JavaScript ja tuon toisen mainitsemasi käsiteen samaan lauseeseen...
neosofta kirjoitti:
(23.11.2021 19:13:12): Joo, kuten täällä joku mainitsikin niin ei...
Tutustuin tuohon indexDB-resurssiin, jonka tarjosit.
Voisi olla paikallaan tehdä tuon puitteissa tosiaan jotain järkevää. Tai yrittää tehdä.
Voisi olla mielenkiintoista, ja saada jotain hyodyllistä aikaan, jos yritettäisiin yhdessä jotain sellaista yleispätevää JavaScript -koodia luoda, jossa hyodynnettäisiin JSON -dataa.
Esimerkiksi Wordpress -sivustoilla on Wp REST Apin julkaisun jälkeen ollut kaikkien noiden Wordpress sivujen data saatavilla avoimesti JSON-formaatissa, niin voisi aloittaa sen ympärille rakentamaan jotainko.
Esimerkiksi tässä yksi esimerkki eräästä Linux -blogista, jossa ylläpitäjä ei ole piilottanut JSON-dataa,
Tuo wp-json/ -kansio on oletuksena se sivuston koko data JSON -muodossa oletuspolku.
Tästä voisi avata kokonaan uuden aiheen tänne "koodit" -keskustelualueelle täällä putkassa, tee sä "neosofta" -aloitus ja pistä jokin koodiesimerkki jos nyt käytetään oppimateriaalina tuota vitux.com -Linux -blogin dataa.
Pukkasin tuon vitux.com/wp-json/ kaman hieman paremmin ihmiselle luettavaan muotoon, tsekkasin... ja olin tosi lähellä oksentaa joten ehdotetulta pohjalta asiaan lähestyminen taisi nyt ikävä kyllä mennä vituix 🤢.
EDIT: ALKUPERÄISEEN AIHEESEEN MITENKÄÄN LIITTYMÄTÖN SISÄLTÖ POISTETTU
neosofta kirjoitti:
Blender versio 2.79 on viimeisin, joka pyörii koneessani johtuen näytönohjaimeni kapasiteetista ja ko. Blender version .X/.fbx exporter plugin härpäkkeet tuntuvat hukkaavan animaatioita sisältävistä malleista aina jotain.
Harmi, että Blenderillä mallintaminen ja työskentely on käyttömukavuudeltaan rinnastettavissa siihen kun seksin aikana hakkaisi vehjettään oven väliin. Tosin tuollakin toiminnalla taitaa kyllä olla omat faninsa... 😂
😂 Kokemuksen syvällä rintaäänellä
jalski kirjoitti:
Harmi, että Blenderillä mallintaminen ja työskentely on...
yhä edelleen sitä mitä se on... eli aivan naulan kantaan. Sanoisin että Blenderin kanssa runkkaaminen vie jotakuinkin vuoden ennen kuin homma alkaa olla jotenkin jouhevaa 🎅.
plenderi on avointa kastiketta, eli ei muuta kun kirjottelemaan omia pätsejä! isot pojat shithubissa sano että avoin soosi on paras ja koodi koska voi itte tehä just sellasen ku haluaa!11
carabia kirjoitti:
plenderi on avointa kastiketta...
Kyllä on muuten v****a, että menisin sekaantumaan kooditasolla mihinkään python kamaan! 🤢
Latasin taannoin Visual Studio 2019 Community ympäristöön viimeisimmän x86/x64 Python härpäkkeen ja katsoin piruuttani puolituntisen esittelyvideon jossa joku iloisesti hymyilevä tyyppi mainosti käytön jouhevuutta. Lopputulos oli webbisivu jossa nappia painamalla tekstilootaan ilmestyi 'HALOO MAAILMA'. Tsekkasin sitten projektin bin kansion, jonne oli kertynyt melkein puoli gigaa kaikenlaista skeidaa. Lähti kyllä välittömästi meikäläisen koneesta hevon v*****n!
neosofta kirjoitti:
carabia kirjoitti:
plenderi on avointa kastiketta...
Kyllä on muuten v****a, että menisin sekaantumaan kooditasolla mihinkään python kamaan! 🤢
Eiks blenderi kuitenkin oo c++:aa, vaikka siihen voikin vissiin laittaa plugareita pyyttonilla.
seetä ja seeplusplussaa se on sekasin suurimmaks osaks juu
Olkoon vaikka puuceetä (boo c) 🎅
Aihe on jo aika vanha, joten et voi enää vastata siihen.