1、 Listener
Java监听器是实现了javax.servlet.ServletContextListener 接口的服务器端程序。
监听观察某个事件(程序)的发生情况,当被监听的事件真的发生了的时候,事件发生者(事件源) 就会给注册该事件的监听者(监听器)发送消息,告诉监听者某些信息,同时监听者也可以获得一份事件对象,根据这个对象可以获得相关属性和执行相关操作。
Listener.png- web应用服务器通过监听器来监听servlet和与之对应的jsp中的三个内置对象。
- web监听器本身是servlet规范定义的一种特殊类
- 用于监听ServletContext、HttpSession、ServletRequest等域对象的创建、销毁、及其属性修改变化发生的事件
- 其主要作用是做一些初始化的内容添加工作,设置一些基本的内容(一些参数、固定的对象等)。
- 可以在事件发生前后进行一些必要的处理操作
2、 常用场景
- 统计在线人数和在线用户
- 网站页面访问量统计
- 应用启动时完成信息初始化工作
- 与spring结合
- Web系统防止用户重复登陆
3、 实现步骤
-1- 编写Java类实现监听器接口,并实现其接口方法。
-2- 在web.xml文件中对实现的监听器类进行注册。
3.1 监听三个域对象创建和销毁的事件监听器
- ServletContextListener 接口用于监听 ServletContext 对象的创建和销毁事件。
- 当 ServletContext 对象被创建时,激发contextInitialized (ServletContextEvent sce)方法
- 当 ServletContext 对象被销毁时,激发contextDestroyed(ServletContextEvent sce)方法。
- servletContext域对象何时创建和销毁:
- 创建:服务器启动,针对每一个web应用创建servletcontext
- 销毁:服务器关闭前,先关闭代表每一个web应用的servletContext
3.1.1 servlet案例
监听三个域对象创建和销毁的事件监听器.pngservlet3.0可以不必在web.xml中配置 程序中有注解@WebListener
- MyServletContextListener
@WebListener
public class MyServletContextListener implements ServletContextListener {
public MyServletContextListener() {
}
public void contextDestroyed(ServletContextEvent sce) {
//在ServletContext对象中获取域中的值
String appName = (String) sce.getServletContext().getAttribute("app_name");
String version = (String) sce.getServletContext().getAttribute("version");
//打印输出
System.out.println("appName="+appName);
System.out.println("version="+version);
}
public void contextInitialized(ServletContextEvent sce) {
// TODO Auto-generated method stub
//从web.xml获得初始化参数
String appName = sce.getServletContext().getInitParameter("app_name");
String version = sce.getServletContext().getInitParameter("version");
//将参数赋值到ServletContext作用域中
sce.getServletContext().setAttribute("app_name", appName);
sce.getServletContext().setAttribute("version", version);
//打印输出
System.out.println("appName="+appName);
System.out.println("version="+version);
}
}
- web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>ListenerDemoWebProj</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>app_name</param-name>
<param-value>Listener Web</param-value>
</context-param>
<context-param>
<param-name>version</param-name>
<param-value>1.0</param-value>
</context-param>
<listener>
<listener-class>com.alan.listener.MyServletContextListener</listener-class>
</listener>
</web-app>
3.1.2 SessionListener案例
- HttpSessionListener接口用于监听HttpSession的创建和销毁
- 创建一个Session时,sessionCreated(HttpSessionEvent se) 方法将会被调用
- 销毁一个Session时,sessionDestroyed (HttpSessionEvent se) 方法将会被调用(此处复习session对象,写多个servlet都去getSession,看session的创建)
-
Session域对象创建和销毁的时机
创建:用户每一次访问时,服务器创建session
销毁:如果用户的session 30分钟没有使用,服务器就会销毁session,我们在web.xml里面也可以配置session失效时间
HttpSessionListener.png
每一个浏览器就会创建一个session
- MyHttpSessionListener
public class MyHttpSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent hse) {
String sessionId = hse.getSession().getId();
Date createTime = new Date(hse.getSession().getCreationTime());
System.out.println("session id:"+sessionId+",createTime:"+createTime);
}
@Override
public void sessionDestroyed(HttpSessionEvent hse) {
String sessionId = hse.getSession().getId();
System.out.println("session destroyed,session id:"+sessionId);
}
}
- web.xml
访问index.jsp,创建一个会话,后台输出sessionId,再用另一个浏览器访问,就会再创建一个sessionId,一分钟后销毁。
<listener>
<listener-class>com.listener.MyHttpSessionListener</listener-class>
</listener>
<!-- 配置session失效时间,为1分钟 -->
<session-config>
<session-timeout>1</session-timeout>
</session-config>
3.1.3 ServletRequestListener案例
ServletRequestListener.png- ServletRequestListener
@WebListener
public class MyServletRequestListener implements ServletRequestListener {
public MyServletRequestListener() {
// TODO Auto-generated constructor stub
}
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("request listener destroyed...");
}
public void requestInitialized(ServletRequestEvent sre) {
//向下转型
HttpServletRequest request = (HttpServletRequest)sre.getServletRequest();
//获得请求路径和请求参数
String path = request.getRequestURI();
String par = request.getParameter("par");
System.out.println("request listener path:"+path+",par:"+par);
}
}
3.2 域对象中属性的创建、替换和消除事件监听器
域对象中属性的创建、替换和消除事件监听器.png- ServletContextAttributeListener案例
@WebListener
public class MyServletContextAttributeListener implements ServletContextAttributeListener {
public MyServletContextAttributeListener() {
// TODO Auto-generated constructor stub
}
public void attributeAdded(ServletContextAttributeEvent scae) {
System.out.println("attributeAddedname:"+scae.getName()+",value:"+scae.getValue());
}
public void attributeRemoved(ServletContextAttributeEvent scae) {
System.out.println("attributeRemoved name:"+scae.getName()+",value:"+scae.getValue());
}
public void attributeReplaced(ServletContextAttributeEvent scae) {
System.out.println("attributeReplaced name:"+scae.getName()+",value:"+scae.getValue());
}
}
3.3 绑定到session中的某个对象的状态事件监听器
绑定到session中的某个对象的状态事件监听器.png监听绑定到 HttpSession 域中的某个对象的状态的事件监听器 (查看API文档)
- ServletRequestListener 接口用于监听ServletRequest 对象的创建和销毁
- Request 对象被创建时,监听器的requestInitialized方法将会被调用
- Request对象被销毁时,监听器的requestDestroyed方法将会被调用(此处复习request对象,在浏览器窗口中多次刷新访问servlet,看request对象的创建和销毁,并写一个servlet,然后用sendRedirect、forward方式跳转到其它servlet,查看request对象的创建和消耗)
- servletRequest域对象创建和销毁的时机:
- 创建:用户每一次访问,都会创建一个reqeust
- 销毁:当前访问结束,request对象就会销毁
不需要在web.xml中注册,即可使用
- HttpSessionBindingListener
//@WebListener
public class User implements HttpSessionBindingListener {
private String username ;
private String passowrd;
public User() {
// TODO Auto-generated constructor stub
}
public void valueBound(HttpSessionBindingEvent hsbe) {
String name = hsbe.getName();
System.out.println("valueBound name:"+name);
}
public void valueUnbound(HttpSessionBindingEvent hsbe) {
String name = hsbe.getName();
System.out.println("valueUnbound name:"+name);
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassowrd() {
return passowrd;
}
public void setPassowrd(String passowrd) {
this.passowrd = passowrd;
}
}
4、 项目案例
-1 通过过滤器实现登录控制,未登录用户不能访问系统首页
-2 用户登录,将登录名存储到session里
-3 登录监听器监听session属性中登录值属性变化
-4 若登录用户用户名已登录系统,清除前次登录信息
-5 记录该次登录信息至缓存中,用于下次登录判断
4.1 登陆权限过滤验证
public class SessionFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest hrequest = (HttpServletRequest)request;
HttpServletResponse hresponse = (HttpServletResponse)response;
String loginUser = (String)hrequest.getSession().getAttribute("loginUser");//从session对象中获取登录用户名
if(loginUser==null){//登录用户名不存在,用户未登录,强制重定向至登陆页面
hresponse.sendRedirect(hrequest.getContextPath()+"/index.jsp?flag=1");
return;
}else{
chain.doFilter(request, response);//已登录,转入相应的请求处理
return;
}
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
4.2 用户信息存储
/** 这里用到了单例模式 **/
public class LoginCache {
private static LoginCache instance = new LoginCache();
/**servlet api 3.0版本中HttpSessionContext中的httpSession不支持直接通过sessionId获得Session对象**/
/** 因此通过用户名获取sessionId,然后通过sessionId获取session**/
private Map<String,String> loginUserSession = new HashMap<String,String>();// key值:登录用户登录名,value值:登录用户sessionId
private Map<String,HttpSession> loginSession = new HashMap<String,HttpSession>();//key值:登录用户sessionId,value值:登录用户session对象
private LoginCache(){
}
public static LoginCache getInstance(){
return instance;
}
/**
* 通过登录名获取对应登录用户的sessionId
* @param username
* @return
*/
public String getSessionIdByUsername(String username){
return loginUserSession.get(username);
}
/**
* 通过sessionId获取对应的session对象
* @param sessionId
* @return
*/
public HttpSession getSessionBySessionId(String sessionId){
return loginSession.get(sessionId);
}
/**
* 存储登录名与对应的登录sessionID至缓存对象
* @param username
* @param sessionId
*/
public void setSessionIdByUserName(String username,String sessionId){
loginUserSession.put(username, sessionId);
}
/**
* 存储sessionId与对应的session对象至缓存对象
* @param sessionId
* @param session
*/
public void setSessionBySessionId(String sessionId,HttpSession session){
loginSession.put(sessionId, session);
}
}
4.3 监听功能
public class LoginSessionListener implements HttpSessionAttributeListener {
private static final String LOGIN_USER="loginUser";
@Override
public void attributeAdded(HttpSessionBindingEvent hsbe) {
String attrName = hsbe.getName();//监听到session属性值发生添加操作,获取对应操作的属性名
if(LOGIN_USER.equals(attrName)){//若属性名为登录属性名,判定为用户登录操作
String attrVal = (String)hsbe.getValue();//获取添加的属性值,即用户登录名
HttpSession session = hsbe.getSession();//该次操作的session对象
String sessionId = session.getId();//该次操作的session对象ID
String sessionId2 = LoginCache.getInstance().getSessionIdByUsername(attrVal);//从缓存对象里面,获得该用户登录名对应的sessionID值
if(null == sessionId2){//未获得结果,不需要清理前次登录用户会话信息
}else{
HttpSession session2 = LoginCache.getInstance().getSessionBySessionId(sessionId2);//获取前次该用户登录对应的session对象
session2.invalidate();//清理前次登录用户会话存储信息,使得前次登录失效
}
//完成该次登录用户登录名、sessionID,session对象的缓存对象存储
LoginCache.getInstance().setSessionIdByUserName(attrVal, sessionId);
LoginCache.getInstance().setSessionBySessionId(sessionId, session);
}
}
@Override
public void attributeRemoved(HttpSessionBindingEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void attributeReplaced(HttpSessionBindingEvent arg0) {
// TODO Auto-generated method stub
}
}
web.xml
<listener>
<listener-class>com.listener.LoginSessionListener</listener-class>
</listener>
<filter>
<filter-name>sessionFilter</filter-name>
<filter-class>com.filter.SessionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sessionFilter</filter-name>
<url-pattern>/main.jsp</url-pattern>
</filter-mapping>
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String flag = request.getParameter("flag");
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="form.css" rel="stylesheet" type="text/css" />
<title>Login</title>
<script type="text/javascript">
var flag = '<%=flag %>';
if("1"==flag){
alert("你尚未登陆,或者账号在异地登陆,请重新登陆!");
}
</script>
</head>
<body>
<form action="login.jsp" method="post" class="smart-green">
<h1>系统登录</h1>
<label>
<span>用户名:</span>
<input id="username" type="text" name="username"/>
</label>
<label>
<span>密码:</span>
<input id="password" type="password" name="password"/>
</label>
<span> </span>
<label>
<input type="submit" class="button" value="登录"/>
</label>
</form>
</body>
</html>
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String username = request.getParameter("username");
String password = request.getParameter("password");
session.setAttribute("loginUser", username);//登录完成,将登录用户名存储至session对象
response.sendRedirect(request.getContextPath()+"/main.jsp");
%>
main.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
String user = (String)session.getAttribute("loginUser");
%>
<!DOCTYPE html>
<html>
<head>
<title>Peculiar a Personal Portfolio Flat Bootstarp responsive Website Template| HOME :: w3layouts</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="keywords" content="Peculiar Responsive web template, Bootstrap Web Templates, Flat Web Templates, Andriod Compatible web template,
Smartphone Compatible web template, free webdesigns for Nokia, Samsung, LG, SonyErricsson, Motorola web design" />
<script type="application/x-javascript"> addEventListener("load", function() { setTimeout(hideURLbar, 0); }, false); function hideURLbar(){ window.scrollTo(0,1); } </script>
<link href="css/bootstrap.css" rel='stylesheet' type='text/css' />
<link href="css/style.css" rel='stylesheet' type='text/css' />
<script src="js/jquery-1.11.0.min.js"></script>
<!---- start-smoth-scrolling---->
<script type="text/javascript" src="js/move-top.js"></script>
<script type="text/javascript" src="js/easing.js"></script>
<script type="text/javascript">
jQuery(document).ready(function($) {
$(".scroll").click(function(event){
event.preventDefault();
$('html,body').animate({scrollTop:$(this.hash).offset().top},1000);
});
});
</script>
<!--start-smoth-scrolling-->
<!--animated-css-->
<link href="css/animate.css" rel="stylesheet" type="text/css" media="all">
<script src="js/wow.min.js"></script>
<script>
new WOW().init();
</script>
<!--animated-css-->
</head>
<body>
<!--start-banner-->
<div class="banner" id="home">
<div id="top" class="callbacks_container">
<ul class="rslides" id="slider4">
<li>
<div class="banner-1">
</div>
</li>
<li>
<div class="banner-2">
</div>
</li>
</ul>
</div>
<div class="clearfix"> </div>
<div class="header">
<div class="navigation">
<span class="menu"></span>
<ul class="navig">
<li><a href="index.html" class="scroll"><%=user %></a><span>|</span></li>
<li><a href="index.html" class="scroll">HOME</a><span>|</span></li>
<li><a href="#portfolio" class="scroll">PORTFOLIO</a><span>|</span></li>
<li><a href="#contact" class="scroll">CONTACT</a></li>
</ul>
</div>
<div class="clearfix"></div>
</div>
<div class="banner-bottom">
<ul>
<li><a href="#"><span class="twt"> </span></a></li>
<li><a href="#"><span class="t"> </span></a></li>
<li><a href="#"><span class="g"> </span></a></li>
</ul>
</div>
</div>
<!-- script-for-menu -->
<script>
$("span.menu").click(function(){
$(" ul.navig").slideToggle("slow" , function(){
});
});
</script>
<!-- script-for-menu -->
<!--Slider-Starts-Here-->
<script src="js/responsiveslides.min.js"></script>
<script>
// You can also use "$(window).load(function() {"
$(function () {
// Slideshow 4
$("#slider4").responsiveSlides({
auto: true,
pager: false,
nav: true,
speed: 500,
namespace: "callbacks",
before: function () {
$('.events').append("<li>before event fired.</li>");
},
after: function () {
$('.events').append("<li>after event fired.</li>");
}
});
});
</script>
<!--End-slider-script-->
<!--end-banner-->
<!--start-free-->
<div class="free wow bounce" data-wow-delay="0.1s">
<div class="container">
<div class="free-main">
<h1>PROIN CONVALLIS SED FELIS EU MALESUADA</h1>
<p><sup><img src="images/quote-1.png" alt=""></sup> Etiam in porttitor risus. Curabitur non diam id lacus facilisis consequat. Integer pulvinar ex nunc, id porttitor orci sollicitudin id. Morbi vitae sodales arcu, vel maximus neque. Nullam a faucibus justo sit. <sub><img src="images/quote-2.png" alt=""></sub> </p>
</div>
</div>
</div>
<!--end-free-->
<!-- Portfolio Starts Here -->
<div class="portfolios entertain_box wow fadeInUp" data-wow-delay="0.4s" id="portfolio">
<div class="container">
<div class="portfolio-top">
<ul id="filters" class="clearfix">
<li><span class="filter active" data-filter="app card icon logo web">All Portfolio</span></li>
<li><span class="filter" data-filter="app">Web Development</span></li>
<li><span class="filter" data-filter="photo">Mockups</span></li>
<li><span class="filter" data-filter="card">Scripts</span></li>
</ul>
<div id="portfoliolist">
<div class="portfolio app mix_all" data-cat="app" style="display: inline-block; opacity: 1;">
<div class="portfolio-wrapper">
<a href="images/p-1.jpg" class="b-link-stripe b-animate-go swipebox" title="Image Title">
<img src="images/port-1.jpg" /><div class="b-wrapper"><h2 class="b-animate b-from-left b-delay03 ">
<ul>
<li><img src="images/hrt.png" alt=""/></li>
<li><img src="images/srch.png" alt=""/></li>
<li><img src="images/rsh.png" alt=""/></li>
</ul>
</h2>
</div></a>
</div>
</div>
<div class="portfolio card mix_all" data-cat="card" style="display: inline-block; opacity: 1;">
<div class="portfolio-wrapper">
<a href="images/p-2.jpg" class="b-link-stripe b-animate-go swipebox" title="Image Title">
<img src="images/port-2.jpg" /><div class="b-wrapper"><h2 class="b-animate b-from-left b-delay03 ">
<ul>
<li><img src="images/hrt.png" alt=""/></li>
<li><img src="images/srch.png" alt=""/></li>
<li><img src="images/rsh.png" alt=""/></li>
</ul>
</h2>
</div></a>
</div>
</div>
<div class="portfolio photo mix_all" data-cat="photo" style="display: inline-block; opacity: 1;">
<div class="portfolio-wrapper">
<a href="images/p-3.jpg" class="b-link-stripe b-animate-go swipebox" title="Image Title">
<img src="images/port-3.jpg" /><div class="b-wrapper"><h2 class="b-animate b-from-left b-delay03 ">
<ul>
<li><img src="images/hrt.png" alt=""/></li>
<li><img src="images/srch.png" alt=""/></li>
<li><img src="images/rsh.png" alt=""/></li>
</ul>
</h2>
</div></a>
</div>
</div>
<div class="portfolio card mix_all" data-cat="card" style="display: inline-block; opacity: 1;">
<div class="portfolio-wrapper">
<a href="images/p-4.jpg" class="b-link-stripe b-animate-go swipebox" title="Image Title">
<img src="images/port-4.jpg" /><div class="b-wrapper"><h2 class="b-animate b-from-left b-delay03 ">
<ul>
<li><img src="images/hrt.png" alt=""/></li>
<li><img src="images/srch.png" alt=""/></li>
<li><img src="images/rsh.png" alt=""/></li>
</ul>
</h2>
</div></a>
</div>
</div>
<div class="portfolio photo mix_all" data-cat="photo" style="display: inline-block; opacity: 1;">
<div class="portfolio-wrapper">
<a href="images/p-5.jpg" class="b-link-stripe b-animate-go swipebox" title="Image Title">
<img src="images/port-5.jpg" /><div class="b-wrapper"><h2 class="b-animate b-from-left b-delay03 ">
<ul>
<li><img src="images/hrt.png" alt=""/></li>
<li><img src="images/srch.png" alt=""/></li>
<li><img src="images/rsh.png" alt=""/></li>
</ul>
</h2>
</div></a>
</div>
</div>
<div class="portfolio app mix_all" data-cat="app" style="display: inline-block; opacity: 1;">
<div class="portfolio-wrapper">
<a href="images/p-6.jpg" class="b-link-stripe b-animate-go swipebox" title="Image Title">
<img src="images/port-6.jpg" /><div class="b-wrapper"><h2 class="b-animate b-from-left b-delay03 ">
<ul>
<li><img src="images/hrt.png" alt=""/></li>
<li><img src="images/srch.png" alt=""/></li>
<li><img src="images/rsh.png" alt=""/></li>
</ul>
</h2>
</div></a>
</div>
</div>
</div>
</div>
</div>
</div>
<link rel="stylesheet" href="css/swipebox.css">
<script src="js/jquery.swipebox.min.js"></script>
<script type="text/javascript">
jQuery(function($) {
$(".swipebox").swipebox();
});
</script>
<!-- Portfolio Ends Here -->
<script type="text/javascript" src="js/jquery.mixitup.min.js"></script>
<script type="text/javascript">
$(function () {
var filterList = {
init: function () {
// MixItUp plugin
// http://mixitup.io
$('#portfoliolist').mixitup({
targetSelector: '.portfolio',
filterSelector: '.filter',
effects: ['fade'],
easing: 'snap',
// call the hover effect
onMixEnd: filterList.hoverEffect()
});
},
hoverEffect: function () {
// Simple parallax effect
$('#portfoliolist .portfolio').hover(
function () {
$(this).find('.label').stop().animate({bottom: 0}, 200, 'easeOutQuad');
$(this).find('img').stop().animate({top: -30}, 500, 'easeOutQuad');
},
function () {
$(this).find('.label').stop().animate({bottom: -40}, 200, 'easeInQuad');
$(this).find('img').stop().animate({top: 0}, 300, 'easeOutQuad');
}
);
}
};
// Run the show!
filterList.init();
});
</script>
<!--Blog-Starts-Here-->
<div class="blog">
<div class="container">
<div class="blog-main">
<div class="col-md-4 blog-left">
<div class="blog-one wow bounceInLeft" data-wow-delay="0.4s">
<img src="images/blog-1.png" alt="" />
<h3>RESUME</h3>
<p>Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000</p>
</div>
</div>
<div class="col-md-4 blog-left">
<div class="blog-one wow bounce" data-wow-delay="0.1s">
<img src="images/blog-4.png" alt="" />
<h3>BLOG</h3>
<p>Random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 </p>
</div>
</div>
<div class="col-md-4 blog-left active">
<div class="blog-one wow bounceInRight" data-wow-delay="0.4s">
<img src="images/blog-3.png" alt="" />
<h3>OTHERS</h3>
<p>Lorem Ipsum is not simply random text. Latin literature from 45 BC, making it over 2000 years old</p>
</div>
</div>
<div class="clearfix"></div>
</div>
</div>
</div>
<!--Blog-Ends-Here-->
<!--Contact-Starts-Here-->
<div class="contact" id="contact">
<div class="container">
<div class="contact-main">
<div class="col-md-6 contact-left wow bounceInLeft" data-wow-delay="0.4s">
<h3>Contact Me</h3>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. </p>
<p>It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
<ul>
<li><p>T: 212-555-1211</p></li>
<li><p><a href="mailto:example@email.com"> E: info@techandall.com </a></p></li>
<li><p>F:<a href="#"> facebook.com/techandall</a></p></li>
</ul>
</div>
<div class="col-md-6 contact-left wow bounceInRight" data-wow-delay="0.4s">
<input type="text" value="Name" onfocus="this.value = '';" onblur="if (this.value == '') {this.value = 'Name';}"/>
<input type="text" value="Email address" onfocus="this.value = '';" onblur="if (this.value == '') {this.value = 'Email address';}"/>
<div class="contact-textarea">
<textarea value="Your question" onfocus="this.value = '';" onblur="if (this.value == '') {this.value = 'Your question';}">Your question</textarea>
</div>
<div class="contact-but">
<input type="submit" value="SEND" />
</div>
</div>
<div class="clearfix"></div>
</div>
</div>
</div>
<!--Contact-Ends-Here-->
<!--Footer-Starts-Here-->
<div class="footer">
<div class="conatiner">
<div class="footer-text wow bounce" data-wow-delay="0.1s">
<p>TEMPLATE BY <a href="http://w3layouts.com/"> W3LAYOUTS</a></p>
<ul>
<li><a href="#"><span class="twt"> </span></a></li>
<li><a href="#"><span class="t"> </span></a></li>
<li><a href="#"><span class="g"> </span></a></li>
</ul>
</div>
</div>
<script type="text/javascript">
$(document).ready(function() {
/*
var defaults = {
containerID: 'toTop', // fading element id
containerHoverID: 'toTopHover', // fading element hover id
scrollSpeed: 1200,
easingType: 'linear'
};
*/
$().UItoTop({ easingType: 'easeOutQuart' });
});
</script>
<a href="#home" id="toTop" class="scroll" style="display: block;"> <span id="toTopHover" style="opacity: 1;"> </span></a>
</div>
<!--Footer-Ends-Here-->
</body>
</html>
参考网站:
网友评论