在没有cookie的Javascript中将网页上的公制转换为英寸转换

时间:2014-05-27 11:22:03

标签: javascript html cookies

我有一个包含技术信息的网站。我想根据用户的偏好将英制单位(英寸)转换为公制单位(毫米)。我的托管服务提供商不允许在网页上使用php,但我可以使用Javascript。

我最初的计划是使用一个按钮来翻转开关以设置UnitPreference cookie,其中包含客户对公制/英制单位的偏好。我发现在Javascript中使用cookie是非常笨拙的。有没有办法在没有cookie的情况下实现我的目标?

2 个答案:

答案 0 :(得分:2)

如果您在HTML5中使用/编码,则可以使用离线/会话存储而不是cookie。语法更容易,但它依赖于允许您的站点存储数据的用户。

更新[1.9.2018]

我今天注意到这个答案收到了另一个upvote,但也许可能更好作为一个简单的评论。为了支持上述评论(重新存储),我敲了一个小演示。

<!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>

答案 1 :(得分:1)

这是一个更改样式规则的简单演示。有更复杂的方法可以解决这个问题,但这是一个简单的方法。默认情况下,您可以显示一个或两个单位。

要更改的规则必须存在于现有样式表中。

<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&ensp;inches</span><span class="metric">25.4&ensp;mm</span> long</div>
<br>
<button onclick="showMetric()">Show metric</button>
<button onclick="showImperial()">Show imperial</button>

如果您有一个表,您可以为每个度量和英制创建一个colgroup,然后只需更改隐藏或显示的colgroup。默认情况下,显示两者。