前端

H5开发学习

2018-10-17  本文已影响82人  loongod

依赖库介绍

React

react 用于构建用户界面的JavaScript库。

React主要用于构建UI,很多人认为 React 是 MVC 中的 V(视图)。
React 起源于 Facebook 的内部项目,用来架设 Instagram 的网站,并于 2013 年 5 月开源。
React 拥有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和使用它。

React.png

Yarn

yarn 快速、可靠、安全的依赖管理工具。

Yarn 对你的代码来说是一个包管理器, 你可以通过它使用全世界开发者的代码, 或者分享自己的代码。Yarn 做这些快捷、安全、可靠,所以你不用担心什么。

通过Yarn你可以使用其他开发者针对不同问题的解决方案,使自己的开发过程更简单。 使用过程中遇到问题,你可以将其上报或者贡献解决方案。一旦问题被修复, Yarn会更新保持同步。

代码通过 包(package) (或者称为 模块(module)) 的方式来共享。 一个包里包含所有需要共享的代码,以及描述包信息的文件,称为 package.json 。

Mock

mock 生成随机数据,拦截Ajax请求。

mock.png

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世界的构建工具。

grunt工具.png

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下

本地调试模式开发配置

按以下步骤:

  1. /resources/redux/文件夹下

  2. 安装依赖:yarn install
    使用yarn需要先安装:brew install yarn

  3. 起前端react服务:yarn start

  4. 起mock服务(假数据):yarn mock

  5. 之后访问localhost:8080 即可

起node服务模式开发配置

配置前须知:

node是管理路由,不管是react还是vue写页面都和node没关系。
如果使用react或者redux写号模块之后,还需要配置node的路由。

按以下步骤:

  1. 安装node (8.9.1) ,node版本需要是8.9.1或者以上
    在mac上安装node.js参考

  2. 安装nodemon:npm install nodemon -g

  3. 安装n模块:npm install n -g 用于管理node的版本
    最好安装,用来选择node的版本到8.9.1

  4. 到工程根目录:yarn install
    使用yarn需要先安装:brew install yarn

  5. 根目录 递归更新子模块 (可以不用递归)
    git submodule update --init --recursive

  6. 然后需要安装redis,如果没有安装brew的话搜索其它方式安装
    brew install redis

  7. 然后启动redis
    brew services start redis

  8. 去assets文件夹下 打包静态资源
    grunt
    使用grunt需要先安装:npm install grunt -g

  9. 去static文件夹下,先安装依赖
    yarn install
    然后打包静态资源
    gulp
    使用gulp需要先安装: npm install gulp -g

  10. 在起node服务前,还需要在本地host文件中添加一个域名解析
    mac下/etc/hosts文件,添加
    127.0.0.1 devm.qdingnet.com

sudo yarn watch

  1. 静态资源打包后,起node服务
    sudo nodemon --watch app server.js
    使用nodemon需要先安装:npm install nodemon -g

  2. 之后访问localhost:9000即可


知识点

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. 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,一些标识符像 classfor 不建议作为 XML 属性名。作为替代,React DOM 使用 classNamehtmlFor 来做对应的属性。

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])

关于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])

replaceState()方法与setState()类似,但是方法只会保留nextState中状态,原state不在nextState中的状态都会被删除。

设置属性:setProps
setProps(object nextProps[, function callback])

设置组件属性,并重新渲染组件。
props相当于组件的数据流,它总是会从父组件向下传递至所有的子组件中。当和一个外部的JavaScript应用集成时,我们可能会需要向组件传递数据或通知React.render()组件需要重新渲染,可以使用setProps()。
更新组件,我可以在节点上再次调用React.render(),也可以通过setProps()方法改变组件属性,触发组件重新渲染。

替换属性:replaceProps
replaceProps(object nextProps[, function callback])

replaceProps()方法与setProps类似,但它会删除原有 props。

强制更新:forceUpdate
forceUpdate([function callback])

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中,该方法返回对应的本地浏览器 DOM 元素。当render返回null 或 false时,this.findDOMNode()也会返回null。从DOM 中读取值的时候,该方法很有用,如:获取表单字段的值和做一些 DOM 操作。

判断组件挂载状态:isMounted
bool isMounted()

isMounted()方法用于判断组件是否已挂载到DOM中。可以使用该方法保证了setState()和forceUpdate()在异步场景下的调用不会出错。

组件声明周期

组件的生命周期可分成三个状态:

生命周期的方法有:


有关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>
上一篇下一篇

猜你喜欢

热点阅读