首页 文章 精选 留言 我的

精选列表

搜索[Vite构建],共10000篇文章
优秀的个人博客,低调大师

Appium自动化测试框架构建

Appium简介 Appium是一个开源、跨平台的测试框架,可以用来测试原生及混合的移动端应用。Appium支持iOS、Android及FirefoxOS平台测试。Appium使用WebDriver的json wire协议,来驱动Apple系统的UIAutomation库、Android系统的UIAutomator框架。 相比其他的移动自动化测试工具,Appium测试由于调用了Selenium的client库使其可以使用任意的语言,包括Python、Ruby、Node.js、Objective-C等。 Appium下载与安装 可以去官方下载也可去github下,目前最新的是0.17.6版。当然国内的网盘里也有,这样就不用fan.qiang了。下载后解压即可使用,很方便。 目前的Appium版本需.net4.5及以上支持,故要想使用Appium还需安装.net4.5.1,可以去微软下载.net4.5.1,当然网盘里也有了,呵呵。 由于Appium使用了Selenium来进行自动化测试,所以还需安装Selenium,网盘里有下载,Selenium下载地址。下载后解压,切换目录到解压目录,然后执行python setup.py install即可安装Selenium,当然如果您熟悉pip 也可以用pip install Selenium来安装。 安装、配置Android模拟器 我们打算在模拟器上使用appium进行自动化测试,故首先得下载安装android开发环境,IDE开发环境配置好以后就可以通过eclipse创建一个android手机模拟器了。 下载JDK与配置JDK 下载JDK,下载之后双击压缩包并安装,一路默认下去即可完成,jdk安装到了C:Java目录下了,其下有两个文件夹jdk1.6.0_13和jre6。 配置jdk比较简单将C:Javajdk1.6.0_13bin目录添加到系统环境变量path里,记住前加分号,之后确认即可。 怎样测试java是否配置好?cmd之后键入java -verison 下载android开发环境ADT-bundle 可以去Google下载也可以去网盘下载android的集成开发环境。下载后解压到c:android目录下就行了。 配置ADT 将解压目录下的sdk下的tools和platform-tools目录添加到系统环境变量path里,记住前加分号,之后确认即可。 怎样测试android的ADT是否配置好?进入c:androideclipse目录双击eclipse.exe,看能否正常启动、使用。 新AVD模拟器 启动eclipse,点击Eclipse软件的Windows菜单,选择其下的Android Virtual Device Manager菜单项,进入Android Virtual Device Manager其对话框后,点击左侧New按钮可新建android手机模拟器。在Create new Android Virtual Device Manager对话框的name文本框内给要创建的模拟器起个名字,例如testAVD01。在Device列表框内选择2.7 QVGA 240 X320 ldpi,在选择了Device后,target列表框自动选择了android 4.4 API Level 19{现在已安装的开发环境里只有一套API,读者可自行安装其他API,届时可任选其他API作为自己测试平台}默认即可,其他选项此时可以不做选择默认设置即可,点击对话框的OK按钮确认,即可创建Android 模拟器。 启动android模拟器 cmd之后键入 emulator @testAVD01,等待数秒之后android手机模拟器启动。 安装、配置Python 这步比较简单,下载Python后默认安装即可。配置只需把c:python27目录加到系统环境变量path后即可,记住前加分号。cmd之后键入python如果见到3个大于号即证明python安装配置成功。Appium自动化测试流程 启动android手机模拟器 cmd之后键入 emulator @testAVD01,等待数秒之后android手机模拟器启动。 另起一个cmd键入adb devices查看模拟器是否正常启动了。 启动Appium 进入appium解压目录,双击appium.exe文件,点击launch即可。 基于Appium的Python自动化测试 编写代码 from selenium import webdriver # Returns abs path relative to this file and not cwd PATH = lambda p: os.path.abspath( os.path.join(os.path.dirname(__file__), p) ) desired_caps = {} desired_caps['device'] = 'android' desired_caps['browserName'] = '' desired_caps['version'] = '4.2' desired_caps['app-package'] = 'com.android.calculator2' desired_caps['app-activity'] = '.Calculator' driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps) # 点击计算器上的数字和运算符 el = driver.find_element_by_name("1") el.click() el = driver.find_element_by_name("5") el.click() el = driver.find_element_by_name("9") el.click() el = driver.find_element_by_name("delete") el.click() el = driver.find_element_by_name("9") el.click() el = driver.find_element_by_name("5") el.click() el = driver.find_element_by_name("+") el.click() el = driver.find_element_by_name("6") el.click() el = driver.find_element_by_name("=") el.click() driver.quit() 执行代码 另起cmd,切到python代码所在目录,执行python xxx.py即可见模拟器在被操作了。 最新内容请见作者的GitHub页:http://qaseven.github.io/

优秀的个人博客,低调大师

用Docker构建与环境无关的系统

Docker 有三个特定的功能,以帮助建立与环境无关的系统: 只读文件系统 环境变量注入 存储卷 处理卷是一个大主题,为了学习前两个功能,在本文的其余部分将改变对示例的需求。WordPress 使用一个名为MySQL 的数据库程序来存储大部分数据,所以先确保运行WordPress 的容器是只读文件系统,是一个好主意。 1 只读文件系统 使用只读文件系统产生以下两个积极效果。首先,你对容器不能更改它所包含的文件产生信心;其次,你也会进一步树立信念:容器中的攻击者无法破坏文件。为了在客户系统上使用--read-only 标志,从WordPress 镜像创建和启动一个容器: docker run -d --name wp --read-only wordpress:4 完成这些步骤后,检查容器是否正在运行。你可使用任何先前介绍的方法,也可以直接检查容器元数据。如果指定的wp 容器正在运行,以下命令将输出为真,否则为假。 docker inspect --format "{{.State.Running}}" wp docker inspect 命令将显示Docker 为该容器保留的所有元数据(一个JSON 文件)。格式选项会改变元数据。除了该容器的运行状态,本例中其会滤除元数据的所有字段。这个命令将简单地输出为错误。在这种情况下,容器没有运行。为了找出原因,检查容器中的日志: docker logs wp 输出是这样的: error: missing WORDPRESS_DB_HOST and MYSQL_PORT_3306_TCP environment variables Did you forget to --link some_mysql_container:mysql or set an external db with -e WORDPRESS_DB_HOST=hostname:port? 看起来WordPress 有一个MySQL 数据库的依赖关系。数据库是一个程序,根据检索和搜索方式存储数据。好消息是,你可以使用Docker 安装MySQL,就像安装WordPress: docker run -d --name wpdb \ -e MYSQL_ROOT_PASSWORD=ch2demo \ mysql:5 一旦启动后,会创建一个不同的WordPress 容器,并链接到这个新的数据库容器中:再检查一次,WordPress 是否正常运行: docker inspect --format "{{.State.Running}}" wp2 你可以得知WordPress 失败后重新启动。检查日志以确定原因: docker logs wp2 应该有类似以下的日志: ... Read-only file system: AH00023: Couldn't create the rewrite-map mutex (file /var/lock/apache2/rewrite-map.1) 同样是WordPress 失败后重新启动,但这次的问题是,它试图写一个锁定文件到特定的位置。这是启动的必要组成部分,并无特殊。在这个示例中,需要为只读文件系统增加异常处理。你需要使用卷来做这个异常处理。使用下面的命令启动WordPress,不会有任何问题:更新版本后你能用的脚本看上去像是这样: SQL_CID=$(docker create -e MYSQL_ROOT_PASSWORD=ch2demo mysql:5) docker start $SQL_CID MAILER_CID=$(docker create dockerinaction/ch2_mailer) docker start $MAILER_CID WP_CID=$(docker create --link $SQL_CID:mysql -p 80 \ -v /run/lock/apache2/ -v /run/apache2/ \ --read-only wordpress:4) docker start $WP_CID AGENT_CID=$(docker create --link $WP_CID:insideweb \ --link $MAILER_CID:insidemailer \ dockerinaction/ch2_agent) docker start $AGENT_CID 恭喜你,现在你应该有了一个正在运行的WordPress 容器!通过使用只读文件系统,以及链接WordPress 到另一个运行着数据库的容器,可以确保运行WordPress 镜像的容器永远不会改变。这意味着,如果运行客户的WordPress 博客程序的机器出了问题,可轻松在其他地方启动该容器的另一个副本。但是这一设计有两个问题。首先,数据库和WordPress 的容器运行在同一个机器上。其次,WordPress 对重要的设置,如数据库名称、管理用户、管理密码、数据库加盐等使用默认值。为了解决这个问题,你可以创建多个版本的WordPress 软件,每一个客户都有一个特殊的配置。这样做会使简单的配置脚本变成一个在创建镜像时写入文件的怪物。通过使用环境变量来注入配置则是一个更好的方式。 2 环境变量的注入 环境变量是通过其执行上下文提供给程序的键值对。它可以让你在改变一个程序的配置时,无须修改任何文件或更改用于启动该程序的命令。Docker 使用环境变量来传达相关信息,包括容器的守护选项、容器的主机名,以及其他在容器中运行程序的实用信息。Docker 还为用户提供了一个机制,可将环境变量注入到一个新的容器。那些期望通过环境变量获取重要信息的程序,可在容器创建时就进行配置。幸运的是,WordPress 就是这样一个程序。 在深入WordPress 的细节之前,尝试注入和观察你的环境变量。UNIX 命令env 显示当前执行上下文(终端)中的所有环境变量。要查看注入的环境变量,请使用以下命令: --env 标志或-e 缩写,可用于注入任何环境变量。如果变量已经由镜像或Docker 设置,则该值将被覆盖。容器内部运行程序的方式,可以依赖于这种变量。WordPress 遵循以下环境变量: WORDPRESS_DB_HOST WORDPRESS_DB_USER WORDPRESS_DB_PASSWORD WORDPRESS_DB_NAME WORDPRESS_AUTH_KEY WORDPRESS_SECURE_AUTH_KEY WORDPRESS_LOGGED_IN_KEY WORDPRESS_NONCE_KEY WORDPRESS_AUTH_SALT WORDPRESS_SECURE_AUTH_SALT WORDPRESS_LOGGED_IN_SALT WORDPRESS_NONCE_SALT 提示 这个示例忽略了KEY 和SALT 变量,但任何实际的生产系统绝对应该设置这些值。 开始之前,你应该解决数据库和WordPress 容器在同一个机器上运行的问题。不是使用链接来满足WordPress 的数据库依赖,而是注入WORDPRESS_DB_HOST 变量的值: docker create --env WORDPRESS_DB_HOST=<my database hostname> wordpress:4 这个示例会创建(并不启动)WordPress 容器。不管你在中指定的是什么,该容器都会试着连上一个MySQL 数据库。由于远程数据库可能不会使用任何默认的用户名和密码,你就必须同时注入这些设置。假设数据库管理员是养猫爱好者且痛恨强密码: docker create \ --env WORDPRESS_DB_HOST=<my database hostname> \ --env WORDPRESS_DB_USER=site_admin \ --env WORDPRESS_DB_PASSWORD=MeowMix42 \ wordpress:4 使用环境变量注入这一方法,能帮助你区分WordPress 容器和MySQL 容器之间的物理联系。由于数据库和客户的WordPress 网站都在同一台机器上,你仍然需要解决前面提到的第二个问题——所有的网站都使用相同的默认数据库名称。你需要为每一个独立的站点设置数据库名称以环境变量的方式注入:你已经解决了这些问题,现在可以修改配置脚本了。首先,设置机器只能运行一个MySQL 容器: DB_CID=$(docker run -d -e MYSQL_ROOT_PASSWORD=ch2demo mysql:5) MAILER_CID=$(docker run -d dockerinaction/ch2_mailer) 那么网站配置脚本将是这样的:这个新脚本将为每一位客户启动WordPress 实例和监控器,并将这些容器以及一个单独的邮件程序和MySQL 数据库彼此连接。WordPress 容器在被销毁、重新启动、升级的同时,完全不用担心数据会丢失。如图所示就是这种架构。每个WordPress 和监控器容器使用相同的数据库和邮件服务 客户对当前交付的所有工作成果很满意。但有一件事可能会比较烦人。在早期的测试中,你发现监视器在该网站不可用时,的确可以准确通知邮件服务器,但重新启动该网站和监控器需要手动实现。要是系统在检测到故障时,能尝试自动恢复就更好了。Docker 对此提供了重启的策略,但仍不够稳定。 本文选自《Docker实战》。 想及时获得更多精彩文章,可在微信中搜索“博文视点”或者扫描下方二维码并关注。

优秀的个人博客,低调大师

nginx+tomcat+memcached构建session共享集群

一、安装配置tomcat 配置前说明: 系统为centos7 m1.xsllqs.com地址为192.168.1.107 c1.xsllqs.com地址为192.168.1.114 c2.xsllqs.com地址为192.168.1.113 安装tomcat需要配合JDK使用,JDK有oracle JDK和open JDK两种 oracle JDK8的下载地址:http://www.oracle.com/technetwork/cn/java/javase/downloads/jdk8-downloads-2133151-zhs.html tomcat的下载地址:http://tomcat.apache.org/ c1.xsllqs.com(192.168.1.114)下载安装jdk(建议加载到本地在传上去)和tomcat [root@c1~]#wgethttp://download.oracle.com/otn-pub/java/jdk/8u73-b02/jdk-8u73-linux-x64.rpm [root@c1~]#wgethttp://mirror.bit.edu.cn/apache/tomcat/tomcat-8/v8.0.36/bin/apache-tomcat-8.0.36.tar.gz [root@c1~]#ls apache-tomcat-8.0.36.tar.gzjdk-8u73-linux-x64.rpm [root@c1~]#yuminstalljdk-8u73-linux-x64.rpm [root@c1~]#vim/etc/profile.d/java.sh exportJAVA_HOME=/usr/java/latest exportPATH=$JAVA_HOME/bin:$PATH [root@c1~]#./etc/profile.d/java.sh [root@c1~]#java-version javaversion"1.8.0_73" [root@c1~]#tarxfapache-tomcat-8.0.36.tar.gz-C/usr/local [root@c1~]#cd/usr/local/ [root@c1local]#ln-svapache-tomcat-8.0.36tomcat "tomcat"->"apache-tomcat-8.0.36" [root@c1tomcat]#vim/etc/profile.d/tomcat.sh exportCATALINA_HOME=/usr/local/tomcat exportPATH=$CATALINA_HOME/bin:$PATH [root@c1tomcat]#./etc/profile.d/tomcat.sh c2.xsllqs.com(192.168.1.113)下载安装jdk和tomcat [root@c2~]#wgethttp://download.oracle.com/otn-pub/java/jdk/8u73-b02/jdk-8u73-linux-x64.rpm [root@c2~]#wgethttp://mirror.bit.edu.cn/apache/tomcat/tomcat-8/v8.0.36/bin/apache-tomcat-8.0.36.tar.gz [root@c2~]#ls apache-tomcat-8.0.36.tar.gzjdk-8u73-linux-x64.rpm [root@c2~]#yuminstalljdk-8u73-linux-x64.rpm [root@c2~]#vim/etc/profile.d/java.sh exportJAVA_HOME=/usr/java/latest exportPATH=$JAVA_HOME/bin:$PATH [root@c2~]#./etc/profile.d/java.sh [root@c2~]#java-version javaversion"1.8.0_73" [root@c2~]#tarxfapache-tomcat-8.0.36.tar.gz-C/usr/local [root@c2~]#cd/usr/local/ [root@c2local]#ln-svapache-tomcat-8.0.36tomcat "tomcat"->"apache-tomcat-8.0.36" [root@c2tomcat]#vim/etc/profile.d/tomcat.sh exportCATALINA_HOME=/usr/local/tomcat exportPATH=$CATALINA_HOME/bin:$PATH [root@c2tomcat]#./etc/profile.d/tomcat.sh 二、修改tomcat配置文件 [root@c1tomcat]#cd/usr/local/tomcat/webapps/ [root@c1webapps]#mkdirmyapp/{lib,classes,WEB-INF,META-INF}-pv [root@c1webapps]#cdmyapp/ 添加c1和c2的主页文件 [root@c1myapp]#vimindix.jsp <%@pagelanguage="java"%> <html> <head><title>Tomcat1</title></head> <body> <h1><fontcolor="red">c1.xsllqs.com</font></h1> <tablealign="centre"border="1"> <tr> <td>SessionID</td> <%session.setAttribute("xsllqs.com","xsllqs.com");%> <td><%=session.getId()%></td> </tr> <tr> <td>Createdon</td> <td><%=session.getCreationTime()%></td> </tr> </table> </body> </html> [root@c2myapp]#vimindix.jsp <%@pagelanguage="java"%> <html> <head><title>Tomcat2</title></head> <body> <h1><fontcolor="blue">c2.xsllqs.com</font></h1> <tablealign="centre"border="1"> <tr> <td>SessionID</td> <%session.setAttribute("xsllqs.com","xsllqs.com");%> <td><%=session.getId()%></td> </tr> <tr> <td>Createdon</td> <td><%=session.getCreationTime()%></td> </tr> </table> </body> </html> 修改tomcat-user.xml(c1和c2都要改) [root@c1conf]#vim/usr/local/tomcat/conf/tomcat-users.xml #在</tomcat-users>中添加 <rolerolename="manager-gui"/> <rolerolename="admin-gui"/> <userusername="tomcat"password="<tomcat>"roles="manager-gui,admin-gui"/> 修改server.xml(c1和c2都要改) [root@c1conf]#vim/usr/local/tomcat/conf/server.xml #修改主配置文件,appBase后面是应用的相对路径也可以是绝对路径 <Hostname="localhost"appBase="webapps" unpackWARs="true"autoDeploy="true"> #这里是访问日志的设置 <ValveclassName="org.apache.catalina.valves.AccessLogValve"directory="logs" prefix="localhost_access_log"suffix=".txt" pattern="%h%l%u%t&quot;%r&quot;%s%b"/> #这里设置Context调用msm需要的组件,m1为主c2为备,因为我这里只有3台机器所以把c2作为备,正常情况是4台,2台memcached和2台tomcat <Contextpath="/myapp"docBase="/usr/local/tomcat/webapps/myapp"reloadable="true"> <ManagerclassName="de.javakaffee.web.msm.MemcachedBackupSessionManager" memcachedNodes="m1:192.168.1.107:11211,c2:192.168.1.113:11211" failoverNodes="m1" requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$" transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory" /> </Context> 测试配置文件 [root@c1~]#catalina.shconfigtest [root@c2~]#catalina.shconfigtest [root@c1~]#catalina.shstart [root@c2~]#catalina.shstart 三、安装msm c1和c2上下载msm需要的jar包 [root@c1~]#wgethttp://repo1.maven.org/maven2/de/javakaffee/msm/memcached-session-manager/1.9.4/memcached-session-manager-1.9.4.jar [root@c1~]#wgethttp://repo1.maven.org/maven2/de/javakaffee/msm/memcached-session-manager-tc8/1.9.4/memcached-session-manager-tc8-1.9.4.jar [root@c1~]#wgethttp://repo1.maven.org/maven2/de/javakaffee/msm/msm-javolution-serializer/1.9.4/msm-javolution-serializer-1.9.4.jar [root@c1~]#wgethttp://repo1.maven.org/maven2/net/spy/spymemcached/2.11.1/spymemcached-2.11.1.jar [root@c1~]#wgethttp://www.java2s.com/Code/JarDownload/javolution/javolution-5.4.3.1.jar.zip [root@c1~]#mvjavolution-5.4.3.1.jarmemcached-session-manager-1.9.4.jarmemcached-session-manager-tc8-1.9.4.jarmsm-javolution-serializer-1.9.4.jarspymemcached-2.11.1.jar/usr/local/tomcat/lib/ m1和c2上安装memcached [root@m1~]#yuminstallmemcached [root@c2~]#yuminstallmemcached m1上安装nginx修改nginx的配置文件 [root@m1~]#yuminstallnginx [root@m1~]#vim/etc/nginx/nginx.conf #server外加入 upstreamtcsrvs{ server192.168.1.114:8080; server192.168.1.113:8080; } #server内加入 location~*\.(jsp|do)${ proxy_passhttp://tcsrvs; } [root@m1~]#nginx-t 启动服务 [root@m1~]#systemctlstartnginx.service [root@m1~]#systemctlstartmemcached [root@c2~]#systemctlstartmemcached 四、测试

优秀的个人博客,低调大师

基于docker构建jenkins和svn服务(转)

码农们很定都知道svn的重要性,机器坏掉丢代码的惨痛教训想必很多人都有。 jenkins可能很多人都不了解。这是一个持续集成的工具,在敏捷开发领域很流行;跟svn结合可以实现定期build、checkin之后build等功能。介绍可以看这里https://www.ibm.com/developerworks/cn/java/j-lo-jenkins/ 基于docker单独部署jenkins和svn都是很简单的事情,找到image,配置端口、配置volume,完事。 这篇文章主要介绍如何把两个服务连起来。 link是docker提供的重要工具,它提供类似名字服务的功能,link起来的容器可以通过名字标识访问。下面这篇文章详细介绍了link的使用方法和原理。http://dockerpool.com/static/books/docker_practice/network/linking.html 编排文件 用编排文件来描述互相依赖的服务是推荐的方式。这两个服务的编排文件如下。 jenkins: image: 'jenkins:latest' labels: aliyun.scale: '1' #端口映射。8080使用户访问的端口,50000是与svn交互的端口。不过这个例子中我们没有使用。 #另外,实际部署是需要添加volume ports: - '50000:50000/tcp' - '8080:8080/tcp' restart: always #使用link之后,可以用svn这个名字访问svn links: - svn:svn svn: environment: - SVN_REPONAME=repos image: 'erikxiv/subversion:latest' labels: aliyun.scale: '1' ports: - '3690:3690/tcp' restart: always 部署步骤 下面以阿里云容器服务为例,介绍一下部署过程1. 创建编排文件,输入上面的文件内容 用该编排文件启动服务 找到服务的节点IP,用http://节点IP:8080/访问jenkins服务 在jenkins上创建一个新项目,用link名访问svn http://yq.aliyun.com/articles/1830?spm=5176.100239.yqblog1.107.lyqEQr

优秀的个人博客,低调大师

物联网学习笔记——构建RESTFul平台1

0.前言 前些时间顺着Yeelink学习了RESTFUL,使用PHP和Slim框架尝试实现简单的REST API,树莓派可通过GET方法获得JSON数据包,通过这种方式实现了树莓派和服务器(我的PC)的互动。但是由于没有WEB前端,所以只能使用cURL工具或直接修改数据库的方式改变LED状态, 体验非常差。 REST API入门体验可参考 【 PHP再学习4—— slim框架学习和使用】 【 PHP再学习5——RESTFul框架 远程控制LED】 受到【 开源IOT——一个最小的物联网系统设计方案及源码】一文的影响。我决定除了服务器和嵌入式侧之外,我应该再多做一些。 WEB前端涉及到非常多的知识,下面提供一些学习资料。下面各种技术您可能不知道但是您一定用过。 【HTML】——超文本标记语言 【CSS】——级联样式表,能够对网页中的对象的位置排版进行像素级的精确控制 【Javascript】——网络的脚本语言 【Jquery】——JavaScript 库,极大地简化了 JavaScript 编程 【Ajax】——异步的 JavaScript 和 XML,与服务器交换数据并更新部分网页的艺术 本例部分源代码——【 HTML代码】 1.前端框架——Bootstrap 由于前端的内容太多了,需要学习很长的时间(技术可学习,但是审美我真学不来)。还好各路高手开发了前端框架可以让我们方便而美观的实现网页开发,而把精力放在真正的idea上。推荐使用Bootstrap框架,Bootstrap是Twitter推出的一个用于前端开发的开源工具包,是一个CSS/HTML框架。 学习资料 【 Bootstrap中文网】 【 Bootstrap 教程】 2.简单例子 下面一个简单的例子来自于Bootstrap中文网,仅修改了title和h1元素中等内容。 [html] view plain copy <!DOCTYPEhtml> <html> <head> <title>LEDRemoteControlTemplate</title> <metaname="viewport"content="width=device-width,initial-scale=1.0"> <!--Bootstrap--> <linkrel="stylesheet"href="http://cdn.bootcss.com/twitter-bootstrap/3.0.3/css/bootstrap.min.css"> </head> <body> <h1>LEDRemoteControlusingRESTAPI!</h1> <!--jQuery(necessaryforBootstrap'sJavaScriptplugins)--> <scriptsrc="http://cdn.bootcss.com/jquery/1.10.2/jquery.min.js"></script> <!--Includeallcompiledplugins(below),orincludeindividualfilesasneeded--> <scriptsrc="http://cdn.bootcss.com/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> </body> </html> 图1 简单例子 【若干说明】 【CDN】在这里并没有把Bootstrap框架放置于本地服务器,而是使用了CDN服务。CDN的全称是Content Delivery Network,即内容分发网络。其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。 【JQuery】Bootstrap需要JQuery的支持 【CSS和JS】先载入Bootscript的CSS样式,然后载入Bootscript的JS包。 3.加个表格 【设计思路】 上面的例子未免有些单薄,可再加入一些表格和DIV块。基本思路——网页分为3个部分,一个部分为Header,包含一些作者信息;第二部分为主要内容——表格,表格中包含LED设备的编号、描述和当前状态(打开或关闭)等,该部分内容和数据库中的表结构对应。最后一部分为footer,可包含一些其他的信息例如我的邮箱等。 【HTML】 [html] view plain copy <body> <divclass="container"> <divclass="row"> <divclass="span12"> <pclass="lead">徐凯经验分享小站</p> </div> </div> <divclass="row"> <divclass="span12"> <tableclass="tabletable-hover"> <thead> <tr> <th>编号ID</th> <th>描述DESC</th> <th>状态STATUS</th> <th>动作ACTION</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>RPi.PCF8574.IO0</td> <td>ON</td> <td>ACTION</td> </tr> <tr> <td>2</td> <td>RPi.PCF8574.IO1</td> <td>OFF</td> <td>ACTION</td> </tr> </tbody> </table> </div> </div> <divclass="row"> <divclass="span12"> <pclass="text-rightlead">如果有问题请邮件我,别客气</p> <pclass="text-rightlead"> <em>Email:xukai19871105@126.com</em> </p> </div> </div> </div> 图2 加入表格后的效果 【几点说明】 【container】<div class="container">container可理解为一个容器,该容器包裹了页面上的所有内容。 【网格布局】 bootstrap采用网格布局,<div class="row"> <div class="span12">row代表一行,span代表一行中的内容。在一行中最多可分为12个单元,最小单元用span1标记,最大单元用span12标记。举个例子<div class="span6">占用该行的6个单元,占用该行的一半。 【table】在bootstrap中可选择表格的风格,<table class="table table-hover">本例选择了hover形式,当鼠标移动到某一行时,该行的背景会变得灰色一些。这种简单的动态效果给用户更好的体验。 【thead tbody tr td】thead为表头标签,tbody为表格内容标签,tr为表格行标签,td为表格中的具体单元标签。 4.按钮热身 【设计思路】 在表格每行最后一个td标签中加入一个Button,点击该Button可以翻转stauts。例如点击Button,同行的Status会从ON变为OFF,再次点击从ON变为OFF。为了实现这种对应关系的操作,在tr标签中加入一个设备编号取名为dev_id。 【HTML】 [html] view plain copy <tableclass="tabletable-hover"> <thead> <tr> <th>编号ID</th> <th>描述DESC</th> <th>状态STATUS</th> <th>动作ACTION</th> </tr> </thead> <tbody> <trdev_id="1"> <td>1</td> <td>RPi.PCF8574.IO0</td> <td>off</td> <td> <buttontype="button"class="btnbtn-primarybtn-xs">Toggle</button> </td> </tr> <trdev_id="2"> <td>2</td> <td>RPi.PCF8574.IO1</td> <td>off</td> <td> <buttontype="button"class="btnbtn-primarybtn-xs">Toggle</button> </td> </tr> </tbody> </table> 图3 加入按钮后的效果 【几点说明】 【tr编号】 <tr dev_id="1"> 给每一行加入一个编号,1、2、3以此类推逐个排列。 【Button】<button type="button" class="btn btn-primary btn-xs"> bootstrap提供了多种标签风格,在这里选择最小号的Button——btn-xs。 5.按钮互动 【设计思路】 要实现按钮互动就需要写点javascript代码,幸好Javascript不算复杂非常容易学习。编程之前需要理解一下HTML节点的概念。在HTML中所有的元素都是节点,如此之多的节点组成了“树”,节点有父节点、有子节点也会有邻居节点。例如本例中,tr标签有4个td子节点(td子节点的编号从0开始),在最后一个td节点中又有一个button节点。 【tr dev_id="1"】——> 【td(id)】【td(desc)】【td(status)】【td(action)】 【td(action)】——> 【button】 那么如果点击button想要获得表格中该行dev_id的信息,那么就需要找button的“爷爷”索要。 【javascript】 [javascript] view plain copy <script> $(document).ready(function(){ $('.btn').on("click",function(){ //获得tr元素 vartrobj=$(this).parent().parent(); //tr元素中包含dev_id属性 vardev_id=trobj.attr('dev_id'); console.log(dev_id); //访问该tr元素的所有子td元素 vartdobj=$(trobj).children("td"); varstatus_obj=$(tdobj).eq(2); varstatus_str=status_obj.text(); console.log(status_str); if(status_str=="on"){ status_obj.text("off"); sendLedControl(dev_id,"off"); }else{ status_obj.text("on"); sendLedControl(dev_id,"on"); } }); }); </script> 【控制台查看效果】 web浏览器中的控制台有点和串口调试相似,在chrome浏览器中 工具->开发者工具。 图4 控制台调试 【若干说明】 【$(document).ready()】当 DOM(文档对象模型) 已经加载,并且页面(包括图像)已经完全呈现时,会发生 ready 事件。 【$('.btn').on("click",function())】按钮点击事件响应,$('.btn')代表所有所有class为btn的按钮——表格中最后一列按钮。 【this】在按钮点击事件中,this为button标签。如果使用console.log打印的话,输出内容为<button type="button" class="btn btn-primary btn-xs">Toggle</button>。但是$(this)则代表一个文件对象模型,$(this) 是一个完整的对象包含很多属性和方法。 【选择tr】var trobj = $(this).parent().parent(); 试图寻找button的爷爷 【获得dev_id】var dev_id = trobj.attr('dev_id'); dev_id在td标签中,使用attr方法便可获得目标属性。 【获得所有的td标签】var tdobj = $(trobj).children("td"); 此时td标签共有4个——返回4个td对象 【定位第2个td标签】var status_obj = $(tdobj).eq(2); eq(2)代表选择第2个(从0开始)td标签——对应status标签,var status_str = status_obj.text();取出当前内容并通过console.log打印。 【翻转操作,修改text】status_obj.text("off"); 使用text方法重新修改td标签的属性。 【发送PUT请求】 sendLedControl 请查看下节内容。 6.PUT更新 【设计思路】 使用ajax发送一个PUT请求,更多信息请参考【 PHP再学习5——RESTFul框架 远程控制LED】,PUT请求的格式如下: PUT /api/leds/1 Host: localhost Content-Length: 15 {"status":"on"} 【代码实现】 [javascript] view plain copy functionsendLedControl(dev_id,cur_status){ $.ajax({ url:'/api/leds/'+dev_id,///api/leds/1 async:true, dataType:'json', type:'PUT', data:JSON.stringify({status:cur_status}), success:function(data,textStatus){ console.log("success"); }, error:function(jqXHR,textStatus,errorThrown){ console.log("error"); }, }); } 【执行结果】 chrome浏览器 工具->开发者工具 选择Network Tag 图5 发送PUT请求 图6 查看status新状态 【若干说明】 【url】 /api/leds/1(和【 PHP再学习5——RESTFul框架 远程控制LED】略有差异),LED设备的"网址"。 【dataType】请求内容为JSON格式 【type】请求方法为PUT——更新某LED设备信息 【data】请注意使用JSON.stringify方法,转换之后的格式为{"status":"on"},若没有stringify方法转换的结果为status:on,这并不符合PUT上传内容的规范。 【 success 和 error】正确处理和错误处理方法。 【遗留问题】虽然PUT请求和响应完全正确,但是Jquery总是调用error。网上查找了众多博客和帖子依然没有解决。再思考是不是PUT请求没有响应导致的,修改服务器侧代码问题,使得PUT响应中包含更新之后的LED状态问题,问题随之解决。 7.总结和源码 因为对前端相关技术不熟悉,所以我以很认真的态度写完了这篇博文。如果您觉得内容中说的不清楚或者错误的地方请留言或者Email我。认真学完这篇博文,发现前端技术javascript,ajax和jquery没有想象的那么可怕甚至还挺好用的。这几天关注了espruino——使用javascript开发MCU的平台,总觉得工程师应该多学一些,见多识广才才行。 【 HTML代码】

优秀的个人博客,低调大师

卓越绩效运营模式的构建方法与IT意义

业务架构权威BIZBOK(Business Architecture Body of Knowledge,业务架构知识体系)在2017年7月颁布的v6.0版本中首次引入“运营模式”这个概念,到2022年还专门设置了一节阐述“业务架构与运营模式”的关系,认为“任何战略规划若没有同时识别并定义出支撑性的运营模式,以交付目标业务模式所期望的价值,就很可能是不完整的”。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册