我有一个网站,其中包含技术信息。我想转换帝国单位(英寸)为公制单位(毫米)根据用户的喜好。我的托管提供商不允许在网页上使用php,但我可以使用Javascript。
我最初的计划是,有一个按钮,翻转一个开关,以设置一个UnitPreference曲奇,以保存客户的偏好米制/帝国单位。我发现使用Javascript中的cookie是..。相当笨重。有没有办法不用饼干来实现我的目标?
发布于 2014-05-27 11:27:40
如果在HTML5中使用/编码,则可以使用脱机/会话存储而不是cookie。语法更简单,但它依赖于允许站点存储数据的用户。
更新1.9.2018
我今天注意到,这个答案得到了另一次投票,但作为一个简单的评论也许会更好。为了支持上面的评论(重新存储),我制作了一个小演示。
<!doctype html>
<html>
<head>
<meta charset='utf-8' />
<title>Unit Preferences Storage with Javascript & localStorage</title>
<style>
body{
display:flex;
align-items:center;
justify-content:center;
height:100vh;
width:100%;
box-sizing:border-box;
padding:0;
margin:0;
}
input[type='button']{
padding:1rem;
color:green;
margin:auto;
align-self:center;
}
</style>
<script>
/* Event handler common flags */
const flags={
once:false,
capture:true,
passive:true
};
/* Unit preferences matrix */
const matrix={
1:{
name:'Metric',
unit:'mm',
conversion:25.4
},
0:{
name:'Imperial',
unit:'inches',
conversion:0.0393701
}
};
/* Simple object to manipulate storage */
const StoreFactory=function( name, type ){
'use strict';
const engine = type.toLowerCase() === 'local' ? localStorage : sessionStorage;
const set=function( data ){
engine.setItem( name, JSON.stringify( data ) );
};
const get=function(){
return exists( name ) ? JSON.parse( engine.getItem( name ) ) : false;
};
const remove=function(){
engine.removeItem( name );
};
const exists=function(){
return engine.getItem( name )==null ? false : true;
};
return Object.freeze({
set,
get,
exists,
remove
});
}
/* Run-time configuration */
const storename='UnitPreference';
const storetype='local'; // "session" is volatile ~ ie: exists only for current session
/* Invoke the storeage object */
let oStore=new StoreFactory( storename, storetype );
/* Event handler that triggers storage of user choice */
const switcher=function(e){
'use strict';
let payload = matrix[ e.target.dataset.state ];
payload.state = e.target.dataset.state;
oStore.set( payload );
e.target.dataset.state = 1 - e.target.dataset.state;
e.target.value=payload.name;
};
/* Bind DOM elements and event handlers rather than inline event handlers... */
const bindEvents=function(){
'use strict';
let json=false;
let bttn=document.querySelector( 'input[type="button"][name="units"]' );
bttn.addEventListener( 'click', switcher.bind( bttn ), flags );
/*
If the user has set his/her choice for units then we need
re-establish initial conditions for button on page load
should they leave & return etc
*/
if( json=oStore.get() ){
bttn.dataset.state = 1 - json.state;
bttn.value = json.name;
/*
potentially you can now access the value stored in the localStorage object
for whatever conversion purposes you have...
*/
}
/* other event listeners ... */
};
document.addEventListener( 'DOMContentLoaded', bindEvents, flags );
</script>
<body>
<!--
A standard button with default settings.
The value will change when clicked and
then on subsequent page loads also.
-->
<input type='button' name='units' value='Choose Units ' data-state=1 />
</body>
</html>发布于 2014-05-27 12:56:38
下面是一个更改样式规则的简单演示。有更复杂的方法来解决这个问题,但是对于这个应用程序来说,这是一个简单的方法。默认情况下,您可以显示一个或两个单元。
要更改的规则必须存在于现有样式表中。
<style type="text/css">
.metric {
display: inline;
}
.imperial {
display: none;
}
</style>
<script>
// Search style sheets for selector. If found, set
// prop to value. Stops when first selector found
function setRuleValue(selector, prop, value) {
selector = selector.toLowerCase();
// Get the style sheets
var sheet, sheets = document.styleSheets;
var j, rule, rules;
if (sheets) {
// Search style sheets for rule
for (var i=0, iLen=sheets.length; i<iLen; i++) {
sheet = sheets[i];
j = 0;
// Choose .cssRules or .rules, whichever is supported
while (rule = (sheet.cssRules[j] || sheet.rules[j])) {
j++;
if (rule.selectorText.toLowerCase() == selector) {
rule.style[prop] = value;
// If had success, return true
return true;
}
}
}
}
// If get here, didn't find rule so return false
return false;
}
// Turn metric on, imperial off
function showMetric() {
setRuleValue('.metric', 'display', '');
setRuleValue('.imperial', 'display', 'none' );
}
// Turn imperial on, metric off
function showImperial() {
setRuleValue('.metric', 'display', 'none');
setRuleValue('.imperial', 'display', '' );
}
</script>
<div>This part is <span class="imperial">3 inches</span><span class="metric">25.4 mm</span> long</div>
<br>
<button onclick="showMetric()">Show metric</button>
<button onclick="showImperial()">Show imperial</button>如果您有一个表,您可以为每一个度量和帝国创建一个colgroup,然后只需更改隐藏或显示的哪个colgroup。默认情况下,将两者都显示出来。
https://stackoverflow.com/questions/23888108
复制相似问题