Java 监听器

Java 监听器简介

监听器是Servlet规范定义的一种特殊类,用于监听ServletContext,HttpSession,ServletRequest等域对象的创建、销毁及其属性修改发生变化的事件。监听器可以在事件发生前后进行一些必要的处理操作。


常见的应用场景

  • 统计在线人数和在线用户
  • 应用启动时完成信息初始化工作
  • 网站访问量的统计
  • 与Spring结合
  • Web系统防止用户重复登陆

监听器的实现步骤

1.编写java类实现监听器接口,并实现其接口方法
2.在web.xml文件中对实现的监听器类进行注册


Java监听器按监听事件分类

  • 域对象自身的创建和销毁事件监听器
  • 域对象中属性的创建、替换和消除事件监听器
  • 绑定到session中某个对象的状态事件监听器(不需要在web.xml中注册)
<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.listener.MyServletContextListener</listener-class>
  </listener>
public class MyServletContextListener implements ServletContextListener {

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        String appName = (String)sce.getServletContext().getAttribute("app_name");
        String version = (String)sce.getServletContext().getAttribute("version");
        
        System.out.println("MyServletContextListener destroyed,appName:" + appName + ",version:" + version);
    }

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        String appName = sce.getServletContext().getInitParameter("app_name");
        String version = sce.getServletContext().getInitParameter("version");

        sce.getServletContext().setAttribute("app_name", appName);
        sce.getServletContext().setAttribute("version", version);

        System.out.println("MyServletContextListener init,appName:" + appName + ",version:" + version);

    }
}
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);
    }
}
<listener>
    <listener-class>com.listener.MyHttpSessionListener</listener-class>
  </listener>
<session-config>
    <session-timeout>1</session-timeout>
  </session-config>

访问index.jsp,创建一个会话,后台输出sessionId,再用另一个浏览器访问,就会再创建一个sessionId,一分钟后销毁。

public class MyServletRequestListener implements ServletRequestListener {

    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        System.out.println("request listener,request destroyed... ...");
    }

    @Override
    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 is :" + par);
    }
}
<listener>
    <listener-class>com.listener.MyServletRequestListener</listener-class>
  </listener> 
<body>
    <h1>首页</h1>
    <label>
        <span>ServletRequestListener测试</span>
        <a href="index.jsp?par=request_par" target="_blank">初始化</a> 
    </label>
</body>
public class MyServletContextAttributeListener implements ServletContextAttributeListener {

    @Override
    public void attributeAdded(ServletContextAttributeEvent scae) {
        System.out.println("ServletContext#attAdded#name:" + scae.getName() + "#value:" + scae.getValue());
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent scae) {
        System.out.println("ServletContext#attRemoved#name:" + scae.getName() + "#value:"   + scae.getValue());

    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent scae) {
        System.out.println("ServletContext#attReplaced#name:" + scae.getName() + "#value:"  + scae.getValue());

    }
}
<listener>
    <listener-class>com.listener.MyServletContextAttributeListener</listener-class>
  </listener>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%
    application.setAttribute("servletcontextPar", "servletcontext_par");
  //application.removeAttribute("servletcontextPar");
  //application.setAttribute("servletcontextPar", "servletcontext_par1");
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
  <h1>attribute_add_listener_test</h1>
  <h1>attribute_removed_listener_test</h1>
  <h1>attribute_replaced_listener_test</h1>
</body>
</html>
public class User implements HttpSessionBindingListener {
    
    private String username;
    private String password;

    @Override
    public void valueBound(HttpSessionBindingEvent hsbe) {
        String name = hsbe.getName();
        System.out.println("value bound,name:"+name);
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent hsbe) {
        String name = hsbe.getName();
        System.out.println("value unbound,name:"+name);
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%
   session.setAttribute("user", new com.model.User());
// session.removeAttribute("user");
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
  <h1>binding_listener_test</h1>
  <h1>unbinding_listener_test</h1>
</body>
</html>

Java监听器项目案例

  • 通过过滤器实现登录控制,未登录用户不能访问系统首页
  • 用户登录,将登录名存储到session里
  • 登录监听器监听session属性中登录值属性变化
  • 若登录用户用户名已登录系统,清除前次登录信息
  • 记录该次登录信息至缓存中,用于下次登录判断

登陆权限过滤验证

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 {
    }
}

用户信息存储实现

/**  这里用到了单例模式 **/
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);
    }
}

监听功能实现

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>&nbsp;</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>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,335评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,895评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,766评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,918评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,042评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,169评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,219评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,976评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,393评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,711评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,876评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,562评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,193评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,903评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,699评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,764评论 2 351

推荐阅读更多精彩内容