React:应用程序在桌面上运行,但在移动设备上显示空白页面

时间:2016-10-03 07:03:52

标签: javascript reactjs

我用React制作了这个应用程序:

calculator app

现场演示:http://n-or.de/simple-calculator/

它适用于桌面,但在移动设备上,实际的应用程序不可见。

只用渐变看到背景。我用iPhone 6s plus测试过。之后我请朋友在她的Android上试用它并且她有相同的空白背景。

这已经是我遇到此问题的第二个React应用程序。

可以在此处看到上面提到的其他React应用:http://n-or.de/weather-app/

所以我认为使用某些特定的语言功能并不重要。

这是计算器应用程序的JSX和Sass代码:

// Main.jsx as starting point of the app.
var React = require('react');
var ReactDOM = require('react-dom');
var Calculator = require('./components/Calculator.jsx');

var NAV_BUTTONS = [
  { value: '+ Add',
    operation: 'add'
  },
  { value: '- Subtract',
    operation: 'subtract'
  },
  { value: 'x Multiply',
    operation: 'multiply'
  },
  { value: '/ Divide',
    operation: 'divide'
  }
];

ReactDOM.render(<Calculator navButtons={ NAV_BUTTONS } />, document.getElementById('app'));

// Calculator.jsx - Main app-component
var React = require('react');
var TextBox = require('./TextBox.jsx');
var Button = require('./Button.jsx');

var Calculator = React.createClass({
  INIT_STATE: { a: 0,
                b: 0,
                placeholderText: 'Enter a number ...',
                resultBox: '',
                aClass: 'input-box',
                bClass: 'input-box',
                aDisabled: false,
                bDisabled: false,
                buttonsDisabled: 'disabled' },
  operations: {
    'add': function() {
      return this.state.a + this.state.b;
    },
    'subtract': function() {
      return this.state.a - this.state.b;
    },
    'multiply': function() {
      return this.state.a * this.state.b;
    },
    'divide': function() {
      return this.state.a / this.state.b;
    }
  },
  getInitialState: function() {
    return this.INIT_STATE; 
  },
  updateNumbers: function(variable, reference) { 
    var val = parseFloat(reference.value);
    var varClass = [variable + 'Class'];
    
    if (typeof val === 'number' && !isNaN(val)) {
      if (this.state[variable + 'Class'].indexOf('invalid-input') > -1) {
        this.setState({
          [varClass]: 'input-box' 
        })
      }
      
      this.setState({
        [variable]: val,
        buttonsDisabled: ''
      });
    } else {
      this.setState({
        [varClass]: [varClass] + ' invalid-input',
        buttonsDisabled: 'disabled'
      });
    }
  },
  triggerOperation: function(operation) {
    var result = this.operations[operation].call(this);
    
    this.setState({
        aDisabled: 'disabled',
        bDisabled: 'disabled',
        buttonsDisabled: 'disabled'
      });

    this.refs.resultBox.refs.inputElement.value = result;
  },
  resetForm: function() {
    function resetElement(itemName, placeholder, disabled) {
      this.refs[itemName].refs.inputElement.value = ''; // Value must be empty f. placeholder to appear.
      this.refs[itemName].refs.inputElement.disabled = disabled;
      this.refs[itemName].refs.inputElement.placeholder = placeholder;
    }
    
    resetElement.call(this, 'a', this.INIT_STATE.placeholderText);
    resetElement.call(this, 'b', this.INIT_STATE.placeholderText);
    resetElement.call(this, 'resultBox', this.INIT_STATE.resultBox, 'disabled');
   
    this.setState({
      a: 0,
      b: 0,
      aClass: 'input-box',
      bClass: 'input-box',
      buttonsDisabled: 'disabled'
    });
  },
  render: function() {
    var that = this;
    
    var navButtons = this.props.navButtons.map(function(button) {
      return (
        <div>
          <Button value={ button.value } classDiv="large-3 medium-6 column"
                  classButton="calculation-method nav-button"
                  handler={ that.triggerOperation } operation={ button.operation } disabled={ that.state.buttonsDisabled }/>
        </div>
      );
    });
    
    return (
      <div className="calculator">
        
        <div className="row">
          <h1>Simple calculator</h1>
        </div>
        
        <div className="row">
          <TextBox divClass="large-6 columns"
                   placeholder={ this.state.placeholderText }
                   id="a" textBoxClass={ this.state.aClass }
                   ref="a"
                   value={ this.state.a }
                   changeHandler={ this.updateNumbers }
                   variable="a"
                   disabled={ this.state.aDisabled }
                   />
          <TextBox divClass="large-6 columns"
                   placeholder={ this.state.placeholderText }
                   id="b" textBoxClass={ this.state.bClass }
                   ref="b"
                   value={ this.state.b }
                   changeHandler={ this.updateNumbers }
                   variable="b"
                   disabled={ this.state.bDisabled }
                   />
        </div>
        
        <div className="row">
          { navButtons }
        </div>
        
        <div className="row">
          <TextBox divClass="medium-9 columns"
                   placeholder={ this.INIT_STATE.resultBox }
                   ref="resultBox" textBoxClass="input-box"
                   disabled="disabled" />
          <Button value="Clear" classDiv="medium-3 columns"
                  classButton="attention nav-button"
                  handler={ this.resetForm } />
        </div>     
      </div>
    );
  }
});

module.exports = Calculator;

// Button component 
var React = require('react');

var Button = React.createClass({
  render: function() {
    function notify(e) {
      this.props.handler(e.target.dataset.operation);
    }
    
    return (
      <div className={ this.props.classDiv }>
        <button href='#' className={ this.props.classButton } 
                    onClick={ notify.bind(this) }
                    data-operation={ this.props.operation }
                    disabled={ this.props.disabled } >
          { this.props.value } 
        </button>
      </div>
    );
  }
});

module.exports = Button;

// TextBox component
var React = require('react');

var TextBox = React.createClass({
  notify: function() {
    let item = this.refs.inputElement;

    this.props.changeHandler(item.dataset.variable, item);
  },
  render: function() {   
    return (
      <div className={ this.props.divClass }
           ref={ this.props.id }>
          <input type="text"
                 placeholder={ this.props.placeholder} 
                 ref="inputElement" 
                 className={ this.props.textBoxClass }
                 disabled={ this.props.disabled } 
                 onChange={ this.notify }
                 data-variable={ this.props.variable } 
                 />
      </div>
    );
  }
});

module.exports = TextBox;
$lightChange: 25%;
$borderRadius: 6px;

@mixin addPseudoClasses($selector, $color) {
  #{$selector}:visited, #{$selector}:hover {
    color: white;
  }

  #{$selector}:hover {
    background: linear-gradient(lighten($color, $lightChange), $color); 
    color: white;
    cursor: pointer;
  }

    #{$selector}:active {
    opacity: 0.6;
    box-shadow: 1px 1px 0 black;
  }
}

html, body {
	height: 100%;
}

body {
  background: linear-gradient(to top, #403B4A , #E7E9BB);
}

.nav-button {
  text-decoration: none;
  color: green;
  padding: 10px 20px;
  text-align: center;
  font-weight: 900;
  font-size: 1.2rem;
  margin-bottom: 16px;
  display: inline-block;
  width: 100%;
  border-radius: $borderRadius;
  letter-spacing: 1px;
  box-shadow: 2px 2px 0 black;
}

.nav-button[disabled] {
  color: crimson;
}

.calculation-method { 
  background: linear-gradient(to top, #abbaab ,#ffffff); 
}

@include addPseudoClasses('.calculation-method', #344334);

h1 {
  text-align: center;
  margin: 20px 0 30px;
  letter-spacing: 2px;
}

.attention {
  background: linear-gradient(to top, darken(#ED4264, $lightChange), #FFEDBC);
  text-transform: uppercase;
  color: white;
}

@include addPseudoClasses('.attention', red);

.invalid-input {
  border-color: red !important;
  background-color: pink !important;
}

input[type=text] {
  border-radius: $borderRadius !important;
  box-shadow: inset 1px 1px 0 black;
  padding-left: 20px;
  font-weight: 900;
}

完整的项目代码在GitHub上:https://github.com/mizech/simple-calculator

如果有人喜欢看第二个应用的代码:https://github.com/mizech/weather-app

如果有人知道导致问题的原因是什么,那么我会非常感谢它作为答案。

2 个答案:

答案 0 :(得分:4)

只需使用浏览器控制台打开应用程序,您将看到一条错误消息(或在桌面上的Safari上打开它):

  

SyntaxError:意外的标识符&#39; item&#39;

这是由let item = this.refs.inputElement;引起的。并非所有浏览器都支持ES6。您必须使用Babel或Google Traceur将ES6转换为ES5。

答案 1 :(得分:1)

问题似乎是由于您测试的移动浏览器无法读取您指定的某些css属性。添加供应商前缀应该可以解决问题。

例如,当您使用Chrome浏览器时,您的网页在Android手机上呈现正常,但使用三星股票互联网浏览器时,只能看到渐变背景。