依赖库介绍
React
react 用于构建用户界面的JavaScript库。
React主要用于构建UI,很多人认为 React 是 MVC 中的 V(视图)。
React 起源于 Facebook 的内部项目,用来架设 Instagram 的网站,并于 2013 年 5 月开源。
React 拥有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和使用它。
Yarn
yarn 快速、可靠、安全的依赖管理工具。
Yarn 对你的代码来说是一个包管理器, 你可以通过它使用全世界开发者的代码, 或者分享自己的代码。Yarn 做这些快捷、安全、可靠,所以你不用担心什么。
通过Yarn你可以使用其他开发者针对不同问题的解决方案,使自己的开发过程更简单。 使用过程中遇到问题,你可以将其上报或者贡献解决方案。一旦问题被修复, Yarn会更新保持同步。
代码通过 包(package) (或者称为 模块(module)) 的方式来共享。 一个包里包含所有需要共享的代码,以及描述包信息的文件,称为 package.json 。
Mock
mock 生成随机数据,拦截Ajax请求。
Faker
faker 在浏览器和node.js中生成大量虚假数据
Nodemon
nodemon 是一款非常实用的工具,用来监控你 node.js 源代码的任何变化和自动重启你的服务器。 Nodemon 是一款完美的开发工具,可以使用 npm 安装。
Redis
REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。
Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。
Webpack 工具
webpack,本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
Grunt 工具
GRUNT 是JavaScript世界的构建工具。
Gulp 工具
Gulp 是增强你工作流程的自动化构建工具!
n 工具
用来管理node版本的工具
安装:npm install n -g
安装指定版本
n 8.9.1
安装最新版本
n latest
安装稳定版本
n stable
切换版本
直接输入n后输出当前已经安装的node版本以及正在使用的版本(前面有一个o),你可以通过移动上下方向键来选择要使用的版本,最后按回车生效。注:要在root权限下切换方可生效
n
8.9.1
o 8.9.1
查看当前版本在node所有版本中的位置
n ls
删除某个版本
n rm 8.9.1
环境配置
配置环境起服务过程中,有可能会出现8080端口被占用的错误
查看8080端口使用情况
sudo lsof -i -P | grep 8080
新建模块必须在app/modules/下,添加相同的模块(里面是路由和服务配置)。
assets resources static 静态资源 给app用
css 放在src/less下
本地调试模式开发配置
按以下步骤:
到
/resources/redux/
文件夹下安装依赖:
yarn install
使用yarn需要先安装:brew install yarn
起前端react服务:
yarn start
起mock服务(假数据):
yarn mock
之后访问
localhost:8080
即可
知识点
div标签
标签定义及使用说明
<div> 标签定义 HTML 文档中的一个分隔区块或者一个区域部分。
<div>标签常用于组合块级元素,以便通过 CSS 来对这些元素进行格式化。
Value = undefined
在计算机程序中,经常会声明无值的变量。未使用值来声明的变量,其值实际上是undefined。
//在执行以下语句后,变量carname的值将是undefined;
var varname;
let 和 var
let允许你声明一个作用域被限制在块级中的变量、语句或者表达式。在Function中局部变量推荐使用let变量,避免变量名冲突。
作用域规则
let 声明的变量只在其声明的块或子块中可用,这一点,与var相似。二者之间最主要的区别在于var声明的变量的作用域是整个封闭函数。
function varTest() {
var x = 1;
if (true) {
var x = 2; // 同样的变量!
console.log(x); // 2
}
console.log(x); // 2
}
function letTest() {
let x = 1;
if (true) {
let x = 2; // 不同的变量
console.log(x); // 2
}
console.log(x); // 1
}
JavaScript对象
是属性和方法的容器;
对象的属性之间一定要用逗号隔开;
对象的方法定义了一个函数,并作为对象的属性存储。
对象方法通过添加()调用(作为一个函数)。
eg:
var person={
"name":"小明",
"age":"18",
"like":function(){
return "喜欢打篮球,弹吉他";
}
}
//调用
person.like;
javaScript对象也可以先创建,再添加属性和属性值,
eg:
var person=new Object();
person.name='小明';
person.sex='男';
person.method=function(){
return this.name+this.sex;
}
javaScript对象中属性具有唯一性(这里的属性包括方法),如果有两个重复的属性,则以最后赋值为准。比如同时存在两个play:
var person = {
name: "小明",
age: 18,
sex: "男",
play: "football",
play: function () {
return "like paly football";
}
};
全局JavaScript变量 和 JavaScript 变量的生存期
在函数外声明的变量是全局变量,网页上的所有脚本和函数都能访问它。
JavaScript 变量的生命期从它们被声明的时间开始。
局部变量会在函数运行以后被删除。
全局变量会在页面关闭后被删除。
向未声明的 JavaScript 变量分配值
如果您把值赋给尚未声明的变量,该变量将被自动作为 window 的一个属性。
这条语句:carname="Volvo";
将声明 window 的一个属性 carname。
非严格模式下给未声明变量赋值创建的全局变量,是全局对象的可配置属性,可以删除。
var var1 = 1; // 不可配置全局属性
var2 = 2; // 没有使用 var 声明,可配置全局属性
console.log(this.var1); // 1
console.log(window.var1); // 1
delete var1; // false 无法删除
console.log(var1); //1
delete var2;
console.log(delete var2); // true
console.log(var2); // 已经删除 报错变量未定义
ES6新增箭头函数
定义函数时更加简洁、易读。
// 传统定义函数方式
function Test () {
//
}
const Test = function () {
//
}
// 使用箭头函数定义函数时可以省略 function 关键字
const Test = (...params) => {
//
}
// 该函数只有一个参数时可以简写成:
const Test = param => {
return param;
}
console.log(Test('hello')); // hello
=== 比较
为绝对相等,即数据类型与值都必须相等。
条件运算符
JavaScript 还包含了基于某些条件对变量进行赋值的条件运算符。
//语法:
variablename=(condition)?value1:value2
//eg:
voteable=(age<18)?"年龄太小":"年龄已达到";
事件冒泡或事件捕获
事件传递有两种方式:冒泡和捕获。
事件传递定义了元素事件触发的顺序。 如果你将 <p> 元素插入到 <div> 元素中,用户点击 <p> 元素, 哪个元素的 "click" 事件先被触发呢?
在 冒泡 中,内部元素的事件会先被触发,然后再触发外部元素,即: <p> 元素的点击事件先触发,然后会触发 <div> 元素的点击事件。
在 捕获 中,外部元素的事件会先被触发,然后才会触发内部元素的事件,即: <div> 元素的点击事件先触发 ,然后再触发 <p> 元素的点击事件。
addEventListener()
方法可以指定"useCapture"
参数来设置传递类型:
addEventListener(event, function, useCapture);
默认值为 false, 即冒泡传递,当值为 true 时, 事件使用捕获传递。
实例
document.getElementById("myDiv").addEventListener("click", myFunction, true);
方法 | 说明 | |
---|---|---|
getElementsByTagName() | 返回HTMLCollection对象,HTMLCollection 对象类似 HTML 元素的一个数组 | 以下代码获取文档所有的 <p> 元素:var x = document.getElementsByTagName("p"); 集合中的元素可以通过索引(以 0 为起始位置)来访问。访问第二个 <p> 元素可以是以下代码:y = x[1];
|
HTMLCollection 对象
getElementsByTagName() 方法返回 HTMLCollection 对象。
HTMLCollection 对象类似 HTML 元素的一个数组。
以下代码获取文档所有的 <p> 元素:
实例:var x = document.getElementsByTagName("p");
集合中的元素可以通过索引(以 0 为起始位置)来访问。
访问第二个 <p> 元素可以是以下代码:
y = x[1];
HTMLCollection 对象的 length 属性定义了集合中元素的数量。
var myCollection = document.getElementsByTagName("p");
document.getElementById("demo").innerHTML = myCollection.length;
注意
HTMLCollection 不是一个数组!
HTMLCollection 看起来可能是一个数组,但其实不是。
你可以像数组一样,使用索引来获取元素。
HTMLCollection 无法使用数组的方法: valueOf()
,pop()
, push()
, 或 join()
。
JavaScript HTML DOM 节点列表
NodeList 对象是一个从文档中获取的节点列表 (集合) 。
NodeList 对象类似 HTMLCollection 对象。
一些旧版本浏览器中的方法(如:getElementsByClassName())返回的是 NodeList 对象,而不是 HTMLCollection 对象。
所有浏览器的 childNodes 属性返回的是 NodeList 对象。
大部分浏览器的 querySelectorAll() 返回 NodeList 对象。
以下代码选取了文档中所有的 <p> 节点:
var myNodeList = document.querySelectorAll("p");
NodeList 中的元素可以通过索引(以 0 为起始位置)来访问。
访问第二个 <p> 元素可以是以下代码:
y = myNodeList[1];
NodeList 对象 length 属性
NodeList 对象 length 属性定义了节点列表中元素的数量。
var myNodelist = document.querySelectorAll("p");
document.getElementById("demo").innerHTML = myNodelist.length;
HTMLCollection 与 NodeList 的区别
HTMLCollection是 HTML 元素的集合。
NodeList 是一个文档节点的集合。
NodeList 与 HTMLCollection 有很多类似的地方。
NodeList 与 HTMLCollection 都与数组对象有点类似,可以使用索引 (0, 1, 2, 3, 4, ...) 来获取元素。
NodeList 与 HTMLCollection 都有 length 属性。
HTMLCollection 元素可以通过 name,id 或索引来获取。
NodeList 只能通过索引来获取。
只有 NodeList 对象有包含属性节点和文本节点。
节点列表不是一个数组!
节点列表看起来可能是一个数组,但其实不是。
你可以像数组一样,使用索引来获取元素。
节点列表无法使用数组的方法: valueOf(), pop(), push(), 或 join() 。
React知识点
Axios
Ajax
ExtractText
ESlint
FSA(Flux Standard Action)
redux-action、redux-promise、redux-sagas、redux-observable
感兴趣的建议学习,思考下未来是否可能整合
React 特点
1.声明式设计 −React采用声明范式,可以轻松描述应用。
2.高效 −React通过对DOM的模拟,最大限度地减少与DOM的交互。
3.灵活 −React可以与已知的库或框架很好地配合。
4.JSX − JSX 是 JavaScript 语法的扩展。React 开发不一定使用 JSX ,但我们建议使用它。
5.组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
6.单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。
学习
1. manifest.json指定了开始页面index.html,一切的开始都从这里开始。
2. setInterval(function, 1000);
1秒调用1次function方法。
3. React 只会更新必要的部分
值得注意的是 React DOM 首先会比较元素内容先后的不同,而在渲染过程中只会更新改变了的部分。
4. JavaScript表达式
我们可以在 JSX 中使用 JavaScript 表达式。表达式写在花括号 {} 中。实例如下:
ReactDOM.render(
<div>
<h1>{1+1}</h1>
</div>
,
document.getElementById('example')
);
在 JSX 中不能使用 if else 语句,但可以使用 conditional (三元运算) 表达式来替代。以下实例中如果变量 i 等于 1 浏览器将输出 true, 如果修改 i 的值,则会输出 false.
ReactDOM.render(
<div>
<h1>{i == 1 ? 'True!' : 'False'}</h1>
</div>
,
document.getElementById('example')
);
样式
React 推荐使用内联样式。我们可以使用 camelCase 语法来设置内联样式. React 会在指定元素数字后自动添加 px 。以下实例演示了为 h1 元素添加 myStyle 内联样式:
var myStyle = {
fontSize: 100,
color: '#FF0000'
};
ReactDOM.render(
<h1 style = {myStyle}>菜鸟教程</h1>,
document.getElementById('example')
);
注释
1、在标签内部的注释需要花括号
2、在标签外的的注释不能使用花括号
注释需要写在花括号中,实例如下:
ReactDOM.render(
<div>
<h1>我是标题</h1>
{/*注释...*/}
</div>,
document.getElementById('example')
);
ReactDOM.render(
/*注释 */
<h1>孙朝阳 {/*注释*/}</h1>,
document.getElementById('example')
);
数组
JSX 允许在模板中插入数组,数组会自动展开所有成员:
var arr = [
<h1>菜鸟教程</h1>,
<h2>学的不仅是技术,更是梦想!</h2>,
];
ReactDOM.render(
<div>{arr}</div>,
document.getElementById('example')
);
HTML 标签 vs React 组件
React 可以渲染 HTML 标签 (strings) 或 React 组件 (classes)。
要渲染 HTML 标签,只需在 JSX 里使用小写字母的标签名。
var myDivElement = <div className="foo" />;
ReactDOM.render(myDivElement, document.getElementById('example'));
要渲染 React 组件,只需创建一个大写字母开头的本地变量。
var MyComponent = React.createClass({/*...*/});
var myElement = <MyComponent someProperty={true} />;
ReactDOM.render(myElement, document.getElementById('example'));
React 的 JSX 使用大、小写的约定来区分本地组件的类和 HTML 标签。
注意:
由于 JSX 就是 JavaScript,一些标识符像class
和for
不建议作为 XML 属性名。作为替代,React DOM 使用className
和htmlFor
来做对应的属性。
React组件
封装一个输出"Hello World!"的组件,组件名为HelloMessage:
function HelloMessage(props) {
return <h1>Hello World!</h1>;
}
const element = <HelloMessage />;
ReactDOM.render(
element,
document.getElementById('example')
);
可以使用函数定义一个组件:
function HelloMessage(props) {
return <h1>Hello World!</h1>;
}
也可以使用ES6 class来定义一个组件:
class Welcome extends React.Component {
render() {
return <h1>Hello World!</h1>;
}
}
注意,原生 HTML 元素名以小写字母开头,而自定义的 React 类名以大写字母开头,比如 HelloMessage 不能写成 helloMessage。除此之外还需要注意组件类只能包含一个顶层标签,否则也会报错。
向组件传递参数,可以使用this.props对象,实例如下:
function HelloMessage(props) {
return <h1>Hello {props.name}!</h1>;
}
const element = <HelloMessage name="Runoob"/>;
ReactDOM.render(
element,
document.getElementById('example')
);
以上实例中 name 属性通过 props.name 来获取。
注意,在添加属性时, class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字。
复合组件
我们可以通过创建多个组件来合成一个组件,即把组件的不同功能点进行分离。
以下实例我们实现了输出网站名字和网址的组件:
function Name(props) {
return <h1>网站名称:{props.name}</h1>;
}
function Url(props) {
return <h1>网站地址:{props.url}</h1>;
}
function Nickname(props) {
return <h1>网站小名:{props.nickname}</h1>;
}
function App() {
return (
<div>
<Name name="菜鸟教程" />
<Url url="http://www.runoob.com" />
<Nickname nickname="Runoob" />
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById('example')
);
实例中 App 组件使用了 Name、Url 和 Nickname 组件来输出对应的信息。
React Props
state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。这就是为什么有些容器组件需要定义 state 来更新和修改数据。 而子组件只能通过 props 来传递数据。
使用props
function HelloMessage(props) {
return <h1>Hello {props.name}!</h1>;
}
const element = <HelloMessage name="Runoob"/>;
ReactDOM.render(
element,
document.getElementById('example')
);
默认 Props
你可以通过组件类的 defaultProps 属性为 props 设置默认值,实例如下:
class HelloMessage extends React.Component {
render() {
return (
<h1>Hello, {this.props.name}</h1>
);
}
}
HelloMessage.defaultProps = {
name: 'Runoob'
};
const element = <HelloMessage/>;
ReactDOM.render(
element,
document.getElementById('example')
);
很多情况下,子控件需要父控件所有的 props 参数,这个时候我们一个一个参数的写会很麻烦,比如:
<Name name={this.props.name} url={this.props.url} .../>
那么我们怎么样吧父属性直接赋值给子组件的props参数呢?如下写法即可:
<Name props={this.props}/>
这样写就非常简洁了,也就子控件和父控件都有了同样数据结构的 props 参数。
React 点击事件的 bind(this) 如何传参?
需要通过 bind 方法来绑定参数,第一个参数指向 this,第二个参数开始才是事件函数接收到的参数:
<button onClick={this.handleClick.bind(this, props0, props1, ...}></button>
handleClick(porps0, props1, ..., event) {
// your code here
}
事件:this.handleclick.bind(this,要传的参数)
函数:handleclick(传过来的参数,event)
React 列表 & Keys
我们可以使用 JavaScript 的 map() 方法来创建列表。
使用 map() 方法遍历数组生成了一个 1 到 5 的数字列表:
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((numbers) =>
<li>{numbers}</li>
);
ReactDOM.render(
<ul>{listItems}</ul>,
document.getElementById('example')
);
Keys
Keys 可以在 DOM 中的某些元素被增加或删除的时候帮助 React 识别哪些元素发生了变化。因此你应当给数组中的每一个元素赋予一个确定的标识。
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li key={number.toString()}>
{number}
</li>
);
一个元素的 key 最好是这个元素在列表中拥有的一个独一无二的字符串。通常,我们使用来自数据的 id 作为元素的 key:
const todoItems = todos.map((todo) =>
<li key={todo.id}>
{todo.text}
</li>
);
当元素没有确定的 id 时,你可以使用他的序列号索引 index 作为 key:
const todoItems = todos.map((todo, index) =>
// 只有在没有确定的 id 时使用
<li key={index}>
{todo.text}
</li>
);
如果列表可以重新排序,我们不建议使用索引来进行排序,因为这会导致渲染变得很慢。
React 组件 API
设置状态:setState
setState(object nextState[, function callback])
- nextState,将要设置的新状态,该状态会和当前的state合并
- callback,可选参数,回调函数。该函数会在setState设置成功,且组件重新渲染后调用。
关于setState
不能在组件内部通过this.state修改状态,因为该状态会在调用setState()后被替换。
setState()并不会立即改变this.state,而是创建一个即将处理的state。setState()并不一定是同步的,为了提升性能React会批量执行state和DOM渲染。
setState()总是会触发一次组件重绘,除非在shouldComponentUpdate()中实现了一些条件渲染逻辑。
class Counter extends React.Component{
constructor(props) {
super(props);
this.state = {clickCount: 0};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({
clickCount: this.state.clickCount + 1
});
}
render () {
return (<h2 onClick={this.handleClick}>点我!点击次数为: {this.state.clickCount}</h2>);
}
}
ReactDOM.render(
<Counter />,
document.getElementById('example')
);
替换状态:replaceState
replaceState(object nextState[, function callback])
- nextState,将要设置的新状态,该状态会替换当前的state。
- callback,可选参数,回调函数。该函数会在replaceState设置成功,且组件重新渲染后调用。
replaceState()方法与setState()类似,但是方法只会保留nextState中状态,原state不在nextState中的状态都会被删除。
设置属性:setProps
setProps(object nextProps[, function callback])
- nextProps,将要设置的新属性,该状态会和当前的props合并
- callback,可选参数,回调函数。该函数会在setProps设置成功,且组件重新渲染后调用。
设置组件属性,并重新渲染组件。
props相当于组件的数据流,它总是会从父组件向下传递至所有的子组件中。当和一个外部的JavaScript应用集成时,我们可能会需要向组件传递数据或通知React.render()组件需要重新渲染,可以使用setProps()。
更新组件,我可以在节点上再次调用React.render(),也可以通过setProps()方法改变组件属性,触发组件重新渲染。
替换属性:replaceProps
replaceProps(object nextProps[, function callback])
- nextProps,将要设置的新属性,该属性会替换当前的props。
- callback,可选参数,回调函数。该函数会在replaceProps设置成功,且组件重新渲染后调用。
replaceProps()方法与setProps类似,但它会删除原有 props。
强制更新:forceUpdate
forceUpdate([function callback])
- callback,可选参数,回调函数。该函数会在组件render()方法调用后调用。
forceUpdate()方法会使组件调用自身的render()方法重新渲染组件,组件的子组件也会调用自己的render()。但是,组件重新渲染时,依然会读取this.props和this.state,如果状态没有改变,那么React只会更新DOM。
forceUpdate()方法适用于this.props和this.state之外的组件重绘(如:修改了this.state后),通过该方法通知React需要调用render()
一般来说,应该尽量避免使用forceUpdate(),而仅从this.props和this.state中读取状态并由React触发render()调用。
获取DOM节点:findDOMNode
DOMElement findDOMNode()
- 返回值:DOM元素DOMElement
如果组件已经挂载到DOM中,该方法返回对应的本地浏览器 DOM 元素。当render返回null 或 false时,this.findDOMNode()也会返回null。从DOM 中读取值的时候,该方法很有用,如:获取表单字段的值和做一些 DOM 操作。
判断组件挂载状态:isMounted
bool isMounted()
- 返回值:true或false,表示组件是否已挂载到DOM中
isMounted()方法用于判断组件是否已挂载到DOM中。可以使用该方法保证了setState()和forceUpdate()在异步场景下的调用不会出错。
组件声明周期
组件的生命周期可分成三个状态:
- Mounting:已插入真实 DOM
- Updating:正在被重新渲染
- Unmounting:已移出真实 DOM
生命周期的方法有:
componentWillMount 在渲染前调用,在客户端也在服务端。
componentDidMount : 在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异步操作阻塞UI)。
componentWillReceiveProps 在组件接收到一个新的 prop (更新后)时被调用。这个方法在初始化render时不会被调用。
shouldComponentUpdate 返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。
可以在你确认不需要更新组件时使用。componentWillUpdate在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。
componentDidUpdate 在组件完成更新后立即调用。在初始化时不会被调用。
componentWillUnmount在组件从 DOM 中移除之前立刻被调用。
有关CSS
CSS 选择器
1. id选择器 (id selector, IS)
id选择器可以为标有特定id的HTML元素指定特定的样式。
HTML元素以id属性来设置id选择器,CSS中id选择器以"#"来定义。
以下的样式规则应用于元素属性 id="para1":
#para1
{
text-align:center;
color:red;
}
注意: ID属性不要以数字开头,数字开头的ID在 Mozilla/Firefox 浏览器中不起作用。
2. class选择器 (class selector, CS)
class 选择器用于描述一组元素的样式,class 选择器有别于id选择器,class可以在多个元素中使用。
class 选择器在HTML中以class属性表示, 在 CSS 中,类选择器以一个点"."号显示:
在以下的例子中,所有拥有 center 类的 HTML 元素均为居中。
.center {text-align:center;}
3. 标签选择器(element selector, AS)
即以 html 标签作为 css 修饰所用的选择器。
<style>
h3{
color:red;
}
</style>
<h3>菜鸟教程</h3>
4. 直接在标签内部写css代码 (attribute selector,AS)
<h3 style="color:red;">菜鸟教程</h3>
这四种 css 选择器有修饰上的优先级。
选择器的优先级:第四种 > id > class > 第三种
5. 包含选择器(package selector, PS)
指定目标选择器必须处在某个选择器对应的元素内部,语法格式:A B{...}(A、B为HTML元素/标签,表示对处于A中的B标签有效)。
例:以下div内的p标签和div外的p标签分别匹配不同的样式
<style>
p{
color:red;
}
div p{
color:yellow;
}
</style>
<p>red text</p><!--文字是红色的-->
<div>
<p>yellow text</p><!--文字是黄色的-->
</div>
6. 子选择器(sub-selector, SS)
类似于包含选择器,指定目标选择器必须处在某个选择器对应的元素内部,两者区别在于包含选择器允许"子标签"甚至"孙子标签"及嵌套更深的标签匹配相应的样式,而子选择器强制指定目标选择器作为 包含选择器对应的标签 内部的标签,语法格式:A>B{...}(A、B为HTML元素/标签)。
例:以下div内的p标签匹配样式,div内的table内的p不匹配
<style>
div>p{
color:red;
}
</style>
<div>
<p>red text</p><!--文字是红色的-->
<table>
<tr>
<td>
<p>no red text;</p><!--文字是非红色的-->
</td>
</tr>
</table>
</div>
子选择器除了有A >B{...} 的形式外(A和B都是标签),还可以有这种形式:.A >B{...} 的形式(A是类名,B是标签)。
作用与上面介绍的相同,会使 class 为 A 的标签里面所有名为 B 的直接子代标签的内容按照设定的内容显示。而非直接子代的 B 标签的内容是不会改变的。
7. 兄弟选择器(brother selector, BS)
兄弟选择器是CSS3.0新增的一个选择器,语法格式:A~B{...}(A、B为HTML元素/标签,表示A标签匹配selector的A,B标签匹配selector的B时,B标签匹配样式),即紧跟A后的B会匹配样式。
<style>
div~p{
color:red;
}
</style>
<div>
<p>no red text</p><!--文字是非红色的-->
<div>no red text</div>
<p>red text</p><!--文字是红色的-->
</div>