手把手教你使用Python打造一款摸鱼倒计界面

大家好,我是吴老板。

前言

前段时间在微博看到一段摸鱼人的倒计时模板,感觉还挺有趣的。


于是我用了一小时的时间写了个页面出来 摸鱼办地址 (当然是摸鱼的时间啦)。

模板是这样的:

摸鱼办公室

【摸鱼办公室】今天是 2021-11-30 星期二

你好,摸鱼人,工作再累,一定不要忘记摸鱼哦 ! 有事没事起身去茶水间去廊道去天台走走,别老在工位上坐着。多喝点水,钱是老板的,但命是自己的 !

距离 周末 放假还有 2 天

距离 元旦 放假还有 3 天

距离 过年 放假还有 34 天

距离 清明节 放假还有 97 天

距离 劳动节 放假还有 123 天

距离 端午节 放假还有 156 天

距离 中秋节 放假还有 255 天

距离 国庆节 放假还有 276 天


  • 由于前端是单页面服务,直接撸一个原始的 html 网页就行。
  • FastAPI 对于异步请求是一把好手、更轻、性能更佳。
  • 挂上一层 Nginx 让它看起来像那么回事儿。

实现过程

  • 首先要知道、除了静态文字之外的比如当前日期、距离节日放假的天数等都是动态返回的,我需要使用 Jinja2 模板进行动态绑定。
  • 我应该把重点放在时间的处理上。
  • 而且在这个模板中,有阳历的节日,也是阴历的节日,我需要转换。

初始化一个 FastAPI 对象并声明静态页面的模板目录 (Jinja2Templates)

# -*- coding: utf-8 -*-
import datetime
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from zhdate import ZhDate as lunar_date

app = FastAPI(
    debug=False,
    title="My API",
    docs_url="/docs",
    openapi_url=f"/openapi.json"
)

templates = Jinja2Templates(directory="templates")

可以看到的是我用到了 zhdate 这个库、主要用于阴历和阳历之间的相互转换。用法如下

today = datetime.date.today()
print(today.year, today.month, today.day)
print("大年时间: ", lunar_date(today.year+1, 1, 1).to_datetime().date())
print("端午时间: ", lunar_date(today.year, 5, 5).to_datetime().date())
print("中秋时间: ", lunar_date(today.year, 8, 15).to_datetime().date())
print("元旦时间: ", f"{today.year+1}-01-01")
print("清明时间: ", f"{today.year}-04-05")
print("劳动时间: ", f"{today.year}-05-01")
print("国庆时间: ", f"{today.year}-10-01")

我们可以梳理一下:

  • 计算距离 大年、元旦 的天数时,要在年份上 +1
  • 计算距离 其他节日 的天数时,要判断天数差是否小于 0,如果是,则年份需要 +1,因为已经过去的节日对此没有意义
distance_big_year = (lunar_date(today.year + 1, 1, 1).to_datetime().date() - today).days

distance_5_5 = (lunar_date(today.year, 5, 5).to_datetime().date() - today).days
distance_5_5 = distance_5_5 if distance_5_5 > 0 else (
        lunar_date(today.year + 1, 5, 5).to_datetime().date() - today).days

distance_8_15 = (lunar_date(today.year, 8, 15).to_datetime().date() - today).days
distance_8_15 = distance_8_15 if distance_8_15 > 0 else (
        lunar_date(today.year + 1, 8, 15).to_datetime().date() - today).days

distance_year = (datetime.datetime.strptime(f"{today.year + 1}-01-01", "%Y-%m-%d").date() - today).days

distance_4_5 = (datetime.datetime.strptime(f"{today.year}-04-05", "%Y-%m-%d").date() - today).days
distance_4_5 = distance_4_5 if distance_4_5 > 0 else (
        datetime.datetime.strptime(f"{today.year + 1}-04-05", "%Y-%m-%d").date() - today).days

distance_5_1 = (datetime.datetime.strptime(f"{today.year}-05-01", "%Y-%m-%d").date() - today).days
distance_5_1 = distance_5_1 if distance_5_1 > 0 else (
        datetime.datetime.strptime(f"{today.year + 1}-05-01", "%Y-%m-%d").date() - today).days

distance_10_1 = (datetime.datetime.strptime(f"{today.year}-10-01", "%Y-%m-%d").date() - today).days
distance_10_1 = distance_10_1 if distance_10_1 > 0 else (
        datetime.datetime.strptime(f"{today.year + 1}-10-01", "%Y-%m-%d").date() - today).days

怎么样? 我的命名足够疯狂吧。

接下来需要计算一下距离周末的天数。

def get_week_day(date):
    week_day_dict = {
        0: '星期一',
        1: '星期二',
        2: '星期三',
        3: '星期四',
        4: '星期五',
        5: '星期六',
        6: '星期天',
    }
    day = date.weekday()
    return week_day_dict[day]

week_day_ = get_week_day(today)
print(f"今天是: {week_day_}") # 先获取今天是星期几

按照每周 5 个工作日计算,今天距离周末的天数就是

5 - today.weekday() # today.weekday() 今天距离周末

现在将所有的数据组装起来

time_ = [
    {"v_": distance_year, "title": "元旦"},  # 距离元旦
    {"v_": distance_big_year, "title": "过年"},  # 距离过年
    {"v_": distance_4_5, "title": "清明节"},  # 距离清明
    {"v_": distance_5_1, "title": "劳动节"},  # 距离劳动
    {"v_": distance_5_5, "title": "端午节"},  # 距离端午
    {"v_": distance_8_15, "title": "中秋节"},  # 距离中秋
    {"v_": distance_10_1, "title": "国庆节"},  # 距离国庆
]

至于为什么是 List 而不是 Dict,那是我需要做一个根据距离天数的排序,让最先放假的节日放于最前面, 这样看起来会舒服得多。

time_ = sorted(time_, key=lambda x: x['v_'], reverse=False)

接下来要写一个 路由,将数据传入到 html 页面中去。

@app.get("/", response_class=HTMLResponse)
async def readme(request: Request):
    return templates.TemplateResponse("readme.html",
                                      {"request": request, "time_": time_, "now_": now_, "week_day_": week_day_})

来看一下完整的代码 (main.py):

# -*- coding: utf-8 -*-
import datetime
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from zhdate import ZhDate as lunar_date

app = FastAPI(
    debug=False,
    title="My API",
    docs_url=f"/docs",
    openapi_url=f"/openapi.json"
)

templates = Jinja2Templates(directory="templates")

today = datetime.date.today()

# print(today.year, today.month, today.day)
# print("大年时间: ", lunar_date(today.year+1, 1, 1).to_datetime().date())
# print("端午时间: ", lunar_date(today.year, 5, 5).to_datetime().date())
# print("中秋时间: ", lunar_date(today.year, 8, 15).to_datetime().date())
# print("元旦时间: ", f"{today.year+1}-01-01")
# print("清明时间: ", f"{today.year+1}-04-05")
# print("劳动时间: ", f"{today.year+1}-05-01")
# print("国庆时间: ", f"{today.year+1}-10-01")

distance_big_year = (lunar_date(today.year + 1, 1, 1).to_datetime().date() - today).days

distance_5_5 = (lunar_date(today.year, 5, 5).to_datetime().date() - today).days
distance_5_5 = distance_5_5 if distance_5_5 > 0 else (
        lunar_date(today.year + 1, 5, 5).to_datetime().date() - today).days

distance_8_15 = (lunar_date(today.year, 8, 15).to_datetime().date() - today).days
distance_8_15 = distance_8_15 if distance_8_15 > 0 else (
        lunar_date(today.year + 1, 8, 15).to_datetime().date() - today).days

distance_year = (datetime.datetime.strptime(f"{today.year + 1}-01-01", "%Y-%m-%d").date() - today).days

distance_4_5 = (datetime.datetime.strptime(f"{today.year}-04-05", "%Y-%m-%d").date() - today).days
distance_4_5 = distance_4_5 if distance_4_5 > 0 else (
        datetime.datetime.strptime(f"{today.year + 1}-04-05", "%Y-%m-%d").date() - today).days

distance_5_1 = (datetime.datetime.strptime(f"{today.year}-05-01", "%Y-%m-%d").date() - today).days
distance_5_1 = distance_5_1 if distance_5_1 > 0 else (
        datetime.datetime.strptime(f"{today.year + 1}-05-01", "%Y-%m-%d").date() - today).days

distance_10_1 = (datetime.datetime.strptime(f"{today.year}-10-01", "%Y-%m-%d").date() - today).days
distance_10_1 = distance_10_1 if distance_10_1 > 0 else (
        datetime.datetime.strptime(f"{today.year + 1}-10-01", "%Y-%m-%d").date() - today).days


def get_week_day(date):
    week_day_dict = {
        0: '星期一',
        1: '星期二',
        2: '星期三',
        3: '星期四',
        4: '星期五',
        5: '星期六',
        6: '星期天',
    }
    day = date.weekday()
    return week_day_dict[day]


# print("距离大年: ", distance_big_year)
# print("距离端午: ", distance_5_5)
# print("距离中秋: ", distance_8_15)
# print("距离元旦: ", distance_year)
# print("距离清明: ", distance_4_5)
# print("距离劳动: ", distance_5_1)
# print("距离国庆: ", distance_10_1)
# print("距离周末: ", 5 - today.weekday())

now_ = f"{today.year}{today.month}{today.day}日"
week_day_ = get_week_day(today)
time_ = [
    {"v_": 5 - 1 - today.weekday(), "title": "周末"},  # 距离周末
    {"v_": distance_year, "title": "元旦"},  # 距离元旦
    {"v_": distance_big_year, "title": "过年"},  # 距离过年
    {"v_": distance_4_5, "title": "清明节"},  # 距离清明
    {"v_": distance_5_1, "title": "劳动节"},  # 距离劳动
    {"v_": distance_5_5, "title": "端午节"},  # 距离端午
    {"v_": distance_8_15, "title": "中秋节"},  # 距离中秋
    {"v_": distance_10_1, "title": "国庆节"},  # 距离国庆
]

time_ = sorted(time_, key=lambda x: x['v_'], reverse=False)


@app.get("/", response_class=HTMLResponse)
async def readme(request: Request):
    return templates.TemplateResponse("readme.html",
                                      {"request": request, "time_": time_, "now_": now_, "week_day_": week_day_})


if __name__ == '__main__':
    import uvicorn

    uvicorn.run(app='main:app', host="0.0.0.0", port=8080, reload=True)

最后就到了 html 页面部分了,来看一下主要的传值。

<center>
    【摸鱼办公室】今天是 {{ now_ }} {{ week_day_ }}
    <br><br>
    {% for v_ in time_ %}
        <p> 距离 {{ v_.title }} 放假还有 {{ v_.v_ }} 天</p>
    {% else %}
        <p>沒有任何值</p>
    {% endfor %}

</center>

这样整个的路由构造和页面编写就算是完成了。

最后通过 Nginx 部署到我的站点上。

摸鱼办预览地址

代码已经上传至 摸鱼办

https://github.com/PY-GZKY/moyu

你可能会有更多的想法、可以在评论区讨论、一切为了摸鱼。

小伙伴们,快快用实践一下吧!如果在学习过程中,有遇到任何问题,欢迎加我好友,我拉你进Python学习交流群共同探讨学习。

终于有人将MySQL的安装讲明白了

前言

在日常开发中,存储数据的最常用的方式便是数据库了,其中最为著名的便是MySQL数据库,因它简便易于上手而且可扩展性强大,跨平台使得它广为使用,今天我们就来具体聊聊它的安装。

一、安装过程

我们所使用的是MySQL 5.7版本,这个版本算是挺不错的。下面我们来介绍下这个版本的具体安装过程吧。

1.解压安装

因为官网目前下载不了,为了大家安装过程中方便,我们下载一个免安装版mysql,下载好后将这个压缩包文件解压到指定的磁盘下,比如我想解压到E盘的mysql文件夹中。如图:

2.配置环境变量

为了让mysql 可以在任意目录运行,我们可以将mysql的bin目录添加到环境变量,如图:

3.修改配置文件

在mysql目录下创建一个my.ini配置文件,修改配置:

[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8
[mysqld]
#设置3306端口
port = 3306
# 设置mysql的安装目录
basedir="E:\mysql\mysql-5.7.11-winx64"
# 设置mysql数据库的数据的存放目录
datadir="E:\mysql\mysql-5.7.11-winx64\data"
# 允许最大连接数
max_connections=200
# 服务端使用的字符集默认为8比特编码的latin1字符集
character-set-server=utf8
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB

4.安装mysql

以管理员身份运行命令提示符,输入mysqld install命令(注意是mysqld而不是mysql)回车,即可安装MySQL,提示:Service successfully installed,则表示安装成功,如下图所示:

移除服务:mysqld remove

5.启动mysql服务

在命令提示符下执行命令,

启动mysql:net start mysql
停止:net stop mysql

发现启动不了,如图:

这是怎么回事了,哦~原来是因为还没有初始化,那么我们现在来进行初始化,

执行指令:mysqld --initialize-insecure --user=mysql,
mysqld --initialize-insecure:自动生成无密码的root用户,
mysqld --initialize:自动生成带随机密码的root用户,
mysqld --initialize --user=mysql --console:生成随机密码并显示在控制台窗口,

data文件夹不为空是不能执行这个命令的(删掉data文件即可),

执行mysqld –initialize-insecure –user=mysql命令会自动新建data文件夹。执行结果如图:

可以看到执行成功了,再次启动mysql服务,启动成功。如图:

6.进入mysql,修改登陆密码确保安全

第一次进入mysql 是没有密码就可以登陆了,我们可以设置登陆密码,更改root密码,输入:

update mysql.user set password=password("123321") where user = "root";

因为新版mysql数据库下没有password字段,所以需要使用如下命令:

update mysql.user set authentication_string=password('123321') where user='root';
刷新权限:flush privileges;

这是必须的,不然操作没有效果。

也可以这样修改密码:

set password = password('123456');

这样就将root用户的密码设置为了 123456了,下面我们退出mysql再重新进去,顺带说下退出命令:

退出mysql:quit;

接下来在进入mysql,如图:

这样root用户就有了密码,它的密码就是123321.

整个安装过程就完成了,是不是很简单了。

另外,为了提高交互效果,我们还可以一个软件——-sqlyong,它可以和mysql建立链接。安装好了之后是这样的一幅画面:

然后将先前的root用户和密码输入然后点连接即可进入:

这样就大功告成了。

四、总结

这篇文章主要讲解了MySQL数据库的安装,希望对大家的学习有帮助。

网页结构的简介和Xpath语法的入门教程

相信很多小伙伴已经听说过Xpath,之前小编也写过一篇关于Xpath的文章,感兴趣的小伙伴可以戳这篇文章如何利用Xpath抓取京东网商品信息以及Python网络爬虫四大选择器(正则表达式、BS4、Xpath、CSS)总结。今天小编继续给大家介绍一些Xpath知识点,希望对大家的学习有帮助。

1、Xpath让我们可以使用一种类似于Windows下的文件路径的方式,让我们可以定位到HTML或者XML结构中的具体元素。Xpath本身包含标一些准函数库,可以让我们的Xpath语法更加强大。

2、在HTML结构中,有一定的层级关系,主要的关系包括:父节点、子节点、同胞节点(兄弟节点)、先辈节点、后代节点。

一般的,像类似于<head>这种结构,称之为一个节点。如上图,根据层次关系,我们可以知道<body>节点是<nav>的父节点,相应的,<nav>节点是<body>节点的子节点。同胞节点又叫兄弟节点,一般的处于同级层次的节点叫同胞节点,如上图中的<nav>节点和第一个<div>节点、177~181行的<li>标签都是属于同胞节点。先辈节点又叫祖先节点,一般的,一个节点的上层以上的节点均称为先辈节点,所以父节点也是属于先辈节点的一种。基于此,我们又可以称<body>节点是<nav>的先辈节点。相对应的,一个节点的下层以下的节点均称为后代节点,所以子节点也是属于后代节点的一种。基于此,我们又可以称<nav>节点是<body>节点的后代节点。

3、理解这些节点之间的关系之后,可以方便我们更好的理解Xpath语法,下表是部分常用的Xpath语法。

表达式

详解

//@class

选取所有名为class的属性

/article

选取根元素article

//div

选取所有div子元素

article

选取所有article元素的所有子节点

article/a

选取所有属于article的子元素的a元素

article//div

选取所有属于article元素的后代的div元素

这里特别强调“/”和“//”的区别,“/”一般代表的某个元素的子节点,而不是全部的后代节点;而“//”一般代表的某个元素的后代节点,范围比“/”代表的要更加广泛一些。@符号后边时常跟着class,代表选取名为class属性的节点,比较常见。

4、下面针对具体的网页源码,让大家了解一下网页结构。

如上图中的红色框框中,class为属性,而等于号后边的“grid-5”即为属性值,有的时候节点内不只是一个属性,如上图中的196行中,就有两个属性。

5、为了更加方便的定位到div或者其他节点下的标签,我们需要继续进一步的进行定位锁定,下表是部分常用的Xpath语法。

表达式

详解

//div[@lang]

选取所有拥有lang属性的div元素

//div[@lang=’eng’]

选取所有拥有lang属性为eng的div元素

/article/div[1]

选取属于article子元素的第一个div元素

/article/div[last()]

选取属于article子元素的最后一个div元素

/div/*

选取属于div元素的所有子节点

//*

选取所有元素

//div/a | //div/p

选取所有div元素的a和p元素

掌握了Xpath语法知识之后,我们就可以通过Xpath语法来进行编写Xpath表达式,以提取网页上的目标数据。

千里之行,始于足下。如果想学好Xpath,更是需要勤加使用。

一文解读JavaScript中的文档对象(DOM)

大家好,我是IT共享者,人称皮皮。

前言

相信做网站对JavaScript再熟悉不过了,它是一门脚本语言,不同于Python的是,它是一门浏览器脚本语言,而Python则是服务器脚本语言,我们不光要会Python,还要会JavaScript,因为它对做网页方面是有很大作用的。

1.文档对象(DOM)

1).Document对象

这是我们用的最普遍的一个文档对象了,专门用来操作DOM节点时用。

1)).获取元素

document.getElementById()           #通过id查找HTML元素
document.getElementsByName()        #通过name查找HTML元素
document.getElementsByTagName()     #通过标签名查找HTML元素
document.getElementsByClassName()   #通过类名查找HTML元素 
document.querySelector(".h")        #第一个类名为 "h" 的元素
document.querySelectorAll("div.no, div#h") #所有class为"no"或者id为"h"的div元素
document.body          #获取body标签
document.documentElement   #获取html标签

2)).获取网页内容

document.cookie        #网页cookie
document.domain        #文档的域名
document.lastModified  #文档被最后修改的日期和时间
document.referrer      #载入当前文档的文档的URL
document.title         #当前文档的标题
document.URL           #当前文档的URL
document.doctype       #当前文档的doctype
document.baseURI       #当前文档的绝对URI
document.documentMode   #浏览器使用的模式
document.documentURI    #文档的URI
document.implementation #DOM实现
document.inputEncoding  #文档的编码(字符集)
document.readyState     #文档的(加载)状态
document.strictErrorChecking    #是否强制执行错误检查

3)).文档写入

document.write('hello world')   向文档写入文本
document.writeln('hello world') 向文档写入文本并换行

4)).获取集合

document.all        #所有html元素
document.anchors    #所有Anchor引用
document.forms      #所有的表单引用
document.images     #所有的图片引用
document.links      #所有的超链接引用
document.scripts    #所有的脚本引用
document.embeds     #所有的流媒体引用

5)).获取节点

childNodes          #获取子节点的集合 ,返回数组 ,并把换行和空格也当成是节点信息。
children            #获取子节点的集合 ,返回数组   
firstChild          #获取第一个子元素  并把换行和空格也当成是节点信息
firstElementChild   #获取第一个子节点
lastChild           #获取最后一个子节点 并把换行和空格也当成是节点信息
lastElementChild    #获取最后一个子节点
parentNode          #获取父节点
parentElement       #获取父节点(IE)
offsetParent        #获取所有父节点  对应的值是body下的所有节点信息
previousSibling         #获取上一个兄弟节点  匹配字符,包括换行和空格,而不是节点
previousElementSibling  #获取上一个兄弟节点  直接匹配节点
nextSibling             #获取下一个兄弟节点  匹配字符,包括换行和空格,而不是节点
nextElementSibling      #获取下一个兄弟节点  直接匹配节点
ownerDocument           #元素的根节点

这里我们获取到了所有的Div元素,我们可以针对性的获取一个ID下的Div的子元素以及它的兄弟和父,子元素,如下:

6)).创建节点

我们可以自定义节点并添加值,不过要将它添加到文档中去,所以必须添加节点,一般和下方的增加节点配套使用。

document.createElement(标签)  #创建HTML元素
document.createTextNode(文本) #给文档添加文本
document.createComment(文本)  #创建一个注释节点
document.createDocumentFragment() #创建文档粉碎节点

7)).增加节点

appendChild(节点) #节点被添加到元素的末尾
insertBefore(a,b) #a节点会插入b节点的前面

8)).删除节点

removeChild(节点名)  #被移除的节点仍在文档中,只是文档中已没有其位置了

9)).替换节点

replaceChild(插入的节点,被替换的节点)

10)).复制节点

a.cloneChild() #复制a节点,复制出来的节点作为返回值为true时,则a元素后代也一并复制。否则,仅复制a元素本身

11)).节点属性

#节点类型 nodeType 有三种情况
#1.元素节点  2.属性节点  3.文本节点


#节点名称 nodeName 


#节点值 nodeValue 
#元素节点没节点值,为null 
#文本节点的节点值就是文本
#属性节点的节点值就是该属性值


#节点属性获取
a.width
a['width']
a.gerAttribute(属性名)  返回指定的属性值
a.gerAttributeNode(属性名) 返回指定的属性节点
节点属性设置
a.width=400
a['width']=400
a.attributes['width']=400
a.setAttribute('width',400) 添加指定的属性
a.setAttributeNode(b) 添加指定的属性节点


#节点属性删除
a.removeChild(子节点)    从元素中移除子节点
a.removeAttribute(属性)  从元素中移除指定属性
a.removeAttributeNode(属性) 移除指定的属性节点,并返回被移除的节点


a.id 获取当前元素的id
a.className  获取当前元素的class
a.classList  获取当前元素的class列表


a.accessKey='w'    设置或返回元素的快捷键
a.namespaceURI     返回指定节点的命名空间的 URI
a.dir              设置或返回元素的内容是否可编辑
a.normalize()      合并元素中相邻的文本节点,并移除空的文本节点
a.tabIndex='3'     设置或返回元素的tab键控制次序
a.tagName          返回元素的标签名
a.textContent      设置或返回节点及其子代的文本内容
a.title            设置或返回元素的标题属性
a.item(num)        返回节点列表中位于指定下标的节点
a.length           返回节点列表中的节点数

12)).获取元素文本

a.innerHTML  获取或者设置对象内的HTML
a.innerText  获取或者设置对象内的文本
a.outerHTML  获取或者设置对象外的HTML
a.outerText  获取或者设置对象外的文本
a.value      获取或者设置表单元素的值

总结

这篇文章主要介绍了JavaScript的文档对象。下一篇文章,我们继续介绍JavaScript,敬请期待!

一文解读JavaScript事件对象和表单对象

前言

相信做网站对JavaScript再熟悉不过了,它是一门脚本语言,不同于Python的是,它是一门浏览器脚本语言,而Python则是服务器脚本语言,我们不光要会Python,还要会JavaScript,因为它对做网页方面是有很大作用的。

1.事件对象(Event)

1).事件对象常量

bubbles         事件是否是起泡事件类型 
cancelable      事件是否可确定可取消的默认动作
currentTarget   事件监听器触发该事件的元素 
eventPhase      事件传播的当前阶段 
target          触发此事件的元素(事件的目标节点),srcElement(IE)
timeStamp       事件生成的日期和时间
type            当前Event对象表示的事件的名称 
initEvent()     初始化新创建的 Event 对象的属性
preventDefault() 不执行默认动作
stopPropagation()   停止冒泡 cancelBubble
x,y             元素的 x 坐标和 y 坐标
returnValue     设置或获取事件的返回值
fromElement  在IE中用于mouseover和mouseout 事件,可以引用移出鼠标的元素。
toElement  在IE中用于mouseover和mouseout 事件,该属性引用移入鼠标的元素。
returnValue 设置或获取事件的返回值
keyCode(IE) 键盘码 which()  charCode
offsetX,offsetY 事件在源元素的中的x坐标和y坐标。

这在后面的其它操作中我都有举例子,大家可以仔细看看。

2).键盘鼠标事件

altKey          判断"ALT" 是否被按下 
button          判断哪个鼠标按钮被点击 
clientX         判断鼠标指针的水平坐标
clientY         判断鼠标指针的垂直坐标
ctrlKey         判断"CTRL" 键是否被按下
keyIdentifier   按键的标识符  
keyLocation     按键在设备上的位置 
metaKey         判断"meta" 键是否被按下
relatedTarget   与事件的目标节点相关的节点
screenX         判断鼠标指针的水平坐标
screenY         判断鼠标指针的垂直坐标
shiftKey        判断"SHIFT" 键是否被按下

这个在后面也会提到,比如获取鼠标坐标:

2.表单对象

1).Form对象

document.forms['表单名']['text'].value #获取表单中的文本框的值
acceptCharset       服务器字符集 
action              设置或返回表单的action
enctype             设置或返回表单用来编码内容的MIME类型 
length              返回表单中的元素数目
method              设置或返回将数据发送到服务器的 HTTP 方法
name                设置或返回表单的名称
target              设置或返回表单提交结果的Frame或Window

2).Button对象(submit,hidden与它方法差不多)

b.accessKey                 设置或返回访问按钮的快捷键
b.alt                       设置或返回当浏览器无法显示按钮时供显示的替代文本 
b.disabled=true|false       设置或返回是否禁用按钮
b.form                      返回对包含该按钮的表单对象的引用
b.id                        设置或返回按钮的 id
b.name                      设置或返回按钮的名称 
b.tabIndex='3'              设置或返回按钮的 tab 键控制次序 
b.type                      返回按钮的表单元素类型 
b.value                     设置或返回在按钮上显示的文本

3).Checkbox 对象(Radio与它方法差不多)

和上面的对象差不多,唯一不同的便是多了一个默认值选中值:“defaultChecked”。

4).Select 对象

s.options  返回下拉列表数组
s.selectedIndex=num    设置或返回下拉列表中被选选项的索引号
s.multiple=true|false  设置或返回是否可有多个选项被选中
s.size                 设置或返回下拉列表中一次显示显示的选项数
s.add()       向下拉列表添加一个选项
s.remove()    从下拉列表中删除一个选项

总结

这篇文章主要介绍了JavaScript的事件对象和表单对象。下一篇文章,我们继续介绍JavaScript,敬请期待!

一文解读JavaScript中的事件知识

前言

相信做网站对JavaScript再熟悉不过了,它是一门脚本语言,不同于Python的是,它是一门浏览器脚本语言,而Python则是服务器脚本语言,我们不光要会Python,还要会JavaScript,因为它对做网页方面是有很大作用的。

1.事件

1).鼠标事件

onclick     #鼠标单击  
ondblclick  #双击鼠标
onmousedown #鼠标按钮被按下。
onmousemove #鼠标被移动。
onmouseover #鼠标移到某元素之上。
onmouseout  #鼠标从某元素移开。
onmouseup   #鼠标按键被松开。

2).键盘事件

onkeydown #按键被按下
onkeypress #按键被按下并松开
onkeyup #按键被松开

3)框架事件

onabort 图像的加载被中断 
onerror 在加载文档或图像时发生错误
onload  页面或图像完成加载  
onresize 窗口或框架被重新调整大小
onscroll 滚动事件
onunload 退出页面

可以看到一会儿就滚动了这么多下。

4).表单对象

onblur 元素失去焦点 
onchange 文本域的内容被改变
onfocus 元素获得焦点
onreset 重置按钮
onselect 文本选中
onsubmit 确认提交

总结

这篇文章主要结束了JavaScript的事件知识。下一篇文章,我们继续介绍JavaScript,敬请期待!

盘点 JavaScript 中那些进阶操作知识(下篇)

相信做网站对 JavaScript 再熟悉不过了,它是一门脚本语言,不同于 Python 的是,它是一门浏览器脚本语言,而 Python 则是服务器脚本语言,我们不光要会 Python,还要会 JavaScript,因为它对做网页方面是有很大作用的。

大家好,我是 IT 共享者,人称皮皮。上篇文章给大家分享了盘点 JavaScript 中那些进阶操作知识(上篇),这篇文章继续来看看趴!

前言

相信做网站对 JavaScript 再熟悉不过了,它是一门脚本语言,不同于 Python 的是,它是一门浏览器脚本语言,而 Python 则是服务器脚本语言,我们不光要会 Python,还要会 JavaScript,因为它对做网页方面是有很大作用的。

1.Javascript 刷新页面

history.go(0) 
location.reload() 
location=location 
location.assign(location) 
document.execCommand('Refresh') 
window.navigate(location) 
location.replace(location) 
document.URL=location.href

2.Js 浏览器兼容问题

1).浏览器事件监听

function addEventhandler(target,type,fn,cap){
            if(target.addEventListener)               /*添加监听事件*/
              {       
                target.addEventListener(type,fn,cap)
                }
            else{
                 target.attachEvent('on'+type,fn)  /*IE 添加监听事件*/
               }
          }
       function removeEventhandler(target,type,fn,cap){
            if(target.removeEventListener)            /*删除监听事件*/
             {
                target.removeEventListener(type,fn,cap)
                }
            else{
                 target.detachEvent('on'+type,fn)    /*IE 删除监听事件*/
               }
          }

2).鼠标键判断

function bu(event)
{
var bt= window.button || event.button;
if (bt==2)
  {
  x=event.clientX
  y=event.clientY   
  alert("您点击了鼠标右键!坐标为:"+x+','+y)
  }
else if(bt==0)
  {
    a=event.screenX
    b=event.screenY
  alert("您点击了鼠标左键!坐标为:"+a+','+b)
  }
else if(bt==1)
  {
  alert("您点击了鼠标中键!");
  }
}

3).判断是否按下某键

function k(event)
{
var ke=event.keyCode || event.which
if(event.shiftKey==1)
  {
  alert('您点击了 shift');
  }
 alert(ke)alert(event.type)
}

4).网页内容节点兼容性

1)).网页可视区域宽高

var w=document.body.offsetWidth|| document.documentElement.clientWidth|| document.body.clientWidth;
var h=document.body.offsetHeight|| document.documentElement.clientHeight || document.body.clientHeight;

2)).窗体宽度高度 比可视区域要大

window.innerHeight - 浏览器窗口的内高度(以像素计) 
window.innerWidth - 浏览器窗口的内宽度(以像素计)

3)).页面滚动条距离顶部的距离

var t=document.documentElement.scrollTop || document.body.scrollTop

4)).页面滚动条距离左边的距离

var s=document.documentElement.scrollLeft || document.body.scrollLeft

5)).元素到浏览器边缘的距离

  function off(o){   #元素内容距离浏览器边框的距离(含边框)var l=0,r=0;
        while(o){
            l+=o.offsetLeft+o.clientLeft;
            r+=o.offsetTop+o.clientTop;
            o=o.offsetParent;
        }
        return {left:l,top:r};
    }

6)).获取滚动条高度

// 滚动条的高度
function getScrollTop() {
var scrollTop = 0;
if (document.documentElement && document.documentElement.scrollTop) {
        scrollTop = document.documentElement.scrollTop;
    }
else if (document.body) {
        scrollTop = document.body.scrollTop;
    }
return scrollTop;
}

7)).DOM 节点操作

function next(o){//获取下一个兄弟节点 if (o.nextElementSibling) {
            return o.nextElementSibling;
        } else{
            return o.nextSibling;
        };
    }
    function pre(o){//获取上一个兄弟节点 if (o.previousElementSibling) {
            return o.previousElementSibling;
        } else{
            return o.previousSibling;
        };
    }
    function first(o){//获取第一个子节点 if (o.firstElementChild) {
            return o.firstElementChild;//非 IE678 支持
        } else{
            return o.firstChild;//IE678 支持
        };
    }
    function last(o){//获取最后一个子节点 if (o.lastElementChild) {
            return o.lastElementChild;//非 IE678 支持
        } else{
            return o.lastChild;//IE678 支持
        };
    }

8)).窗口的宽高

document.body.scrollWidth||document.docuemntElement.scrollWidth;//整个网页的宽
document.body.scrollHeight||document.docuemntElement.scrollHeight;//整个网页的高

9)).屏幕分辨率的宽高

window.screen.height;//屏幕分辨率的高
window.screen.width;//屏幕分辨率的宽

10)).坐标

window.screenLeft;//x 坐标
window.screenX;//X 坐标
window.screenTop;//y 坐标
window.screenY;//y 坐标

11)).屏幕可用工作区宽高

window.screen.availHeight 
window.screen.availWidth

5).事件源获取

e.target || e.srcElement

6).行外样式

funtion getStyle(obj,name){
   if(obj.currentStyle){
      //IE
    return obj.currentStyle[name];
    }else{
    //Chrom,FF
   return getComputedStyle(obj,false)[name];
      }
 }

7).阻止事件冒泡函数封装

function pre(event){

           var e = event || window.event;

           if(e.stopPropagation){   // 通用方式阻止冒泡行为

               e.stopPropagation();

           }else{    //IE 浏览器

               event.cancelBubble = true;

           }

8).阻止浏览器默认行为(例如点击右键出来菜单栏)

function stop(event) {

     var e = event || window.event;

     if (e.preventDefault){

         e.preventDefault();   // 标准浏览器

     }else{

         e.returnValue = false; // IE 浏览器

     }

}

3.严格模式

"use strict"

4.判断变量类型

typeof  variable
instance  instanceof  object
instance.constructor== object
Object.prototype.toString.call(instance)

5.下载服务器端文件

<a href="http://somehost/somefile.zip" download="myfile.zip">Download file</a>

总结

这篇文章主要介绍了 JavaScript 的进阶操作命令!希望对大家的学习有所帮助。


人生苦短,我用Python!

盘点JavaScript中那些进阶操作知识(上篇)

前言

相信做网站对JavaScript再熟悉不过了,它是一门脚本语言,不同于Python的是,它是一门浏览器脚本语言,而Python则是服务器脚本语言,我们不光要会Python,还要会JavaScript,因为它对做网页方面是有很大作用的。

1.进阶操作

这里列举了一些小编以前经常用到的一些例子以及一些经验,由于篇幅受限,这里我将会把部分执行结果的输出直接输入到代码下面。

1).浏览器输入

prompt('请输入') 返回一个字符串变量

2).浏览器输出

document.write('我被输出了') 返回一个字符串

3).浏览器弹框

alert('我是弹框')  返回一个字符串

4).浏览器交互

confirm("是否进入"); 返回一个比尔类型的值

5).控制台打印结果

console.log('显示在控制台的结果')

6).类型检查

typeof ss
ss instanceof string

7).转换为字符串

var ff=123
ff.toString()

8).转换为数字

parseInt(‘231fasd’) -->231  isNumeric 用来判断是否是数字
parseInt('df',num) --> num介于2~36之间,若省略则为10,若‘0x’开头,则为16,若小于2或大于36则为NAN
parseFloat('10') -->无法转换为数字将返回NaN,可通过isNan来判断是否为NaN

9).转换为原始对象

var ff=123
ff.ValueOf()

10).编解码函数

1))字符串编解码

escape(string)    # 编码
unescape(string)   #解码

2))URL编解码

encodeURI(URIstring)  #编码
decodeURI(URIstring)  #解码
encodeURIComponent(URIstring)   #把字符串编码为 URI 组件
decodeURIComponent(URIstring)   #解码一个编码的 URI 组件

11).Eval

可把里面的字符串当做Js代码来执行,犹如Python中的Eval。

eval("alert('fasd')")

12).Call

能够使用属于另一个对象的方法,可传多个参数,是经典的对象冒充方法。

function ss(a,b) {
    alert(a + this.val + b);
};
var o= new Object();
o.val = "123";
ss.call(o, "I am", "years old.");


output:
I am 123 years old

13).Apply

与Call差不多,前面是对象但是它后面的参数是一个数组。

function ss(a,b) {
    alert(a + this.val + b);
};
var o= new Object();
o.val = "123";
ss.apply(o, new Array("I am", "years old"));

14).Caller

返回一个对函数的引用,该函数调用了当前函数,caller 属性只有在函数执行时才有定义。

function aa() {
    if (aa.caller) {
       console.log(aa.caller);   
    } else {
        console.log("111");
     }
}
aa()
output: 111

15).Callee

返回正被执行的 Function 对象,表示对函数对象本身的引用,一般用在递归。

function ff(x){
    if(x==1)
{
        return 1;
}
    else{
        return x+arguments.callee(x-1)
}
}
ff(3);
output:6

总结

这篇文章主要介绍了JavaScript的进阶操作知识。下一篇文章,我们继续介绍JavaScript,敬请期待!

盘点儿童智力开发的首选编程语言——Scratch

大家好,我是IT共享者,人称皮皮。

前言

Scratch作为少儿编程的首选编程语言,这几年发展的如火如荼,当然,这主要还是因为它简单易学,不用掌握太多概念即可编程,这意味着你不用认识英文单词,编程照样行云流水,是不是很激动?那么现在让我们一起进入Scratch的世界吧。

一、安装Scratch

首先我们需要安装Scratch,下载地址:
https://u062.com/file/7715018-456560477,然后我们双击安装软件,它会自动安装,并且无法选择安装路径,所以系统盘最好保留足够的空间,安装完毕,打开如图所示:

当然如果你想切换到其它语言的界面也很简单,如图:

二、基本操作

我们从上图中可以看出Scratch的界面比较简洁,非常适合少儿编程,所以我们学起来也不会很困难。可以看到Scratch有这些早就编好的代码功能模块供我们使用,如图:

首先我们来看看猫咪的基本属性,如图:

这些参数我们都可以设置,我们还可以设置多个角色,比如大于吃小鱼,就可以找几个大鱼的图片和小鱼的图片。那么接下来让我们来看看Scratch有哪些妙用之处吧。

1.运动

这个板块具有让Scratch中的对象运动起来的功能,如下:

这里我们点击移动10步,角色就会向右移动10个像素,不过我们需要将这个模块拖动到中间这个窗口中来,如图:

这样点击中间的这个蓝色的不规则方块即可执行角色动作任务。比如我要角色左转,如图:

可以看到,我们拖动左转后可以设置左转的角度,然后点击之后角色就开始旋转一定角度,就好比移动了一样。然后我们还可以移动角色,这里可以选择移动到随机位置或者鼠标指针位置,这里我选择了随机位置,如图:

这里选择了随机位置的所有操作,可以看到我们的角色开始移动并且还可以在指定时间内移动到某个位置。这里还有一个边缘检测模块,如图:

当角色碰到边缘的时候,只要触发该模块的功能,角色即可反弹回来。勾选下面的三个选项即可显示当前角色的坐标和方向,如图:

2.外观

这个模块可以设置角色的形状和语言还有显示隐藏以及各种特效,如图:

我们可以看到这几个动作不像刚才那样连接起来了,我们将它镶嵌起来了,这样做的用途便是点击一处即可触发所有的功能,这里我们可以看到改变了角色的颜色和形状,甚至加了点特效,看起来怪怪的。我们也可以利用清除图形特效功能来清除上面的特效,也可以设置角色的状态,显示或者隐藏,并把角色移动到前面或者后面,显示角色的信息,如图:

3.声音

这个不用我多说,大家都知道,这个就是用来设置角色的声音的,如图:

系统内置的是猫咪的声音,我们可以自己录制猫咪的声音,如图:

4.事件

可以接收响应角色的各个事件,如图:

这个模块需要配合其它模块使用,比如前面的模块,我们让它在按下某个键后就发出猫咪声,如图:

这里小编设置了按下“a”键发出猫咪叫,按下”b”键角色马赛克特效增加25,小编刚按下“b”键就出现了马赛克效果,可见小编的做法是正确的。然后我们还可以看到这个事件可以接收到消息,并进行一些处理,比如说:

可以看到当我们收到这条消息后角色就进行思考,而且是不停的思考。

5.控制

控制就是可以重复执行角色的基本操作,或者使用一些控制循环语句,来看一下,如图:

这里我们克隆了这个角色,而且重复执行了十次说Hello并等待3秒的过程,但是控制里面有一些功能并不能单独使用,所以我们需要搭配其它功能模块来使用,下面我们接着来看其它模块。

6.侦测

这个模块通常是和控制和其它模块相辅相成的,它是控制模块中的某些判读语句的条件,如图:

7.运算

这里有这众多的计算方法,如加减乘除,下面来看看:

我们可以在里面输入任意数值来进行计算,不过随机数中只会显示随机整数。

8.变量

这个可以说是一门编程语言必备的东西了,Scratch也是,有了它,你可以做很多事情并实现它们。我们点击变量模块并点击建立一个变量,如图:

新建变量名然后选择变量的作用范围,如果适用于所有角色则是全局变量,可以在整个程序的任意位置使用,如果是仅适用于当前角色,说明只能作用在局部环境中。新建好变量后我们给变量设置一个值,如图:

这样即可使用变量了。

9.自制积木

这个模块我们在编写程序时完全可以不使用它,但是如果你的逻辑变得十分冗长的时候,你可以使用它来讲逻辑给包裹起来,也就是面向对象中的封装技术了。

三、总结

Scratch是儿童智力开发的首选编程语言,它把编程变得简单,而且可以提升孩子们 的想象力,如果可以做到亲子互动的话那么将更加有趣。