您的位置:首页 > Web前端 > JavaScript

Python全栈开发【Javascript】

2020-01-12 19:00 344 查看

Python全栈开发【Javascript】

本节内容:

  • Javascript 概述

  • Javascript基础

  • 控制语句

  • 函数

  • 面向对象

  • JS补充

  • BOM对象

  • DOM对象

  • 实例练习

Javascript概述

 

1、概念

javascript是一门动态弱类型的解释型编程语言,增强页面动态效果,实现页面与用户之间的实时动态的交互。

 

javascript是由三部分组成:ECMAScript、DOM、BOM

 

  • ECMAScript由ECMA-262定义,提供核心语言功能(ECMA是欧洲计算机制造商协会)
  • DOM(Document Object Model)文档对象模型,提供访问和操作网页内容的方法和接口
  • BOM(Browser Object Model)浏览器对象模型,提供与浏览器交互的方法和接口

2、注释

JavaScript中代码注释:

  • 单行 //
  • 多行 /*  */

3、引入文件

理论上放在body和head中都可以,但是推荐放在body代码块底部,因为Html代码是从上到下执行,如果Head中的js代码耗时严重,就会导致用户长时间无法看到页面,如果放置在body代码块底部,那么即使js代码耗时严重,也不会影响用户看到页面效果,只是js实现特效慢而已。

Js代码可以放在一个单独的文件中,然后通过 <script src="common.js" type="text/javascript"></script>可以将其导入进来,或者直接在html文件中直接书写代码,如下面所示,其中两种方式的 type都可以不用写,因为浏览器默认的便是javascript

<script type="text/javascript">
Js代码内容
</script>
Javascript基础

一、变量

JavaScript中变量的声明是一个非常容易出错的点,局部变量必须一个 var 开头,如果未使用var,则默认表示声明的是全局变量。

name = 'alex';                  //不加var 定义的是全局变量
function f1() {
//name = 123 ;             // 不加var 函数里面修改的还是全局变量
var name = 'ocean'         // 加var 函数里面修改的是局部变量
}

二、数据类型

1、数字类型(Number)

最基本的数据类型,不区分整型数值和浮点型数值,所有数字都采用64位浮点格式存储,相当于Java和C语言中的double格式。
var num1 = new Number(123); //创建了一个数字类型的对象
var num3 = Number(456);   // 456
var num2 = 666;

var s1 = 's123';
var num4 = parseInt(s1);

console.log(num1.valueOf(),num2,num3);
console.log(num4);  // NaN
if(isNaN(num4)){
console.log('not a number');  // not a number
}
else {
console.log('a number');
}
console.log(isFinite(num3));    // 是否是有限值 true   Infinity表示无穷大。
console.log(typeof num3);      // 'number' 返回的是字符串
     var a = 1222.4444444;
     console.log(a.toFixed(2));       // 1222.44
     console.log(a.toExponential(3)); // 1.222e+3 

2、字符串

 

  • 字符串是由Unicode字符、数字、标点符号组成的序列

  • 字符串常量首尾由单引号或双引号括起 JavaScript中没有字符类型

  • 常用特殊字符在字符串中的表达

  • 字符串中部分特殊字符必须加上右划线\

  • 常用的转义字符 \n:换行 \':单引号 \":双引号 \\:右划线

//创建字符串对象两种方式
var str1='hello';
var str2=new String('hello2');

console.log(typeof str1);
console.log(typeof str2);
//字符串属性
console.log(str1.length);

//字符串的方法
console.log(str1.italics()); // <i>hello</i>
console.log(str1.bold()) ;// <b>hello</b>
console.log(str1.anchor()); //<a>

//索引查询
var str1='welcom to the world of JS!';
var str2=str.indexOf('l');
var str3=str.lastIndexOf('d');

//切片
console.log(str1.slice(1,3));

3、布尔型

布尔类型仅包含真假,与Python不同的是其首字母小写。下面来简单的看一下代码示例

var a = 123;
var s = '123';
console.log(a==s);      // true
console.log(a===s);     // false  判断值和类型一样 

4、Null & Undefined

Undefined 类型

Undefined 类型只有一个值,即 undefined。当声明的变量未初始化时,该变量的默认值是 undefined。

当函数无明确返回值时,返回的也是值 "undefined";

Null 类型

另一种只有一个值的类型是 Null,它只有一个专用值 null,即它的字面量。值 undefined 实际上是从值 null 派生来的,因此 ECMAScript 把它们定义为相等的。

尽管这两个值相等,但它们的含义不同。undefined 是声明了变量但未对其初始化时赋予该变量的值,null 则用于表示尚未存在的对象(在讨论 typeof 运算符时,简单地介绍过这一点)。如果函数或方法要返回的是对象,那么找不到该对象时,返回的通常是 null。

var person=new Person()

var person=null

5、数据类型转换

JavaScript属于松散类型的程序语言
变量在声明的时候并不需要指定数据类型
变量只有在赋值的时候才会确定数据类型
表达式中包含不同类型数据则在计算过程中会强制进行类别转换 数字 + 字符串:数字转换为字符串 数字 + 布尔值:true转换为1,false转换为0 字符串 + 布尔值:布尔值转换为字符串true或false

6、强制类型转换函数

函数parseInt:   强制转换成整数   例如parseInt("6.12")=6  ; parseInt(“12a")=12 ; parseInt(“a12")=NaN  ;parseInt(“1a2")=1

函数parseFloat: 强制转换成浮点数  parseFloat("6.12")=6.12

函数eval:       将字符串强制转换为表达式并返回结果 eval("1+1")=2 ; eval("1<2")=true

7、类型查询函数(typeof)

ECMAScript 提供了 typeof 运算符来判断一个值是否在某种类型的范围内。可以用这种运算符判断一个值是否表示一种原始类型:如果它是原始类型,还可以判断它表示哪种原始类型。

函数typeof :查询数值当前类型
 (string / number / boolean / object )
例如typeof("test"+3) "string"

例如typeof(null) "object "

例如typeof(true+1) "number"

例如typeof(true-false) "number"

三、运算符

1、ECMAScript算数运算符

 

加(+)、 减(-)、 乘(*) 、除(/) 、余数(% )  加、减、乘、除、余数和数学中的运算方法一样  例如:9/2=4.5,4*5=20,9%2=1

-除了可以表示减号还可以表示负号  例如:x=-y

+除了可以表示加法运算还可以用于字符串的连接  例如:"abc"+"def"="abcdef"

 

 递增(++) 、递减(--)

假如x=2,那么x++表达式执行后的值为3,x--表达式执行后的值为1
i++相当于i=i+1,i--相当于i=i-1
递增和递减运算符可以放在变量前也可以放在变量后:--i

var i=1;
console.log(i++);
console.log(++i);
console.log(i--);
console.log(--i);

2、ECMAScript逻辑运算符

 

等于 ( == )  、不等于( != ) 、 大于( > ) 、 小于( < ) 
大于等于(>=) 、小于等于(<=)
与 (&&) 、或(||) 、非(!)
1 && 1 = 1  1 || 1 = 1
1 && 0 = 0  1 || 0 = 1
0 && 0 = 0  0 || 0 = 0

!0=1
!1=0

 

逻辑 AND 运算符(&&)

逻辑 AND 运算的运算数可以是任何类型的,不止是 Boolean 值。

如果某个运算数不是原始的 Boolean 型值,逻辑 AND 运算并不一定返回 Boolean 值:

  • 如果一个运算数是对象,另一个是 Boolean 值,返回该对象。 
  • 如果两个运算数都是对象,返回第二个对象。 
  • 如果某个运算数是 null,返回 null。 
  • 如果某个运算数是 NaN,返回 NaN。 
  • 如果某个运算数是 undefined,返回undefined。

逻辑 OR 运算符(||)

与逻辑 AND 运算符相似,如果某个运算数不是 Boolean 值,逻辑 OR 运算并不一定返回 Boolean 值:

  • 如果一个运算数是对象,并且该对象左边的运算数值均为 false,则返回该对象。 
  • 如果两个运算数都是对象,返回第一个对象。 
  • 如果最后一个运算数是 null,并且其他运算数值均为 false,则返回 null。 
  • 如果最后一个运算数是 NaN,并且其他运算数值均为 false,则返回 NaN。 
  • 如果某个运算数是 undefined,返回undefined。 

 

 

3、ECMAScript 关系运算符(重要)

var bResult = "Blue" < "alpha";
alert(bResult); //输出 true  

在上面的例子中,字符串 "Blue" 小于 "alpha",因为字母 B 的字符代码是 66,字母 a 的字符代码是 97。

比较数字和字符串

另一种棘手的状况发生在比较两个字符串形式的数字时,比如:

var bResult = "25" < "3";
alert(bResult); //输出 "true"

上面这段代码比较的是字符串 "25" 和 "3"。两个运算数都是字符串,所以比较的是它们的字符代码("2" 的字符代码是 50,"3" 的字符代码是 51)。

不过,如果把某个运算数该为数字,那么结果就有趣了:

var bResult = "25" < 3;
alert(bResult); //输出 "false"

这里,字符串 "25" 将被转换成数字 25,然后与数字 3 进行比较,结果不出所料。

总结:

比较运算符两侧如果一个是数字类型,一个是其他类型,会将其类型转换成数字类型.
比较运算符两侧如果都是字符串类型,比较的是最高位的asc码,如果最高位相等,继续取第二位比较.

 

控制语句

1、条件语句

 

if(条件){

}else if(条件){

}else{

}

switch(name){
case '1':
age = 123;
break;
case '2':
age = 456;
break;
default :
age = 777;
}

 

2、循环语句

var names = ["aaa", "bbb", "ccc"];

for(var i=0;i<names.length;i++){
console.log(i);
console.log(names[i]);
}

var names = ["aaa", "bbb", "ccc"];

for(var index in names){
console.log(index);
console.log(names[index]);
}

while(条件){
// break;
// continue;

3、异常处理

try {
//这段代码从上往下运行,其中任何一个语句抛出异常该代码块就结束运行
}
catch (e) {
// 如果try代码块中抛出了异常,catch代码块中的代码就会被执行。
//e是一个局部变量,用来指向Error对象或者其他抛出的对象 主动跑出异常 throw Error('xxxx')
}
finally {
//无论try中代码是否有异常抛出(甚至是try代码块中有return语句),finally代码块中始终会被执行。
}
函数

1、函数类型

  JavaScript中函数基本上可以分为一下三类,普通函数,匿名函数,自执行函数,此外需要注意的是对于JavaScript中函数参数,实际参数的个数可能小于形式参数的个数,函数内的特殊值arguments中封装了所有实际参数。

// 普通函数
function func(arg){
return true;
}

// 匿名函数
var func = function(arg){
return "ocean";
}

// 自执行函数
(function(arg){
console.log(arg);
})('123')

2、函数作用域  

  JavaScript中每个函数都有自己的作用域,当出现函数嵌套时,就出现了作用域链。当内层函数使用变量时,会根据作用域链从内到外一层层的循环,如果不存在,则异常。下面就是一个简单其实就是简单的闭包。

name = 'ocean';
function f1() {
var name = 'kobe';
function f2() {
console.log(name);
}
return f2;
}
ret = f1();
ret();               //打印出kobe f2函数的作用域已经定死,上一级作用域为f1
面向对象
// 面向对象,没有class 用function定义
function Person(name,age) {
this.name = name;             // Person充当构造函数
this.age = age;               // this指代对象
}

// 使用原型保存类中的函数,如果放在person中,则每创建一个
// 对象都会在内存中创建一份,这样会浪费内存
Person.prototype = {
Show:function () {
console.log(this.name,this.age);
}
};

Person.prototype.Show2 = function () {
console.log(this.name,this.age)
};
person1 = new Person('ocean',18);
person1.Show();                    // ocean 18
person1.Show2()                    // ocean 18
JS补充

javascript补充 

  1. 为了强制使用var定义变量,可以在代码开始加上'use strict',这样未被var声明的变量将会报错,前提是浏览器支持该模式

  2. 可以用转义字符

    \,
    'I\'am "ok"'

  3. 要获取字符串某个指定位置的字符,可以使用s[1]下表进行操作, 如果对s[1] = 'f'赋值的话,不会报错,原字符串也不会改变。调用字符串的相关方法只会产生一个新的字符串

  4. 对数组进行操作,var f = [1,2],f[4] = 5,超过了数组长度,但是不会报错,相反数组f变成了 [1, 2, undefined × 2, 5]这一点需要特别注意,此外如果在pycharm中运行的话,不会出现上述情况但是会在数组中增加一个键值对。因此千万要注意自己操作数组的时候不要越界

  5. 数组切片,

    arr.slice(3)表示从索引3开始到结束,
    arr.slice(0, 3)表示从索引0开始,到索引3结束,arr.slice()可以复制一个数组。

  6. 对象,每个对象的属性用逗号分隔,访问不存在的属性会返回一个undefined,可以通过delete 删除某一属性,当然也可以直接动态的添加某一属性,要判断一个对象是否有某个属性,可以使用 in 比如 onsole.log('name' in xiaoming),但是这样可以能有一个问题,如果xiaoming继承了某一属性,那么判断这一属性也会成功,所以最好用 xiaoming.hasOwnProperty('name')

  7. 函数传参的时候,可以多传,也可以少传,少传的话,未被传入的参数会被定义为undefined,在函数内部用arguments获取到所有函数传入的参数,

  8. 函数内部的变量会"提前声明",具体的请看下面的代码

function foo() {
var x = 'Hello, ' + y;
alert(x);           // Hello, undefined
var y = 'Bob';
}
foo();

//    对于上述foo()函数,JavaScript引擎看到的代码相当于:
function foo() {
var y; // 提升变量y的申明
var x = 'Hello, ' + y;
alert(x);
y = 'Bob';

  9.不在任何函数内定义的变量就具有全局作用域,实际上,JavaScript默认有一个全局对象

window
,全局作用域的变量实际上被绑定到
window
的一个属性

var a = 'hello';
console.log(window.a);
console.log(a);

function foo() {
console.log('foo');
}
foo();
window.foo();

可以看到上面两种方式的执行效果一样,JavaScript实际上只有一个全局作用域。任何变量(函数也视为变量),如果没有在当前函数作用域中找到,就会继续往上查找,最后如果在全局作用域中也没有找到,则报ReferenceError错误。全局变量会绑定到

window
上,不同的JavaScript文件如果使用了相同的全局变量,或者定义了相同名字的顶层函数,都会造成命名冲突,并且很难被发现。减少冲突的一个方法是把自己的所有变量和函数全部绑定到一个全局属性中。例如:

// 唯一的全局属性MYAPP:
var MYAPP = {};

// 其他变量:
MYAPP.name = 'myapp';
MYAPP.version = 1.0;

// 其他函数:
MYAPP.foo = function () {
return 'foo';
};

 

  10. 

Array
sort()
方法默认把所有元素先转换为String再排序,结果
'10'
排在了
'2'
的前面,因为字符
'1'
比字符
'2'
的ASCII码小。

BOM对象

BOM(浏览器对象模型),可以对浏览器窗口进行访问和操作。使用 BOM,开发者可以移动窗口、改变状态栏中的文本以及执行其他与页面内容不直接相关的动作。

使 JavaScript 有能力与浏览器“对话”。

1、Windows对象

所有浏览器都支持 window 对象。

概念上讲.一个html文档对应一个window对象.

功能上讲: 控制浏览器窗口的.

使用上讲: window对象不需要创建对象,直接使用即可.

方法讲解:
//----------alert confirm prompt----------------------------
//alert('aaa');

/* var result = confirm("您确定要删除吗?");
alert(result); */

//prompt 参数1 : 提示信息.   参数2:输入框的默认值. 返回值是用户输入的内容.

// var result = prompt("请输入一个数字!","haha");
// alert(result);

方法讲解:
//open方法 打开和一个新的窗口 并 进入指定网址.参数1 : 网址.
//调用方式1
//open("http://www.baidu.com");
//参数1 什么都不填 就是打开一个新窗口.  参数2.填入新窗口的名字(一般可以不填). 参数3: 新打开窗口的参数.
open('','','width=200,resizable=no,height=100'); // 新打开一个宽为200 高为100的窗口
//close方法  将当前文档窗口关闭.
//close();
View Code

练习:

var num = Math.round(Math.random()*100);
function acceptInput(){
//2.让用户输入(prompt)    并接受 用户输入结果
var userNum = prompt("请输入一个0~100之间的数字!","0");
//3.将用户输入的值与 随机数进行比较
if(isNaN(+userNum)){
//用户输入的无效(重复2,3步骤)
alert("请输入有效数字!");
acceptInput();
}
else if(userNum > num){
//大了==> 提示用户大了,让用户重新输入(重复2,3步骤)
alert("您输入的大了!");
acceptInput();
}else if(userNum < num){
//小了==> 提示用户小了,让用户重新输入(重复2,3步骤)
alert("您输入的小了!");
acceptInput();
}else{
//答对了==>提示用户答对了 , 询问用户是否继续游戏(confirm).
var result = confirm("恭喜您!答对了,是否继续游戏?");
if(result){
//是 ==> 重复123步骤.
num = Math.round(Math.random()*100);
acceptInput();
}else{
//否==> 关闭窗口(close方法).
close();
}
}
View Code

定时器setInterval clearInterval(重要)

<input id="ID1" type="text" onclick="begin()">
<button onclick="end()">停止</button>

<script>

function showTime(){
var nowd2=new Date().toLocaleString();
var temp=document.getElementById("ID1");
temp.value=nowd2;

}

var clock;

function begin(){

if (clock==undefined){

showTime();
clock=setInterval(showTime,1000);

}

}

function end(){

clearInterval(clock);
}

</script>

setTimeout clearTimeout

var ID = setTimeout(abc,2000); // 只调用一次对应函数.
clearTimeout(ID);
function abc(){
alert('aaa');
}

2、History 对象

History 对象属性

History 对象包含用户(在浏览器窗口中)访问过的 URL。

History 对象是 window 对象的一部分,可通过 window.history 属性对其进行访问。

length  返回浏览器历史列表中的 URL 数量。

History 对象方法

back()    加载 history 列表中的前一个 URL。
forward()    加载 history 列表中的下一个 URL。
go()    加载 history 列表中的某个具体页面。
<a href="rrr.html">click</a>
<button onclick=" history.forward()">>>></button>
<button onclick="history.back()">back</button>
<button onclick="history.go()">back</button>

3、Location 对象

Location 对象包含有关当前 URL 的信息。

Location 对象是 Window 对象的一个部分,可通过 window.location 属性来访问。

Location 对象方法

location.assign(URL)
location.reload()
location.replace(newURL)//注意与assign的区别

 

DOM对象(重要)

二、增、删、改

增:

createElement(name)创建元素
appendChild();将元素添加

:

 

获得要删除的元素
获得它的父元素
使用removeChild()方法删除

 

:

第一种方式:

使用上面增和删结合完成修改

第二中方式:

使用setAttribute();方法修改属性          

使用innerHTML属性修改元素的内容

三、修改 HTML DOM 

  • 改变 HTML 内容 

        改变元素内容的最简答的方法是使用 innerHTML ,innerText。

  • 改变 CSS 样式
  • <p id="p2">Hello world!</p>
    document.getElementById("p2").style.color="blue";.style.fontSize=48px
  • 改变 HTML 属性 

        elementNode.setAttribute(name,value)

        elementNode.getAttribute(name)<-------------->elementNode.value(DHTML)

  • 创建新的 HTML 元素 

        createElement(name)

  • 删除已有的 HTML 元素 

        elementNode.removeChild(node)

  • 关于class的操作 

        elementNode.className

        elementNode.classList.add

        elementNode.classList.remove

实例练习

1 搜索框

<input id="ID1" type="text" value="请输入用户名" onblur="Blurs()" onfocus="Focus()">

<script>

function Focus(){

var input=document.getElementById("ID1");
if (input.value=="请输入用户名"){
input.value="";
}

};

function Blurs(){

var ele=document.getElementById("ID1");
var val=ele.value;
if(!val.trim()){

ele.value="请输入用户名";
}
}

</script>
View Code

2 模态对话框

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.back{
background-color: rebeccapurple;
height: 2000px;
}

.shade{
position: fixed;
top: 0;
bottom: 0;
left:0;
right: 0;
background-color: coral;
opacity: 0.4;
}

.hide{
display: none;
}

.models{
position: fixed;
top: 50%;
left: 50%;
margin-left: -100px;
margin-top: -100px;
height: 200px;
width: 200px;
background-color: gold;

}
</style>
</head>
<body>
<div class="back">
<input id="ID1" type="button" value="click" onclick="action('show')">
</div>

<div class="shade hide"></div>
<div class="models hide">
<input id="ID2" type="button" value="cancel" onclick="action('hide')">
</div>

<script>

function action(act){
var ele=document.getElementsByClassName("shade")[0];
var ele2=document.getElementsByClassName("models")[0];
if(act=="show"){
ele.classList.remove("hide");
ele2.classList.remove("hide");
}else {
ele.classList.add("hide");
ele2.classList.add("hide");
}

}
</script>
</body>
</html>
View Code

3 全选反选取消

<button onclick="select('all');">全选</button>
<button onclick="select('cancel');">取消</button>
<button onclick="select('reverse');">反选</button>

<table border="1" id="Table">
<tr>
<td><input type="checkbox"></td>
<td>111</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>222</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>333</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>444</td>
</tr>
</table>

<script>
function select(choice){
var ele=document.getElementById("Table");

var inputs=ele.getElementsByTagName("input");
for (var i=0;i<inputs.length;i=i+1){

var ele2=inputs[i];
if (choice=="all"){
ele2.checked=true;

}else if(choice=="cancel"){
ele2.checked=false;
}
else {

if (ele2.checked){
ele2.checked=false;
}else {
ele2.checked=true;
}
}

}
}
</script>
View Code

4 两级联动

<select id="province">
<option>请选择省:</option>
</select>

<select id="city">
<option>请选择市:</option>
</select>

<script>
data={"河北省":["廊坊","邯郸"],"北京":["朝阳区","海淀区"]};

var p=document.getElementById("province");
var c=document.getElementById("city");

for(var i in data){
var option_pro=document.createElement("option");

option_pro.innerHTML=i;

p.appendChild(option_pro);
}
p.onchange=function(){

pro=(this.options[this.selectedIndex]).innerHTML;
citys=data[pro];

c.options.length=0;

for (var i in citys){
var option_city=document.createElement("option");
option_city.innerHTML=citys[i];
c.appendChild(option_city);
}

}
</script>
View Code

5 select左右移

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#box1{
float: left;
}
#choice{
margin-left: 30px;
float: left;
}
#content{
margin-left: 30px;
float: left;
}

</style>
</head>
<body>
<div id="box1">
<select multiple="multiple" size="10" id="left">
<option>海淀区</option>
<option>朝阳区</option>
<option>东城区</option>
<option>西城区</option>
<option>昌平区</option>
<option>通州</option>
</select>
</div>

<div id="choice">
<input class="add"     type="button" value="添加>>>" onclick="add()"><br>
<input class="remove"  type="button" value="<<<移除" onclick="remove();"><br>
<input class="add-all" type="button" value="全部添加>" onclick="addall()"><br>
<input class="remove-all" type="button" value="<全部移除" onclick="remall()">
</div>

<div id="content">
<select multiple="multiple" size="10" id="right">
<option>oooo</option>
</select>
</div>

<!--<script src="jquery-3.1.1.js"></script>-->
<script>
function add() {
var op=document.getElementById('left').getElementsByTagName('option');
var right=document.getElementById('right');
for(var i=0;i<op.length;i++){
if (op[i].selected==true){
right.appendChild(op[i]);
i--;
}
}
}
function addall() {
var op=document.getElementById('left').getElementsByTagName('option');
var right=document.getElementById('right');
for(var i=0;i<op.length;i++){
right.appendChild(op[i]);
i--;
}
}
function remove() {
var op = document.getElementById('right').getElementsByTagName('option');
var left = document.getElementById('left');
for (var i = 0; i < op.length; i++) {
if (op[i].selected == true) {
left.appendChild(op[i]);
i--;
}
}
}

function remall() {
var op = document.getElementById('right').getElementsByTagName('option');
var left = document.getElementById('left');
for (var i = 0; i < op.length; i++) {
left.appendChild(op[i]);
i--;

}
}
</script>

</body>
</html>
View Code

 

http://www.cnblogs.com/yuanchenqi/articles/5980312.html

转载于:https://www.cnblogs.com/mocean/p/6400025.html

  • 点赞
  • 收藏
  • 分享
  • 文章举报
dengshign16357 发布了0 篇原创文章 · 获赞 0 · 访问量 118 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: