我用React制作了这个应用程序:
现场演示: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
如果有人知道导致问题的原因是什么,那么我会非常感谢它作为答案。
答案 0 :(得分:4)
只需使用浏览器控制台打开应用程序,您将看到一条错误消息(或在桌面上的Safari上打开它):
SyntaxError:意外的标识符&#39; item&#39;
这是由let item = this.refs.inputElement;
引起的。并非所有浏览器都支持ES6。您必须使用Babel或Google Traceur将ES6转换为ES5。
答案 1 :(得分:1)
问题似乎是由于您测试的移动浏览器无法读取您指定的某些css属性。添加供应商前缀应该可以解决问题。
例如,当您使用Chrome浏览器时,您的网页在Android手机上呈现正常,但使用三星股票互联网浏览器时,只能看到渐变背景。