Jade 代码:
html
head
title Modal Window
link(href="/window.css", rel="stylesheet", type="text/css")
script(src="/window.js", type="text/javascript")
body
div.content_container
div.content
span I am content here!
span here make the content long long long long long long ...
a(href="#", onclick="open_window()") click me to open window.
div#my_window.modal_window_container
div#my_real_window.modal_window
div.window_bar
a.close_button(href="#", onclick="close_window()")
div.window_body
p I am content in window.
我们温故知新一下,div#my_window.modal_window_container
这个 Jade 的语法,表示一个 DIV,id 是 my_window
, class 是 modal_window_container
。
我们在这个基础上增加一个 class,比如 #my_window.modal_window_container.new_class
,(此处没有使用 div 开头,因为 Jade 默认的 DOM 类型就是 DIV),最终得到的 HTML 代码如下:
<div id='my_window' class='modal_window_container new_class'> </div>
.modal_window_container{
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
background: rgba(0, 0, 0, 0.75);
}
.modal_window{
position: absolute;
left: 60px; top: 50px;
width: 500px; height: 350px;
border-radius: 10px;
background: rgba(255, 255, 255, 0.8);
.window_bar{
position: relative;
height: 30px;
background: red;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
.close_button{
font-family: sans-serif;
text-decoration: none;
position: absolute;
right: 5px; top: 0px;
width: 30px; height: 30px;
line-height: 30px;
color: #fff;
&:before{
content: "x"; margin-left: 10px;
}
&:hover{ color: black; }
}
}
}
var open_window = function(){
// 显示窗口
var my_window = document.getElementById('my_window');
my_window.style.display = 'block';
// 计算坐标,保持居中
var my_real_window = document.getElementById('my_real_window');
var page_width = document.documentElement.clientWidth;
var page_height = document.documentElement.clientHeight;
my_real_window.style.left = (page_width - my_real_window.clientWidth)/2 + 'px';
my_real_window.style.top = (page_height - my_real_window.clientHeight)/2 + 'px';
}
var close_window = function(){
var my_window = document.getElementById('my_window');
my_window.style.display = 'none';
}
我们在最初介绍 Javascript 的时候,说它是可以改变 HTML 与 CSS 的。一般 Javascript 上的基础逻辑:
document.getElementById
(这是一个函数)
document.documentElement.clientWidth
my_real_window.style.left = ?
的赋值
对了,(page_width - my_real_window.clientWidth)/2 + 'px'
中,其实是 整数+字符串
,在其它编程语言中,这两种不同类型一般是无法相加的;但这个也呈现了 Javascript 『不拘小节』的特性。
虽然与 HTML、CSS 相比,Javascript 的难度上了不止一个等级;但因为这种『不拘小节』,也说明它最初来到世界时,本身是不严谨的,换句话说,它的上手难度其实也不会太高。
只要自己想要达到什么效果,而 HTML+CSS 无法满足的时候,就可以尝试使用 Javascript,在具体解决问题的过程中,会很自然地学会基础的 Javascript。
HTML+CSS 的复用,是通过 CSS 的样式规则来实现的,大部分就是 CSS 中 类(class) 的概念。
而 Javascript 的复用是一个 .js 文件、库、函数、类,这也是大部分编程语言的复用模式。
Javascript 中 类(class) 的概念,或者说几乎所有(后端)编程语言,都有 类 的概念,这个与 CSS 中 类 的概念是截然不同的,这要分清楚。`
在本段中,我们使用的是原生的 Javascript,在实际项目中,我们一般会引入 jQuery 这个基础框架,从而提高代码的可读性,以及写代码的效率。
说到 Javascript 的框架,或许未来你会面对 Angular、React、Vue,但它们与 jQuery 相比,更倾向于 App 方向;而 jQuery 可以单纯理解为更容易书写的 Javascript。
现在大部分 Javascript 的框架,会和 Node.js
关联在一起。Node.js
是后端语言,跑在服务器上,用的语法跟 Javascript 一样;而 HTML、CSS、Javascript 是前端语言,跑在浏览器上的。
简而言之,在入门阶段,Javascript 的 框架,用 jQuery 就好;其它的,未来有需要,一边用一边学就好了。
注意: 一般实际项目中,如非必要不会自己手工写弹窗的机制,而只是处理弹窗的内容布局,弹窗本身的机制会引入对应的 Javascript 库。简言之,本 Demo 的意义,就是在于 Demo,而非实际应用场景。
有一个问题,怎么默认不让弹窗显示,只有点击某个触发的链接才打开弹窗呢?
很简单呀,.modal_window_container
CSS 设个默认属性为 display: none
就可以了。
引入 Javascript 后,我们可以关闭弹窗、触发弹窗了,弹窗的窗口也居中了 (如下图):
height == line-height
的时候,就可以了。
height: 30px;
line-height: 30px;
如果是多行的垂直居中,会比较麻烦,因为一个元素在使用 CSS 样式渲染的时候,其实并不知道自己当前当前的高度,这个高度往往是由内部所有的子元素+当前元素属性
决定的。高度未知,就无法做到垂直方向的居中;当然,此时可以使用 Javascript 了。
但是,在本课程最开始的 Level 1 里,我们已经介绍过垂直居中的办法了,现在再回过头去看看,或许也能更容易理解一些。
比如 Demo 中弹窗的关闭按钮,其实就是一个 A 元素(超级链接),只是点击它的时候,打开的并不是网页,而是调用了一个 Javascript 的函数。
同样,我们在 Level 1 最开始的时候,已经介绍过 函数 是什么,如果 HTML+CSS 构建的最终页面,需要交互,基本上都会引入 Javascript,也经常可以放在一个 A 元素上面,点击从而触发事件。
因为 A 元素本身有兼容性更广的伪类支持,比如 a:hover
,表示鼠标悬浮其上时候的状态。
兼容性更广是什么意思?
在更早版本的浏览器,特别是 IE 浏览器,非 A 元素的 :hover
这个伪类是不生效的……
另外一方面,由于普通的页面,基本上都是引入了 Javascript,而多数的 Javascript 基础库会对应浏览器的一些兼容问题,:hover
这个伪类的触发,通过 Javascript 的机制也能实现。
于此同时,我们应该要说明下: 如非必要,不引入 Javascript 的基本原则。但也不用太在乎这个原则,权作为一种提醒;因为,真需要用到 Javascript 的时候,也就是说明它是必要的。
:hover
、:first-child
、:before
这些都是 CSS 的选择器,与此同时,:hover
是一个伪类,而 :before
是一个 伪元素。
所谓的 类
,在 HTML+CSS 的概念中,就是 HTML 中的 class,一般对应到 CSS 中以 .
开头的规则名。
所谓的伪类
,就是说,它是一个 class,但并不是常见的以 .
开头的。
所谓的 伪元素
,我们在前面其实已经接触到好几次了,除了 :before
之外还有 :after
,它们的意思是,首先是一个 DOM元素,其次,它们实际没有出现在 HTML 的源码中,是由 CSS 规则构造出来的。
换个角度来看,知道这些术语的存在即可,不深究。
比如 :hover
肯定会用起来的,但是不知道它叫 伪类
,又有什么关系?
如果 :before
用起来了,知道它怎么使用,同样也不知道叫 伪元素
,肯定也没有关系!
另外呢,伪元素
就算不会用,直接在 HTML 的结构中通过其它真实的元素,完成视觉修饰的作用,也肯定没有关系!
从实用主义出发,我们追求用起来就已经足够了。即使用得不熟练,能知道怎么用(可能还需要通过搜索引擎获取帮助),其实是不会影响最终界面的实现。
但是,从纯技术的角度出发,假设你不知道这些基本技术术语,是要出问题的。
自己把握这个度,就可以了。