整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          深度解析各種網站頁面跳轉方式原理及優劣勢對比分析「進階篇」

          黑帽SEO技術不論多么神奇,不管用戶看到的頁面多么的敏感,但是搜索引擎爬蟲看到的永遠都是正規的信息,而用戶看到的是非常規信息。很明顯,這是因為網站頁面做了處理,能夠分辨出普通用戶和搜索引擎,不同的對象調用不同的頁面,這個就是網站頁面跳轉。

          什么是網站頁面跳轉以及為什么要進行頁面跳轉就不多去細說了,那么怎么進行頁面跳轉呢。關于網頁跳轉技術很多,文章也很多,方法代碼都很多,但是這些方法差別在那里,那些方法速度更快,那些方法更靈活,那些方法用戶能感覺到,為什么能感覺到。夜島SEO看了一些文章,結合多年的黑帽SEO優化工作經驗,通過繪制序列圖等辦法簡單總結一下,換個角度理解一下,希望對大家有所幫助!

          本文夜島重點在于比較http跳轉,html跳轉,js跳轉的工作流程,以及重點分析他們在時間開銷上的情況,同時我們重點在于繪制一些圖形,然后希望讀者能夠從圖中體會到區別,需要讀者體會的地方都用特別區域標識出來了。請大家注意。

          一.什么是頁面跳轉


          網站都是由各種各樣頁面組成,正常情況下A頁面里面包含B頁面,C頁面的鏈接,用戶在瀏覽A頁面過程中,手工人為點擊B鏈接,然后用戶瀏覽器就顯示到B頁面。這個過程我們就可以叫頁面跳轉。

          黑帽SEO中常用的站群排名技術99.9%是必須要做跳轉的,不然排名上去了給客戶看什么內容呢。我們考慮如下場景,一個網站由A,B,C頁面構成。正常他們有他們自己顯示內容。隨著時間推移,發現A頁面內容應該同C頁面內容相同,但是由于A頁面已經被大量用戶收藏在瀏覽器的收藏夾中,或者被搜索引擎收錄,若是現在取消A頁面的地址(就是取消頁面),則對用戶是個非常糟糕的事情,但是同時維護兩個頁面A及C又是個麻煩的事情,稍有疏忽就會造成內容不一致,給用戶造成困惑,同時搜索引擎也會不認可。

          如何保證A地址不取消,同時又準確保證兩個頁面顯示內容相一致?

          我們今天要解決的是在沒有用戶干預下的頁面跳轉,完成當用戶需要顯示頁面A時,我們給他顯示頁面C的內容。

          另外為了說明問題方便,我們同時也假設頁面B內容也指向內容C,只是采用跳轉技術不一樣,這樣我們方便區別兩種行為的差別。



          如上圖中,展示了用戶訪問服務器獲取頁面的一個基本過程。圖中主要分為兩個部分,左側區域是用戶端,右側區域是服務端,用戶端的用戶通過手機或者電腦或者智能設備訪問服務端頁面。

          服務端由若干頁面構成,這里簡化了服務端行為,并且抽象成三個頁面A,B,C,正常情況下服務端應該有很多Action對象,Action對象同頁面相對應,提供各種服務,我們僅僅簡化Page:A,Page:B,Page:C;

          用戶端就是手機,包括手機操作操作系統,網絡層(tcp/ip/udp等),http等協議層,以及瀏覽器,瀏覽器內部進行html的解析,css渲染,js執行引擎等等。

          典型用戶頁面瀏覽行為如下:


          1.用戶啟動瀏覽器

          2.在瀏覽器地址中輸入域名url地址

          3.瀏覽器發起http請求

          4.網絡層發起tcp請求到服務器,傳輸http數據包

          5.服務器接收到請求后進行處理,然后返回相關頁面內容

          6.Tcp接收返回數據給http協議解析系統

          7.http將返回數據返回瀏覽器

          8.瀏覽器解析html數據,處理htmlhead

          9.根據head處理后續工作

          10.解析body數據

          11.處理裝載事件Onload(已經開始js的執行,在裝入數據過程中已經可以執行一些js事件,具體要根據頁面以及瀏覽器特性而定)

          12.根據css進行顯示,執行js

          13.用戶進行后續事情

          以上僅僅是典型瀏覽器行為,具體瀏覽器行為同頁面內容、瀏覽器特性等都有關系,要具體分析。

          二.頁面跳轉的分類


          根據上面的圖1,我們可以有如下分類方法:

          一)以跳轉地點發生系統那一側分為:

          服務端跳轉


          頁面跳轉發生在服務端,服務端負責將實際內容獲取,然后發送給客戶端,這個情況下,一般用戶不會感覺到跳轉的實際行為,因此有些時候我們也不叫做跳轉。具體的服務端跳轉行為有很多,各個技術都有各自的特點。例如:Struts2基于注解服務端跳轉、<request.getRequestDispatcher(“xx.jsp”).forward(request,response)、<jsp:forwardpage=””/>等,php也有自己的放回,總之各自有各自的辦法,夜島就不一一舉例了,大家自己去搜索吧。

          客戶端跳轉


          跳轉行為需要客戶單程序參與的一種行為(自然不是用戶參與的,那個不是本文討論的)。在這個過程中,一般用戶一定會知道的,瀏覽器地址欄會發生變化,這個分類比較多,我們專門進行一個分類。

          二)用戶端跳轉中,我們根據跳轉行為發生在那個軟件層次,分為:http層跳轉、應用層跳轉;應用層跳轉繼續分為:htmlhead跳轉、js跳轉等。

          http層跳轉


          http跳轉是指server根據工作情況通過http返回狀態碼,指示客戶端瀏覽器跳轉到相應頁面的過程,一般返回碼是302.,下面是http302狀態碼的定義:

          Htmlhead頭指令跳轉

          在html代碼的head中添加特殊標簽,如下

          <metahttp-equiv=”refresh”content=”5;url=http://www.heimaoke.com/”/>

          表示:5秒之后轉到黑帽客網站首頁。

          這個跳轉需要瀏覽器具體解析html后才能進行,慎重更多時間才能進行,或者情況更復雜。

          Js跳轉


          通過在html代碼中添加js代碼,通過js代碼實現跳轉

          <scriptlanguage=”javascript”type=”text/javascript”>

          window.location.href=”login.jsp?backurl=”+window.location.href;

          </script>
          這個跳轉應該比htmlhead跳轉更向后延遲。

          服務端跳轉流程


          頁面跳轉顯示的內容發生在服務端,服務端負責將實際內容獲取到,然后發送給客戶端。一般用戶不會感覺到跳轉的實際行為,因此有些時候我們也不叫做跳轉

          具體工作的參考過程如下:



          如上圖,用戶請求訪問PageA,頁面A內容指向頁面C,相關過程如下:

          1.用戶通過瀏覽器訪問PageA

          2.瀏覽器通過http處理模塊請求GetPageA
          3.http處理模塊同服務器建立tcp連接,并發出請求獲取PageA指令

          4.PageA內容指向PageC,通過內部程序將內容C獲取到本地

          5.PageA接收到PageC的數據后,將數據返回給http模塊

          6.http模塊接收到數據后返回給瀏覽器

          7.瀏覽器接收到http返回的html數據后,解析html的head

          8.處理html的body

          9.處理html的onload方法

          10.瀏覽器最后將數據等顯示給用戶

          注意:圖中不同斜線的區域

          通過server跳轉后,用戶看到的是PageC的內容,但是瀏覽器地址欄中地址是PageA的地址。

          優點:跳轉行為在server進行,一次tcp連接完成相關操作,對用戶是透明的,不會造成疑惑。

          缺點:對用戶隱藏了信息,跳轉行為都發生在server端,對server有壓力。

          server端功能各異,需要分工負責,當用戶訪問某功能后,需要返回另外一個功能,這個時候沒必要把全部功能都放到一個服務器上。

          例如:單點登錄:用戶在某個服務器上登錄成功后,一定要在重新跳轉到功能服務器上。

          網絡支付:用戶在銀行的網站支付完成后,必須重新定向到另外企業應用服務器上。

          適用范圍:應用內部系統,適當的包含關系時。

          http跳轉流程


          http跳轉是指server根據工作情況通過http返回狀態碼,指示客戶端瀏覽器跳轉到相應頁面的過程,一般返回碼是302,下面是http302跳轉的相關參考流程

          注意圖中,區域,顏色,斜線等等。



          如上圖,用戶請求訪問PageB,頁面B內容指向頁面C,相關過程如下:

          1.用戶通過瀏覽器訪問PageB

          2.瀏覽器通過http處理模塊請求GetPageB

          3.http處理模塊同服務器建立tcp連接,并發出請求獲取PageB

          4.PageB內容指向PageC,PageB的處理模塊通過http的重定向協議通知客戶端程序,通過發送消息,302,以及跳到目的地址等進行

          5.http處理模塊接收到消息后直接跳轉到目標地址,同時通知瀏覽器(修改地址欄)

          6.http處理模塊請求PageC頁面內容

          7.PageC處理模塊處理數據,生成html代碼,返回數據給http處理模塊

          8.http處理模塊接收到數據后放回數據給瀏覽器

          9.瀏覽器接收到http返回的html數據后,解析html的head

          10.處理html的body

          11.處理html的onload方法

          12.瀏覽器最后將數據等顯示給用戶

          優點:響應速度快,在http1.1協議下通過合適的設置可以使用同一個tcp連接,節省網絡時間,服務器及用戶端都不需要進行額外的數據處理工作,節省時間。

          缺點:僅僅能做跳轉沒有其他功能,基于js及html的跳轉可以選擇延時跳轉,但是302無法選擇延時跳轉等

          適用范圍:快速跳轉,不需要延時,經常用在兩個系統之間跳轉等。

          Htmlrefresh跳轉流程


          通過在htmlhead中添加<meta>標簽,在標簽里指定相關參數,指示瀏覽器跳轉到相應頁面,相關跳轉必須在http層面將html數據傳輸給瀏覽器后,瀏覽器解釋html代碼過程中,發現跳轉并且根據跳轉指令跳轉到相應頁面。

          參考流程如下圖:



          如上圖,用戶請求訪問PageB,頁面B內容指向頁面C,相關過程如下:

          1.用戶通過瀏覽器訪問PageB

          2.瀏覽器通過http處理模塊請求GetPageB

          3.http處理模塊同服務器建立tcp連接并發出請求獲取PageB

          4.PageB處理模塊處理數據,生成html代碼,最后將html通過http協議傳輸回去。

          5.http后將數據放回給瀏覽器,瀏覽器開始處理html

          6.瀏覽器首先會處理html的head部分,最后發現有跳轉的相關指令

          7.瀏覽器根據跳轉指令,重新聯系http模塊,發出獲取PageC的指令

          8.http通過tcp連接到服務器,獲取PageC內容,然后返回給瀏覽器

          9.瀏覽器接收到http返回的html數據后重新處理html,首先解析html的head

          10.處理html的body

          11.處理html的onload方法

          12.瀏覽器最后將數據等顯示給用戶

          優點:跳轉方式靈活,可以指定延時跳轉等等

          缺點:可能多次建立tcp連接,在低速網絡下效率更低,浪費客戶端的時間

          Htmljs實現跳轉工作流程


          最后來看一下js跳轉,工作中每個瀏覽器都有自己的js執行引擎,執行引擎根據js代碼,來動態調用瀏覽器進行跳轉,相關參考代碼如下:

          <scriptlanguage=”javascript”type=”text/javascript”>

          window.location.href=”login.jsp?backurl=”+window.location.href;

          </script>

          具體js跳轉過程如下圖:



          如上圖,用戶請求訪問PageB,頁面B內容指向頁面C,相關過程如下:

          1.用戶通過瀏覽器訪問PageB

          2.瀏覽器通過http處理模塊請求GetPageB

          3.http處理模塊同服務器建立tcp連接同server建立連接,并發出請求獲取PageB

          4.PageB處理模塊處理數據,生成html代碼,最后將html通過http協議傳輸回去。

          5.http后將數據放回給瀏覽器,瀏覽器開始處理html

          6.瀏覽器首先會處理html的head部分,最后會發現有跳轉的相關指令

          7.瀏覽器處理html的body,以及js等,最后根據js的指令指示瀏覽器獲取頁面C

          8.最后根據js的指令指示瀏覽器獲取頁面C瀏覽器會根據跳轉指令,重新聯系http模塊,發出獲取PageC的指令

          9.http通過tcp連接到服務器,最后獲取PageC的內容,然后返回給瀏覽器

          10.瀏覽器接收到http返回的html數據后重新處理html,首先解析html的head

          11.處理html的body

          12.處理html的onload方法
          13.瀏覽器最后將數據等顯示給用戶

          優點:跳轉方式靈活,可以指定延時跳轉等等。

          缺點:可能多次建立tcp連接,在低速網絡下效率更低,浪費客戶端的時間。

          使用訪問:快速跳轉,不需要延時,經常用在兩個系統之間跳轉等。

          頁面跳轉最糟糕的情況


          當A跳轉到B時,我們用符號A–>B表示,下面的循環跳轉A–>B–>C–>A,會發生什么事情。若是循環跳轉僅僅發生在server端,則相關系統會迅速被拖垮。若是循環跳轉發生在客戶端參與的系統中,很快客戶端及server端都會發生問題。

          因此循環跳轉我們是要嚴格避免的,解決辦法:

          1.不跳轉,但是不可能完全避免,并且不太可能實現,一般系統都是開放的系統,會不斷添加功能,即使當前沒有跳轉,但是過幾個月。。。。。。

          2.打破跳轉的循環,加強系統的檢查力度避免循環跳轉的發生。

          3.最重要的,監控系統,當發現某個客戶端或者系統在單位時間內有過多的訪問時,主動斷開連接或者拒絕這個客戶端的訪問等等。這個非常重要,一個好的系統是必須有這個功能的,否則即使沒有循環跳轉,但是若是用戶連續快速訪問一個頁面也是有很大問題的,例如ie中按下F5鍵循環刷新頁面,若是沒有檢測機制。。。。

          三.總結


          每種跳轉方法對于用戶來講都帶來了內容上的變化,原以為A頁面的內容變成C頁面內容。跳轉的方法有很多,夜島SEO無法為大家一一列舉,當我們使用時如何選擇那種類別時,需要弄明白每一種跳轉的特點,包括:性能,功能等,根據不同網絡情況進行不同的選擇,例如有的網絡建立tcp連接速度慢,這個時候就適宜選擇server端的跳轉等。

          若是保證系統之間的耦合關系更小,系統之間更靈活則需要采用http方式跳轉、js跳轉,html跳轉等。

          有的時候需要在跳轉前進行一些判斷或者額外的操作等,就是js跳轉比較方便,但是也有個瀏覽器適配的問題。有時候一個js兼容性不好的js代碼可能不工作,造成部分用戶無法跳轉。
          更多黑帽SEO技術知識學習教程請訪問夜島SEO技術博客(www.yeadao.com),一個專注于黑帽SEO快速排名技術研究與學習教程分享的網站!

          pringMVC默認的參數對象

          • SpringMVC默認的參數對象是指,不用再另行創建,相當于SpringMVC內置對象,可以直接聲明并使用
          • 默認的參數對象有:HttpServletRequest,HttpServletResponse,HttpSession,Model,Map,ModelMap
          • 注意:Model,Map,ModelMap和HttpServletRequest對象一樣都使用請求作用域,所以在頁面跳轉時,只可以采用轉發方式
          • 如果要采用重定向的方式完成頁面跳轉而且還要保證數據傳遞的正確性,只能使用HttpSession

          進行攜帶數據的頁面跳轉

          • SpringMVC的項目配置和前面SpringMVC博集中(指SpringMVC 02)配置相同
          • webapp/index.jsp:網站的首頁,用來向后端發送一個簡單的攜帶數據的get請求
          <%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
              <title>index.jsp</title>
          </head>
          <body>
          <a href="${pageContext.request.contextPath}/data.action?name=餃子">攜帶數據進行頁面跳轉</a>
          </body>
          </html>
          
          • webapp/admin/main.jsp如下:作為請求的最終響應頁面,測試在經過頁面跳轉后,后端放入對應作用域中的數據是否還有效
          <%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
              <title>main.jsp</title>
          </head>
          <body>
          <h2>顯示頁面跳轉時攜帶的數據......</h2>
              <!-- 在經過頁面跳轉后,在跳轉到的頁面里,嘗試獲取之前存放的數據-->
          	request: ${requestUser}<br>
          	httpSession: ${sessionUser}<br>
          	model: ${modelUser}<br>
          	map: ${mapUser}<br>
          	modelMap: ${modelMapUser}<br>
              
              <!-- 嘗試直接獲取請求地址中攜帶的參數數據-->
          	param: ${param.name}
          </body>
          </html>
          
          • 創建SpringMVC控制器:DataAction。在控制器的action方法中利用SpringMVC內置對象,將數據存放到相應作用域中
          package com.example.controller;
          
          import com.example.pojo.User;
          import org.springframework.stereotype.Controller;
          import org.springframework.ui.Model;
          import org.springframework.ui.ModelMap;
          import org.springframework.web.bind.annotation.RequestMapping;
          
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpSession;
          import java.util.Map;
          
          @Controller
          public class DataAction {
              @RequestMapping("/data")
              //這幾個參數都是SpringMVC內置的,可以直接聲明使用
              public String data(HttpServletRequest request, HttpSession httpSession, Model model, Map<Object, Object> map, ModelMap modelMap){
                  
                  //User實體類含有兩個屬性:name(String), age(int)。無參構造方法。全屬性的有參構造方法,getter,setter,toString方法
                  User user = new User("荷包蛋", 20);
                  //將user對象利用各SpringMVC內置對象存放到相應作用域中
                  request.setAttribute("requestUser", user);
                  httpSession.setAttribute("sessionUser", user);
                  model.addAttribute("modelUser", user);
                  map.put("mapUser", user);
                  modelMap.addAttribute("modelMapUser", user);
                  //最后完成頁面轉發跳轉
                  return "main";
              }
          }
          
          • 當控制器中的action方法以轉發的方式跳轉到webapp/admin/main.jsp頁面時
          • 部署并啟動tomcat進行測試
          • 網站首頁(left),響應頁面(right):可見對于放入相應作用域中的數據,在經過頁面轉發跳轉后仍然可以獲取到之前存放的數據
          • 而且對于param也可以在響應的頁面中直接獲取到隨著前端請求攜帶而來的數據(攜帶而來的數據放在請求域中,轉發是一次請求,請求域還在,自然可以獲取到)

          • 當控制器中的action方法以重定向的方式跳轉到webapp/admin/main.jsp頁面時
          package com.example.controller;
          
          import com.example.pojo.User;
          import org.springframework.stereotype.Controller;
          import org.springframework.ui.Model;
          import org.springframework.ui.ModelMap;
          import org.springframework.web.bind.annotation.RequestMapping;
          
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpSession;
          import java.util.Map;
          
          @Controller
          public class DataAction {
              @RequestMapping("/data")
              public String data(HttpServletRequest request, HttpSession httpSession, Model model, Map<Object, Object> map, ModelMap modelMap){
                  User user = new User("荷包蛋", 20);
                  request.setAttribute("requestUser", user);
                  httpSession.setAttribute("sessionUser", user);
                  model.addAttribute("modelUser", user);
                  map.put("mapUser", user);
                  modelMap.addAttribute("modelMapUser", user);
                  
                  //最后完成頁面的重定向跳轉
                  return "redirect:/admin/main.jsp";
              }
          }
          
          • 網站首頁(left),響應頁面(right):可見對于放入相應作用域中的數據,在經過頁面重定向跳轉后只有session域中可以獲取到之前存放的數據
          • 因為本例中的重定向是兩次請求,凡是放在第一次請求域中的數據,在第二次請求發起后,之前存放的數據對于第二次請求來說已經失效,無法訪問原來存放的數據,而由于瀏覽器并未關閉,則session域仍然有效,可以正確獲取之前存放在session域中的數據

          目中經常會出現點擊跳轉錨點的方法,比如給一個a標簽一個href=“#錨點”,然后要跳的錨點給個id=“錨點”,這樣就實現簡單的跳轉,但是這樣在url地址欄后面都會出現一個諸如www.csdn.net#錨點,然后你點擊給一次后退都是退回上一個選擇的錨點url,這里總結一些跳轉錨點的方法。

          第一種方法,也是最簡單的方法是錨點用<a>標簽,在href屬性中寫入DIV的id。如下:

          <!DOCTYPE html>

          <html>

          <head>

          <style>

          div {

          height: 800px;

          width: 400px;

          border: 2px solid black;

          }

          h2 {

          position: fixed;

          margin:50px 500px;

          }

          </style>

          </head>

          <body>

          <h2>

          <a href="#div1">to div1</a>

          <a href="#div2">to div2</a>

          <a href="#div3">to div3</a>

          </h2>

          <div id="div1">div1</div>

          <div id="div2">div2</div>

          <div id="div3">div3</div>

          </body>

          </html>

          這種方法的缺點是點擊錨點之后,瀏覽器的URL會發生變化,如果刷新可能會出現問題。

          第二種方法是在js事件中通過window.location.hash="divId"跳轉,但地址也會發生變化,感覺跟第一種方法沒區別,甚至更麻煩。

          第三種方法是用animate屬性,當點擊錨點后,頁面滾動到相應的DIV。接著上面的代碼,具體添加如下代碼:

          <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.0.min.js"></script>

          <script type="text/javascript">

          $(document).ready(function() {

          $("#div1Link").click(function() {

          $("html, body").animate({

          scrollTop: $("#div1").offset().top }, {duration: 500,easing: "swing"});

          return false;

          });

          $("#div2Link").click(function() {

          $("html, body").animate({

          scrollTop: $("#div2").offset().top }, {duration: 500,easing: "swing"});

          return false;

          });

          $("#div3Link").click(function() {

          $("html, body").animate({

          scrollTop: $("#div3").offset().top }, {duration: 500,easing: "swing"});

          return false;

          });

          });

          </script>

          注意:運行上面的腳本的之前,先將為錨點增加相應的id,同時去掉href屬性。

          $("html, body")可以替換為響應的div,如果不起作用,試著給該div增加overflow:scroll屬性。

          另外,腳本可以進一步優化,自己來試試

          這樣做的好處是:URL地址不會變,同時點擊錨點時會自動響應scroll事件,不需要重新綁定。

          缺點是:如果頁面復雜的話,偏移值可能會發生變化需要算法輔助。

          第四種方法是用js的srollIntoView方法,直接用:

          document.getElementById("divId").scrollIntoView();

          比如:

          document.querySelector("#roll1").onclick = function(){

          document.querySelector("#roll1_top").scrollIntoView(true);

          }

          這里就是點擊id是#roll1的元素可以滾動到id是#roll1_top的地方,這里的#roll1和#roll1_top最好是一一對應的,

          這種方法的好處,是URL不會變,同時能夠響應相應的scroll事件,不需要算法什么的。代碼如下:

          <html>

          <head>

          <title>HTML5_ScrollInToView方法</title>

          <meta charset="utf-8">

          <script type="text/javascript">

          window.onload = function(){

          /*

          如果滾動頁面也是DOM沒有解決的一個問題。為了解決這個問題,瀏覽器實現了一下方法,

          以方便開發人員如何更好的控制頁面的滾動。在各種專有方法中,HTML5選擇了scrollIntoView()

          作為標準方法。

          scrollIntoView()可以在所有的HTML元素上調用,通過滾動瀏覽器窗口或某個容器元素,

          調用元素就可以出現在視窗中。如果給該方法傳入true作為參數,或者不傳入任何參數,那么

          窗口滾動之后會讓調動元素頂部和視窗頂部盡可能齊平。如果傳入false作為參數,調用元素

          會盡可能全部出現在視口中(可能的話,調用元素的底部會與視口的頂部齊平。)不過頂部

          不一定齊平,例如:

          //讓元素可見

          document.forms[0].scrollIntoView();

          當頁面發生變化時,一般會用這個方法來吸引用戶注意力。實際上,為某個元素設置焦點也

          會導致瀏覽器滾動顯示獲得焦點的元素。

          支持該方法的瀏覽器有 IE、Firefox、Safari和Opera。

          */

          document.querySelector("#roll1").onclick = function(){

          document.querySelector("#roll_top").scrollIntoView(false);

          }

          document.querySelector("#roll2").onclick = function(){

          document.querySelector("#roll_top").scrollIntoView(true);

          }

          }

          </script>

          <style type="text/css">

          #myDiv{

          height:900px;

          background-color:gray;

          }

          #roll_top{

          height:900px;

          background-color:green;

          color:#FFF;

          font-size:50px;

          position:relative;

          }

          #bottom{

          position:absolute;

          display:block;

          left;0;bottom:0;

          }

          </style>

          </head>

          <body>

          <button id="roll1">scrollIntoView(false)</button>

          <button id="roll2">scrollIntoView(true)</button>

          <div id="myDiv"></div>

          <div id="roll_top">

          scrollIntoView(ture)元素上邊框與視窗頂部齊平

          <span id="bottom">scrollIntoView(false)元素下邊框與視窗底部齊平</span>

          </div>

          </body>

          </html>

          個人建議使用第四種方法。


          主站蜘蛛池模板: 精品日韩一区二区三区视频| 国产一区二区三区精品视频| 亚洲一区二区三区四区视频| 精品国产日韩亚洲一区91| 成人一区二区免费视频| 冲田杏梨AV一区二区三区| 精品无码日韩一区二区三区不卡 | 国产精品一区视频| 伦理一区二区三区| 亚洲国产精品一区二区九九| 国产精品自拍一区| 精品香蕉一区二区三区| 五月婷婷一区二区| 亚洲视频一区在线播放| 色久综合网精品一区二区| 无码日韩精品一区二区免费暖暖| 成人精品一区二区三区中文字幕| 国产免费av一区二区三区| 性色av闺蜜一区二区三区| 冲田杏梨AV一区二区三区 | 久久久久久一区国产精品| 日本免费精品一区二区三区| 国产福利一区二区精品秒拍| 日本在线视频一区二区三区| 日本福利一区二区| 日韩精品一区二区三区不卡| 老湿机一区午夜精品免费福利| 精品无码人妻一区二区三区18| 亚洲AV无码一区二区三区牲色 | 国产在线观看一区二区三区精品 | 日韩精品一区二区三区中文精品| 久久精品免费一区二区三区| 无码日韩精品一区二区免费暖暖| 国产精品高清一区二区三区| 亚洲一区二区中文| 精品久久久久久无码中文字幕一区| 亚洲欧美日韩一区二区三区在线| 日韩一区二区a片免费观看| 成人无号精品一区二区三区| 视频在线观看一区二区| 亚洲色大成网站www永久一区|