简体   繁体   中英

How do I store JavaScript variables in a website URL?

I have a game, https://e4494s.neocities.org/bounce.html , where the player can mess around with various variables and modify the physics of the simulation. I want to add a button that will take the user to a separate page where there are no text boxes or anything and the values they modified are stored in the URL so they can send it to somebody or save it for themselves. For example, if they modify bounciness to be 0.5 and gravity to -0.25, then clicking the Get Link button would send them to https://e4494s.neocities.org/fullscreenbounce.html/bounciness=0.5;gravity=-0.25 . (I would be fine with any other way of storing them there, such as /0.5/0.25 or any other method). The problem is, when I go to this link, it is trying to go to the page "bounciness=0.5;gravity=-0.25" which doesn't exist on my website. But I know there IS some way to store variables in the URL, like for example Mr. Doob's game Voxels . As I make more Voxels, the URL changes and I can simply copy that URL and it will have the exact thing I built every time I go to it.

So how would I go about incorporating that into my game?

I'd recommend you have a read of this related issue: Adding a parameter to the URL with JavaScript

Although you might want to look into using local storage instead (unless you are looking to use these as sharing links). Local storage will allow the values to be saved in the user's browser and still be there if they reload the page with no query parameters. Take a look at this one: https://www.w3schools.com/html/html5_webstorage.asp

One way to store accessible, redundant javascript data is using json. So the full parameterization of your game could be represented by the following string :

{ "bounciness": 0.5, "gravity": -0.25, "friction": 1.2, "windVector": { "ang": 2.7314, "mag": 4.23 } }

If that string was stored in a variable called dataString , you could do the following:

let { bounciness, gravity, friction, windVector } = JSON.parse(dataString);

Now the trick is to get the value in dataString into the URL. Json is good for arbitrary values, but it does not embed properly into a url. We need to make the additional step of encoding the json into a form that does fit in a url. One such encoding is base64, and base64 encoding already exists via the global btoa function ( mdn ) So the process will look like:

original raw data -> json data -> base64 encoded json data

The value to be inserted into the url, if the raw data is held in a variable called params , would be:

 let params = { bounciness: 0.5, gravity: -0.25, friction: 1.2, windVector: { ang: 2.7314, mag: 4.23 } } let valueForUrl = btoa(JSON.stringify(params)); console.log(valueForUrl);

Here's an example where, as the raw data is updated, the url value automatically updates:

 let rawData = { "bounciness": 0.5, "gravity": -0.25, "friction": 1.2, "windVector": { "ang": 2.7314, "mag": 4.23 } } let resultJson = document.querySelector('.result.json'); let resultBase64 = document.querySelector('.result.base64'); let elems = [ 'bounciness', 'gravity', 'friction', 'windVector-ang', 'windVector-mag' ].map(v => document.querySelector(`[name="${v}"]`)); let [ bElem, gElem, fElem, waElem, wmElem ] = elems; let fullUpdate = () => { if (document.querySelector(':invalid')) { resultJson.innerHTML = 'Invalid input'; resultBase64.innerHTML = 'Invalid input'; return; } let json = JSON.stringify(rawData); resultJson.innerHTML = json; resultBase64.innerHTML = btoa(json); }; let updateElem = (elem, obj, prop) => { elem.value = obj[prop].toString(); elem.addEventListener('input', evt => { if (elem.matches(':valid')) obj[prop] = parseFloat(elem.value, 10); fullUpdate(); }); }; updateElem(bElem, rawData, 'bounciness'); updateElem(gElem, rawData, 'gravity'); updateElem(fElem, rawData, 'friction'); updateElem(waElem, rawData.windVector, 'ang'); updateElem(wmElem, rawData.windVector, 'mag'); fullUpdate();
 input { display: block; } input:valid { background-color: rgba(0, 150, 0, 0.2); } input:invalid { background-color: rgba(150, 0, 0, 0.2); } p { margin: 0; margin-top: 5px; }.result { font-family: monospace; border: 2px solid #a0a0a0; margin-top: 0; overflow: hidden; text-overflow: ellipsis; }
 <p>Bounciness</p> <input type="text" pattern="[-+]?[0-9]+([.][0-9]+)?" name="bounciness" /> <p>Gravity</p> <input type="text" pattern="[-+]?[0-9]+([.][0-9]+)?" name="gravity" /> <p>Friction</p> <input type="text" pattern="[-+]?[0-9]+([.][0-9]+)?" name="friction" /> <p>Wind Angle</p> <input type="text" pattern="[-+]?[0-9]+([.][0-9]+)?" name="windVector-ang" /> <p>Wind Magnitude</p> <input type="text" pattern="[-+]?[0-9]+([.][0-9]+)?" name="windVector-mag" /> <p>JSON</p> <p class="result json"></p> <p>Base64</p> <p class="result base64"></p>

Now when a new page loads with a supplied url, you can convert back from base64 (using atob ) to json, and then back from json to raw data. Assume the value in the url is in a variable urlData :

 let urlData = 'eyJib3VuY2luZXNzIjowLjUsImdyYXZpdHkiOi0wLjI1LCJmcmljdGlvbiI6MS4yLCJ3aW5kVmVjdG9yIjp7ImFuZyI6Mi43MzE0LCJtYWciOjQuMjN9fQ'; console.log(JSON.parse(atob(urlData)));

Note that base64 is not the only possible encoding (and it may be more inefficient than other encodings!)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM