ngularJS已然成为Web应用开发世界里最受欢迎的开源JavaScript框架。自成立以来,见证其成功的是惊人的经济增长以及团体的支持与采用——包括个人开发者、企业、社区。
Angular已经变成一个构建复杂单页面应用的客户端MVW框架(Model-View-Whatever)。它在应用测试和应用编写方面都扮演重要角色,同时简化了开发过程。
Angular目前的版本为1.3,该版本稳定,并被谷歌(框架维护者)用于支持众多应用(据估计,在谷歌有超过1600个应用运行于Angular1.2或1.3)。Angular 2.0正式宣布与去年10月份的尼日利亚会议上,该版本不会是一个复杂的重大更新。
在进一步讨论Angular 2.0(估计发布日期为2015年底)之前,让我们简单的思考下新版本背后的哲学。Angular 2.0开发始于解决以下问题:
在尼日利亚会议上并没有提及迁移到2.0版本的途径。同时也指出跳转到2.0版本将会打破原有的1.3版本应用,不会有任何的向后兼容性。自从那时开始开发者社区一直充斥着不确定性和猜测,一些开发者也开始质疑是否值得开始一个新的Angular 1.3项目。
AtScript
AtScript是ES6的一个父集,被用于开发Angular 2.0。它是由Traceur编译器(连同ES6)处理来生成ES5代码并用TypeScript类型语法来生成执行时间的断言,以此来代替编译时的检查。不过AtScript并不是强制的,你仍然能够使用纯JavaScript/ES5代码代替AtScript来编写Angular应用。
改善依赖入驻(DI)
依赖注入(Dependency injection )模式的基本思想是客户类Client不用自己来初始化它所依赖的成员变量IServer,使用一个独立的对象创建IServer适当的实现类并将它赋值给Client的成员变量。它对模块开发与组件隔离特别有益。Angular 2.0将会解决Angular 1.X所存在的这个方面的问题。添加丢失的的特性,如child injectors和lifetime/scope控制。
Annotations
AtScript提供工具关联元数据和功能。这有助于构建提供必要信息到DI库的对象实例(检查相关元数据时调用一个函数或创建一个类的实例)。它还容易通过提供一个注解重载参数数据。
Child Injectors
一个child injector继承了其父类的所有性能服务。根据要求,不同类型的对象可以被调用,并且自动覆盖不同的范围。
实例范围
改进的DI库将以实例范围为特性,这在使用Child Injectors和自己的范围标识符时变得更加强大。
模板和数据绑定
在开发应用中,模板和数据绑定将齐头并进。
动态载入
这是当前Angular版本所缺失的一个特性,不过将在Angular 2.0中出现。这将让开发者可以在忙碌中添加新的指令或控制器。
模板
在Angular 2.0中,模板编译过程将是异步的。由于代码是基于ES6模块规格,该模块加载器将通过简单的引用组件定义来加载依赖关系。
指令
在Angular 2.0中将会出现三种指令:
初始的Angular路由是被设计用于处理一些简单的情况。然而,随着框架的发展,越来越多的功能被添加。在Angular 2.0中路由已经是可扩展的,它将包含以下基本功能:
现在,让我们来看看那些让Angular 2.0达到新高度的路由特性:
子路由
子路由将把应用的每个组件通过为它们提供各自路由的方式转换成更小的应用,这将有助于封装整个应用的特性集。
屏幕激活
这将帮助开发者通过一组can*回调更出色的控制导航的生命周期:
这些回调将允许开发者返回Boolean值或一个命令(为了更低层次上的控制)。
设计
所有的这些逻辑都是使用流水线结构构建的,使得它非常容易将自己的步骤添加到流水线中或移除默认的东西。此外,它的异步特性将允许开发者使用服务器请求进行身份验证或为控制器加载数据,不过这还在规划中。
Angular 2.0将包含一个被称为diary.js的日志服务——一个非常有用的特性,测量你在应用中时间花费在哪里。
$scope将从Angular 2.0中移除,取而代之的是ES6类。
随着发布日期的临近,围绕Angular 2.0的兴奋和声音将会加剧。是否打破改变是一件好事?我们无法知道,不过反对者感到紧张是可以理解的,因为明显缺乏迁移的计划。Duang的一下就来了。不过其既然要来了,我们可以做的就是积极的迎接它。
原文来自:sitepoint
司使用python+selenium+pytest来做UI自动化测试,我经历了从0开始搭建自动化工程、开发测试报告web服务、编写测试用例,经过了一段时间的磨合,感觉已经比较顺手了,这里梳理下我采用的自动化工程目录组织结构。
整个目录结构如下,其中第一级目录和文件有:
project_name
conf
settings.py
logic
__init__.py
logic.py
mysql.py
testsuite
feature01
test_feature01.py
feature02
test_feature02.py
utils
utils.py
.gitignore
conftest.py
pytest.ini
requirements.txt
runall.py
README.md
目录组织示例
下面的配置主要是针对日志格式和级别进行了设置,log_cli开头的配置是针对控制台输出设置的,log_file开头的是针对输出到日志文件来设置的,会生成run.log日志文件,在./log目录下,如果log目录不存在会自动创建。
[pytest]
log_cli=1
log_cli_level=INFO
log_cli_date_format=%Y-%m-%d-%H-%M-%S
log_cli_format=%(asctime)s - %(filename)s - %(module)s - %(funcName)s - %(lineno)d - %(levelname)s - %(message)s
log_file=./log/run.log
log_file_level=INFO
log_file_date_format=%Y-%m-%d-%H-%M-%S
log_file_format=%(asctime)s - %(filename)s - %(module)s - %(funcName)s - %(lineno)d - %(levelname)s - %(message)s
列举依赖的python第三方库,可以指定版本,也可以不指定,不指定的情况下默认安装最新版本。文件示例内容如下,其中selenium、pytest、pytest-html、pytest-xdist是必须的,其他需要根据自己的项目情况来定。
xlrd >=1.2.0
openpyxl >=3.0.4
requests >=2.24.0
psutil >=5.7.2
pymysql >=0.10.0
selenium
pytest
pytest-html
pytest-repeat
elasticsearch
pyyaml
jsonpath
python-dateutil
paramiko
pytest-xdist
xlwt
pandas
runall.py文件主要是给jenkins等CI/CD工具拉起自动化任务使用的,它的主要作用就是执行pytest.main方法来使用pytest框架来收集并执行测试用例,最终会生成html和xml两份报告。
import os
import time
import pytest
from conf.settings import *
def new_report_dir():
return time.strftime("%Y-%m-%d")
def new_report_name(project="demo", file_type="html"):
"""file_type: 文件后缀名,默认为html
"""
now=time.strftime("%Y-%m-%d_%H-%M-%S")
report_name="{2}_{0}.{1}".format(now, file_type, project)
return report_name
if __name__=="__main__":
report_base_dir=r".\report"
report_html=os.path.join(report_base_dir, new_report_dir(), new_report_name())
report_xml=os.path.join(report_base_dir, new_report_dir(), new_report_name("demo", "xml"))
pytest.main(["--html={0}".format(report_html),
"--junit-xml={0}".format(report_xml),
"-n {0}".format(CPU_NUM),
"--dist=loadfile"])
但是,pytest默认生成的html报告并不友好,如果还想把历史数据做下统计分析就需要使用生成的xml报告了。比如通过flask框架可以快速定制开发出web服务,通过持续采集解析xml报告写入数据库作为数据源,不仅能更好地展现单次测试报告的数据,而且还能分析历史数据的统计曲线。
浏览器中实现用户界面时,请尽可能减少浏览器带来的差异,以使用户界面具有可预测性。跟踪所有这些差异很困难,因此,我整理了一些常见问题及其解决方案方便大家查看。
添加一个按钮时,重置它的背景,否则它会在不同的浏览器中看起来不同。在下面的例子中,同样的按钮在 Chrome 和 Safari 中,后者添加了默认的灰色背景。
重置按钮的样式可以解决些问题:
button {
appearance: none;
background: transparent;
}
事例源码:https://codepen.io/shadeed/pen/MzWBYv
要限制元素的高度并允许用户在其中滚动,可以添加overflow: scroll-y。在 macOS 上的Chrome上会很好看。然而,在 Windows上,滚动条总是在那里(即使内容很短)。这是因为无论内容如何,scroll-y都会显示滚动条,这时候我们可以使用overflow: auto,它只会在需要时显示滚动条。
.element {
height: 300px;
overflow-y: auto;
}
事例源码:https://codepen.io/shadeed/pen/vQYwXj
对包含多个子元素使用 display: flex,如果元素过多,所有子元素会被压缩,如下所示:
<div class="wrapper">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
.wrapper {
display: flex;
}
.item {
flex: 0 0 120px;
height: 100px;
}
面的例子在大屏幕上非常有用。在移动设备上,浏览器会显示一个水平滚动条。
解决方法就是使用 flex-wrap: wrap,这样当水平空间不够时,浏览器会帮我们自动换行。
事例源码:https://codepen.io/shadeed/pen/JejVLG
当将justify-content: space-between应用于flex容器时,它将分配元素并在元素之间留出相等的空间。我们的示例有8个卡片项,它们看起来不错。如果,由于某种原因,项目的数量是7呢?第二行元素看起来与第一行不同。
在这种情况下,使用CSS网格会更合适。
事例源码:https://codepen.io/shadeed/pen/XyWLLo
当在移动屏幕上阅读一篇文章时,一个长单词或内联链接可能会导致出现水平滚动条。使用CSS word-break可以防止这种情况的发生
解决方法:
.article-content p {
word-break: break-all;
}
当渐变是以 transparent 开始或者结束的时候,在Safari中看起来会有点黑。这是因为Safari不能识别关键字transparent,这里可以通过rgba(0,0,0,0)来解决该问题。请注意下面的截图:
出问题的代码:
.section-hero {
background: linear-gradient(transparent, #d7e0ef), #527ee0;
/*Other styles*/
}
解决方式:
.section-hero {
background: linear-gradient(rgba(0, 0, 0,0), #d7e0ef), #527ee0;
/*Other styles*/
}
在CSS grid中,repeat函数可以创建响应列布局,而不需要使用媒体查询。要做到这一点,使用auto-fill或auto-fit即可。
.wrapper {
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
}
简而言之,auto-fill将在不扩展列宽的情况下对列进行排列,而auto-fit只会在列为空的情况下将列折叠到零宽度。
如果将元素固定在屏幕顶部,如果视口不够高会发生什么情况?很简单:它会占用屏幕空间,因此,用户浏览网站时可用的垂直区域就会变小,这会影响用户的体验。解决方法不是当用户往下划动的时候,固定头部需要回到文档中跟随屏幕滚动,可以使用position: sticky来快速达到该效果。
@media (min-height: 500px) {
.site-header {
position: sticky;
top: 0;
/*other styles*/
}
}
在上面的代码段中,我们告诉浏览器仅在视口的高度等于或大于 500`像素时才标题固定在顶部。
使用 position: sticky 还需要指定 top 值,不然它无法正常工作。
事例源码:https://codepen.io/shadeed/pen/oQLYmg
当添加图像时,定义max-width: 100%,这样当屏幕很小时图像就会改变大小。否则,浏览器将显示一个水平滚动条。
img {
max-width: 100%;
}
CSS grid 常规布局中 main 和 aside 部分,为了让布局更加的完美,我们应该让 aside 高度等于 main 高度,即使 aside 内容为空。
要解决这个问题,将aside元素对齐到其父元素的开始位置,这样它的高度就不会扩大。
.wrapper {
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
grid-gap: 20px;
}
// align-self will tell the aside element to align itself with the start of its parent.
aside {
grid-column: 1 / 4;
grid-row: 1;
align-self: start;
}
main {
grid-column: 4 / 13;
}
事例源码: https://codepen.io/shadeed/pen/yQJgXr
有时,在使用 SVG 时,如果在 SVG 中以内联方式添加了fill属性,填充就不会像预期的那样工作。要解决这个问题,可以从SVG本身删除fill属性,也可以覆盖fill: color。
举个例子:
.some-icon {
fill: #137cbf;
}
如果 SVG 具有内联fill,这将不起作用,应该这样写:
.some-icon path {
fill: #137cbf;
}
我经常使用伪元素,它们为我们提供了一种创建伪造元素的方法,主要用于装饰目的,而无需将其添加到HTML中。
使用它们时,我们经常会忘记下面这些步骤:
在使用伪元素的时候,记得要添加 content 属性,不然会无法显示其内容,别外也需要定义 display ,设置宽高才有效。
为多个元素设置 display: inline-block或 display: inline,会在每个元素之间创建一个很小的空格。之所以会添加空格,是因为浏览器将元素解释为单词,因此在每个元素之间添加了一个字符空间。
在下面的示例中,每个项目的右侧都有8px的空间,但是由于使用display:inline-block导致增加了一个空格,最后结果是12px,这不是期望的结果。
一个简单的修复方法是在父元素上设置font-size: 0。
ul {
font-size: 0;
}
li {
font-size: 16px;
}
事例源码:https://codepen.io/shadeed/pen/qQYPxV
在处理表单元素时,可以为label元素分配一个id,这将增加表单的可访问性,当label 元素被点击时,对应的 input 也会获取焦点。
<label for="emailAddress">Email address:</label>
<input type="email" id="emailAddress">
当为整个文档设置字体时,它们不会应用于input、button、select和textarea等元素。它们在默认情况下不会继承,因为浏览器将默认系统字体应用于它们。
要修复此问题,需要我们手动分配字体属性:
input, button, select, textarea {
font-family: your-awesome-font-name;
}
由于元素的宽度,有些元素会导致出现水平滚动条。
找到这个问题的原因最简单的方法就是使用 「CSS outline」。Addy Osmani 分享了一个非常方便的脚本,可以添加到浏览器控制台,列出页面上的每个元素。
[].forEach.call($$("*"), function(a) {
a.style.outline="1px solid #" + (~~(Math.random() * (1 << 24))).toString(16);
});
在CSS中调整图像大小时,如果宽高比与图像的宽度和高度不一致,则可能会对其进行压缩或拉伸。
解决方法很简单:使用CSS object-fit,它的功能类似于ackground-size: cover用于背景图像。
img {
object-fit: cover;
}
使用object-fit并不是在所有情况下都适用。有些图片需要在没有裁剪或调整大小的情况下显示,有些平台会强制用户上传或裁剪一个定义大小的图片。例如,Dribbble接受以800 * 600像素上传的缩略图。
为 input 添加正确的 type,会增强移动浏览器中的用户体验,并使其更易于用户访问。
假设有如下的 HTML 代码:
<form action="">
<p>
<label for="name">Full name</label>
<input type="text" id="name">
</p>
<p>
<label for="email">Email</label>
<input type="email" id="email">
</p>
<p>
<label for="phone">Phone</label>
<input type="tel" id="phone">
</p>
</form>
下面是每个 input 元素在移动端输入的样子。
在从右到左的布局中添加电话号码(如+ 972-123555777)时,加号将定位在电话号码的末尾。要解决这个问题,重新分配电话号码的方向即可。
p {
direction: ltr;
}
里提到的所有问题都是我在前端开发工作中遇到的最常见的问题,希望能对你们有些帮助。
作者:Chidume Nnamdi 译者:前端小智 来源:smashingmagazine
原文:https://www.reddit.com/r/css/comments/aakwgr/common_css_issues_for_frontend_proects/
*请认真填写需求信息,我们会在24小时内与您取得联系。