- 1.块级元素独占一行,其宽度自动填满其父元素的宽;
- 2.行内元素不会独占一行,相邻的两个行内元素会排列在同一行,直到这一行排不下,才会换到下一行,宽度随着内容的宽度来变化,不会根据样式设置的宽高来变化;想要使行内元素设置的宽高样式起作用,可以设置display样式为block;
- 3.行内元素设置宽高样式不起作用的,只会随内容的宽高变化而变化;块级元素可以设置宽高样式;注意:块级元素即使设置了宽度,仍然是独占一行的;
- 4.将块级元素转换为行内元素,设置display的值为inline-block;
- 5.块级元素可以设置margin和padding;但行内元素的padding-left,padding-right,margin-left,margin-right都可以产生边距作用,但是padding-top,padding-bottom,margin-top,margin-bottom都不能产生边距效果,也就是说行内元素水平方向上起作用,垂直方向上没有作用;
- 6.display:inline-block 元素既可以在一行(行内元素特征),又可以设置宽高(块级元素特征);
- 7.块级元素设置宽高后,实际的宽高为:width+padding(左右的padding值)+border(左右的边框值);
- 8.margin与padding设置值的区别:
/*
padding margin 设置值的区别:
一个值:上下左右
两个值:上下 左右
三个值:上 左右 下
四个值:上 右 下 左
*/
- 9.选择器的区别:
/*
选择器:
通配符:* 代表所有的标签;
标签选择器:eg:div 代表所有的div标签;即所有的div都是用这个样式;
id选择器:id = “” 同一个页面不能有个多个标签使用同一个id选择器;唯一,以#开头;
类选择器:class = “” 同一个页面可以有个多个标签使用同一个class选择器;以.开头;eg: .log .empty-log :代表log类选择器下面的empty-log类选择器会应用这个样式;
标签选择器-类选择器结合使用的(span-title),指定某一个标签选择器(span)且指定类选择器(class=“title”)的样式;
div > p :指定div下面的p标签的样式的;
*/
- 10.undefine这个值代表这个变量没有值,null代表将这个变量的值清空;
- 11.JavaScript中number,string,boolean,null和undefine型数据都是值类型,由于值类型数据占据的空间都是固定的,所以可以把它们储存在狭窄的内存栈中;而object,function和array等对象都是引用数据类型;
- 12.js中创建对象的几种方式
//alert(typeof obj);
var num = 777;
console.log(typeof(num));
console.log(typeof num);
//创建对象的方式
//Object
var p = new Object();
p.name = "wanglu";
p.age = 18;
p.sayName = function(){
console.log("对象person的名字是:%s,年龄是:%i",this.name,this.age);
}
p.sayName();
//字面量创建对象方式
var p2 = {name:'wanglu2',age:28,sayName:function(){
console.log("对象person2的名字是:%s,年龄是:%i",this.name,this.age);
}}
p2.sayName();
//工厂方法创建对象
function sayName(){
console.log("对象的名字是:%s,年龄是:%i",this.name,this.age);
}
function createPerson(){
var o = new Object();
o.name = "wanglu3";
o.age = 30;
// o.sayName = function(){
// console.log("对象person3的名字是:%s,年龄是:%i",this.name,this.age);
// }
//下面这种方式,是将sayName定义为全局的方法,不能讲sayName()赋值给o.sayName,因为sayName()是结果值;
o.sayName = sayName ;
return o ;
}
var p3 = createPerson();
p3.sayName();
//构造函数创建对象
function Person(name,age){
this.name = name ;
this.age = age ;
this.sayName = function(){
console.log("构造函数创建对象的名字是:%s,年龄是:%i",this.name,this.age);
}
}
var p4 = new Person("wanglu5",55);
p4.sayName();
console.log(p4 instanceof Person);
//原型模式创建对象
function Person1(){
this.height = 100;
}
Person1.prototype.name = "wanglu6";
Person1.prototype.age = 66;
Person1.prototype.sayName = function(){
console.log("原型模式创建对象的名字是:%s,年龄是:%i,身高是:%i",this.name,this.age,this.height);
}
var p5 = new Person1();
p5.sayName();
var p6 = new Person1();
p6.name = "update";
p6.sayName();
console.log("----------继承的实现-------------------")
//继承的实现
function Student(){
Person1.call(this);
}
Student.prototype = new Person1();
//如果使用这样继承,那么上面Person1中的height就无法继承
//Student.prototype = Person1.prototype;
var stu = new Student();
stu.sayName();
//使用构造函数继承--call或者apply
function Studen2(){
//继承构造函数中已有的属性,不能继承使用原型生成的属性
Student.call(this);
}
//继承函数
Studen2.prototype = new Student();
var s2 = new Studen2();
//s2.sayName();
console.log(s2.height);//100
//注意:call只能继承构造函数中自带的一些属性和函数,
//不能继承通过prototype指定的属性与函数;
//也就是说借助构造函数来实现继承,方法在构造函数中定义,那么函数复用是个问题;
console.log(s2.age);
//注意:在父类原型中定义的函数,对于子类是不可见的,需要使用原型继承即可使用里面的函数;继承原型后,子类能够拿到构造函数中声明的属性和方法;
s2.sayName();//
console.log("---------------组合继承--------------");
function SuperType(name){
this.name = name ;
this.colors = ['red','green','blue'];
}
SuperType.prototype.sayName = function(){
console.log("-----组合继承------->"+this.name);
}
function SubType(name,age){
//继承构造函数中已有的属性
SuperType.call(this,name);
this.age = age ;
}
//继承函数
SubType.prototype = new SuperType();
//指定下构造函数,如果不指定,继承原型后,构造函数会变成SuperType
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
console.log("------组合继承----sayAge---->"+this.age);
}
var sub = new SubType("组合继承1",188);
sub.sayName();
sub.sayAge();
sub.colors.push("yellow");
console.log(sub.colors);//['red','green','blue','yellow'];
var sub2 = new SubType("组合继承2",18888);
sub.sayName();
sub.sayAge();
console.log(sub.colors);//['red','green','blue'];
- 注意:原型继承的问题?
1.当原型中的属性是引用数据类型(比如数组)时,这些引用属性会被所有实例共享; 如果是值类型的话,没有这个问题;
2.如果使用构造函数继承,引用类型属性和值类型都不会共享;
3.通过构造函数继承,那么在构造函数中定义的方法,不能被继承的子类使用,那么复用问题;
4.为了解决原型中引用类型的共享和构造函数继承方法继承复用的问题,一般都是使用组合继承;
- 13.样式的使用
/*log和empty都会使用这个样式*/
.log .empty-log{
display:inline-block;
padding: 50px 50px;
}
/*log下的empty-log会使用这个样式*/
.log > .empty-log{
display:inline-block;
padding:50px 50px;
}
- 14.bind的使用:来改变执行的上下文
import React, {Component} from 'react';
import '../App.css'
import DisplayLog from './DisplayLog';
import Button from './Button';
import FormatTime from '../utlis/FormatTime';
export default class TimeDisplay extends Component {
constructor(props) {
super(props);
this.state = {
time: 0,
on: false,
logArray:[]
}
}
buttonToggle() {
//已经开始了,取消正在运行的timer
if (this.state.on) {
clearInterval(this.timer);
} else {
//否则开启定时器
//计时器
this.timer = setInterval(() => {
this.setState({
time: this.state.time + 1,
});
}, 10);
}
//等价上面的写法:下面的bind(this)用来改变函数的上下文环境
// setInterval(function () {
// this.setState({
// time:this.state.time+1,
// })
// }.bind(this), 10);
this.setState({
on: !this.state.on
})
}
buttonTogggle1 = () => {
//计时器
setInterval(() => {
this.setState({
time: this.state.time + 1,
})
}, 10);
//等价上面的写法:下面的bind(this)用来改变函数的上下文环境
// setInterval(function () {
// this.setState({
// time:this.state.time+1,
// })
// }.bind(this), 10);
};
resetTime(){
console.log("--------resetTime---------")
if(this.timer) {
clearInterval(this.timer)
}
this.setState({
time: 0,
on: false,
logArray:[]
})
}
//记录时间
handleLogTime = ()=>{
//存储在数组中
//数组的创建两种方式
// let a = [];
// let b = new Array();
//数组的元素赋值
this.state.logArray.push(this.state.time);//添加到数组中
console.log(this.state.logArray);
};
//清空函数:这种写法,下面可以直接使用onClick={ this.cleanLog}调用或者()=>this.cleanLog();注意不用写括号:onClick={ this.cleanLog()},如果这样写,代表已经执行;
//如果需要给cleanLog传递参数,那么在调用的时候必须使用()=>this.cleanLog(xxx)此种方式才行;
cleanLog = ()=>{
console.log("--------清空-------");
this.setState({logArray:[]})
};
render() {
let time = FormatTime(this.state.time);
return (
<div className="Container">
<h1>{time==0?'00:00:00.00':time}</h1>
<div className="ButtonContainer">
{/*这个地方必须要使用bind(this):因为把buttonToggle函数传到Button组件中,this代表的是Button组件的上下文
,这里使用bind(this),来指定上下文为TimeDisplay的上下文;如果不bind,将报出setState undefine;如果不这样写,
写成箭头函数形式的即可;或者下面的调用不变,而是将将buttonTggle改写成箭头函数*/}
<Button styles="success" text={this.state.on ? "暂停" : "开始"} onClick={this.buttonToggle.bind(this)}/>
{/*这样写,必须写上括号:前后都必须带括号;onClick={()=>this.resetTime()*/}
<Button styles="warn" text="重置" onClick={()=>this.resetTime()}/>
{/*或者下面的调用不变,而是将buttonTggle改写成箭头函数*/}
<Button styles="primary" text="记录" onClick={this.handleLogTime}/>
{/*{如果没有参数的话,可以直接使用this.cleanLog或者使用()=>this.cleanLog(),这两种调用方式都行}*/}
{/*<Button styles="success" text="清空" onClick={ this.cleanLog} />*/}
<Button styles="success" text="清空" onClick={ ()=>this.cleanLog('清空')}/>
</div>
<DisplayLog logArray = {this.state.logArray} />
</div>
)
}
}