Hãy đăng ký thành viên để có thể dễ dàng trao đổi, giao lưu và chia sẻ về kiến thức đồ họa.
  1. Hãy đăng ký subscribe kênh Youtube mới của Việt Designer tại địa chỉ: Youtube.com/VietDesignerChannel để theo dõi các video về thiết kế đồ họa. Do trước đó kênh cũ bị Youtube quét không rõ lý do, trong thời gian chờ kháng cáo nếu các bạn thấy video trên diễn đàn bị die không xem được thì có thể vào kênh mới để tìm xem video sơ cua nhé.
    Loại bỏ thông báo

[HTML+JS] Một Trang Onepage đơn giản

Chủ đề thuộc danh mục 'HTML - CSS - JS - PHP - ASP' được đăng bởi banbaonylong, 5/6/14.

Lượt xem: 12,014

  1. banbaonylong Ko phải assmin

    Yêu cầu đặt ra:
    1. Loading Screen mặc định thẩm du tinh thần (nghĩa là loading screen vu vơ, bạn chỉnh đc thời gian nó tồn tại)
    2. OnePage, khả năng mở rộng số lượng page con vô hạn.
    3. Responsive
    4. 3 phương án chuyển page bằng: bấm navigation, xài cuộn chuột và bấm phím lên xuống.
    5. Chặn mấy thằng wởn cuộn chuột hay bấm phím liên tục, thời gian này tuỳ biến đc nhé. (Buộc phải chặn nếu bạn muốn web chuyển sang trang mượt mà, chính xác, trên pad của laptop dễ bị cuộn 1 lần sang vài trang)
    Khuyến cáo:
    1. Dĩ nhiên là mình chỉ care trên PC thôi, hiệu ứng trên smartphone các bạn cần phải viết lại do có nhiều hàm sẽ chạy ko chính xác. :D
    2. Demo nhỏ này chủ yếu giới thiệu cách sử dụng 1 số hàm js cơ bản ;).
    3. Code viết chưa đc tối ưu cho dễ nhìn, dễ đọc, chứ tóm gọn lại thì khó nhìn lắm :D
    4. Bạn cần hiểu đc code js và có tư duy lập trình. Mình xin lỗi không thể giúp cho các bạn không biết chút j vào đọc thớt này và hiểu rõ đc :-??
    [​IMG]
    Bước 1: Gắn cái cần thiết vào:
    PHP:
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    Bước 2: Tự vẽ nên 1 khung các thành phần con và sắp xếp chúng
    [​IMG]

    Bước 3: Hiện thực hoá bằng HTML
    PHP:
    <div id="page-wrap">
            <
    section id="first">
                <
    div class="meter">
                    <
    span id="bar" style="width: 100%"></span>
                    <
    span id="num">100</span>
                </
    div>
            </
    section>
            <
    section id="second" style="" class="active"><h1>Slide nội dung 1</h1></section>
            <
    section id="third" style="" class=""><h1>Slide nội dung 2</h1></section>
            <
    section id="forth" style="" class=""><h1>Slide nội dung 3</h1></section>
            <
    section id="fifth" style="" class=""><h1>Slide nội dung 4</h1></section>
            <
    section id="sixth" style="" class=""><h1>Slide nội dung 5</h1></section>
        </
    div>
        <
    ul class="nav">
            <
    li><a href="javascript:;" title="#second" class="second active">Slide nội dung 1</a></li>
            <
    li><a href="javascript:;" title="#third"  class="third">Slide nội dung 2</a></li>
            <
    li><a href="javascript:;" title="#forth"  class="forth">Slide nội dung 3</a></li>
            <
    li><a href="javascript:;" title="#fifth"  class="fifth">Slide nội dung 4</a></li>
            <
    li><a href="javascript:;" title="#sixth"  class="sixth">Slide nội dung 5</a></li>
        </
    ul>
    bên trong section "first" mình nhét 1 số đồ chơi nhỏ để làm cái loading thui :D. Thanh navigator mình chuyển thành ul cho dễ quản lí. Như code bạn thấy có 5 section nội dung từ "second" đến "sixth", vì vậy ta có 5 thẻ <li>.

    Bước 4: Making-up CSS cho nó long lanh :D

    bạn có thể tuỳ biến CSS :D, nhưng nhớ các điểm sau:
    1. <section> (các trang con) luôn luôn display block, float left, width 100%.
    2. Thanh nav chạy theo từng trang con, nên position fixed.
    3. <body> là cái nền, nên position relative, overflow:hidden.
    4. <div id="page-wrap"> là nền bao bên ngoài các trang con nên overflow:hidden, width 100%, margin auto, display block.
    Bước 5: Responsive nhẹ.
    Để mỗi <section> nó bung ra toàn màn hình và responsive theo kích thước trình duyệt, bạn cần dùng JS.
    PHP:
    function  _height() {
                var 
    = $(window).height()+1;
                $(
    "section").height(a);
                $(
    window).resize(function () {
                    var 
    = $(window).height()+1;
                    $(
    "section").height(b);
                });
            }
    Hàm dùng để responsive <section>, kỹ thuât:
    1. Bạn get chiều cao màn hình trình duyệt bằng $(window).height()
    2. Bạn set chiều cao đó vào <section>
    3. Khi màn hình trình duyệt resize thì bạn làm lại bước 1 thông wa $(window).resize(function () { });
    Tiếp theo, do thanh nav cũng ở sát lề phải nhưng nằm giữa màn hình, nên bạn cũng cần responsive :P
    PHP:
    function _heightNav() {
                var 
    $nav = $(".nav");
                var 
    = $(window).height()+1;
                var 
    $nav.height();
                
    $nav.css("top", (a-b)/2);
                $(
    window).resize(function () {
                    var 
    = $(window).height()+1;
                    var 
    $nav.height();
                    
    $nav.css("top", (a-b)/2);
                });
            }
    Kỹ thuật:
    1. Bạn get chiều cao màn hình trình duyệt bằng $(window).height()
    2. Bạn get chiều cao của cả cái menu navigator $nav.height()
    3. Bạn tính toán thông số để set css top cho cái menu :D
    4. Khi màn hình trình duyệt resize thì bạn làm lại bước 1 thông wa $(window).resize(function () { });
    Bước 6: làm phần loading Screen mở đầu
    Ở đây mình chỉ làm 1 dạng đơn giản là thanh loading bar, thêm số % chạy từ 0->100.

    Xem lại HTML
    PHP:
    <section id="first">
                <
    div class="meter">
                    <
    span id="bar" style="width: 100%"></span>
                    <
    span id="num">100</span>
                </
    div>
            </
    section>
    JS tương ứng
    PHP:
    //hàm gọi trang loading, biến a là trang loading, b là tốc độ load, càng cao càng lâu
            
    function loadingScreen(ab) {
                var 
    $meter = $(a).find(".meter");
                var 
    $bar $meter.find("span#bar");
                var 
    $num $meter.find("span#num");
                var 
    $queue = $({});

                
    //hàm xử lí thanh progress bar
                
    function loadDaBars(a) {
                    
    $bar.each(function() {
                        var 
    $el = $(this);
                        var 
    origWidth $el.width();
                        
    $el.width(0);
                        
    $queue.queue(function(next) {
                            
    $el.animate({widthorigWidth}, anext);
                        });
                    });
                }
                
    //hàm xử lí số %
                
    function loadNum(a) {
                    function 
    count($this){
                        var 
    current parseInt($this.html(), 10);
                        
    $this.html(++current);
                        if(
    current !== $this.data("cNum")){
                            
    setTimeout(function(){count($this)}, a);
                        }
                    }
                    
    $num.each(function() {
                        $(
    this).data("cNum"parseInt($(this).html(), 10));
                        $(
    this).html('0');
                        
    count($(this));
                    });
                }
                
    //hàm tổng hợp thực thi trang load và làm biến mất trang loading
                
    function _loadingScreen(ab) {
                    var 
    liz 3
                    loadDaBars
    (liz);
                    
    loadNum(liz/120);
                    $(
    a).delay(b).fadeOut("slow");
                    $(
    ".nav").delay(b+25).fadeIn("slow");
                }

                
    _loadingScreen(ab);
            }
    Kỹ thuật:
    1. Xử lí thanh loading: Ban đầu, bạn set thanh bar <span id="bar"> có width = 0 (bằng js), sau đó kết hợp .each(function() { });$queue.queue(function(next) { }); để dùng animation kéo dài width của <span id="bar"> ra 100%.
    2. Xử lí số loading 100%: bạn dùng hàm count() và setTimeout thôi :D, cái khó khăn ở đây là bạn phải canh thời gian để thanh bar vừa đầy thì số chạy tới 100 luôn :D
    3. Sau khi load 100%, màn hình loading screen sẽ tự động biến mất: $(a).delay(b).fadeOut("slow");
    4. Sau đó, thanh menu mới xuất hiện! $(".nav").delay(b+25).fadeIn("slow");

    Bước 7: bấm navigation thì đổi trang con
    Xem lại html của menu
    PHP:
    <ul class="nav">
            <
    li><a href="javascript:;" title="#second" class="second active">Slide nội dung 1</a></li>
            <
    li><a href="javascript:;" title="#third"  class="third">Slide nội dung 2</a></li>
            <
    li><a href="javascript:;" title="#forth"  class="forth">Slide nội dung 3</a></li>
            <
    li><a href="javascript:;" title="#fifth"  class="fifth">Slide nội dung 4</a></li>
            <
    li><a href="javascript:;" title="#sixth"  class="sixth">Slide nội dung 5</a></li>
        </
    ul>
    mình đã set trước title của từng cái li trùng với id của trang con <section> tương ứng :D
    PHP:
    $(".nav li a").click(function() {
                var 
    $a = $(this);
                $(
    ".nav li a").removeClass("active");
                
    $a.addClass("active");
                $(
    'html,body').animate({scrollTop: $($a.attr("title")).offset().top}, 'slow');
            });
    Bởi vậy, kỹ thuật khá đơn giản:
    1. Khi bấm, bạn get cái thẻ <a> được click, var $a = $(this);
    2. Bạn xoá lớp css "active" của toàn bộ thẻ a, rồi gán css "active" cho thẻ <a> vừa click.
    3. bạn xài hàm .offset().top để lấy vị trí top của trang con, rồi dùng hàm animate scrollTop để nó chạy :D (như dòng kế cuối của code)

    Bước 8: Scrolling
    Do mình đã xài overflow hidden nên bạn không thể scroll đc!!! Bởi vậy, buộc lòng ta fải xài thư viện để bắt sự kiện scroll (nhét vô trong <head>). Bạn có thể down plugin đó từ đây: link
    PHP:
    <script src="js/jquery.mousewheel.min.js"></script>
    JS sẽ có dạng sau:
    PHP:
    var = $("section").length;
    $(
    document).mousewheel( function(edelta){   
                function 
    _a(){
                        
    //scroll lên
                        
    if(delta>0) {
                            if(
    $b.index()==1) {} else {
                                $(
    'html,body').animate({scrollTop$b.prev().offset().top}, 'slow');        
                                
    ad($b.prev().attr("id"));
                                
    $b $b.prev();
                            }
                        }
                        
    //scroll xuống
                        
    if(delta<0){
                            if(
    $b.index()==(a-1)) {} else {
                                $(
    'html,body').animate({scrollTop$b.next().offset().top}, 'slow');
                                
    ad($b.next().attr("id"));
                                
    $b $b.next();
                            }
                        }       
                    }
                    
    _a();
                }
                
    //Hàm thực thi scroll chuột, nếu loading screen đang chạy thì chặn ko cho scroll
                
    if($("#first").css("display")=="none") {
                    
    _a();
                }
            });        
    Kỹ thuật:
    1. Bạn quan tâm đến delta, khi delta>0 thì nghĩa là đang scroll lên, delta<0 thì ngược lại nghĩa là scroll xuống :D
    2. Phải xác định đc cái trang con đang hiển thị (ban đầu mình đã set trang #second 1 lớp active làm cờ chứng tỏ nó đang hiển thị)
    3. Khi scroll lên, bạn lại dùng .offset().top để lấy vị trí top của trang con, rồi dùng hàm animate scrollTop y chang như Bước 7 vậy, nhưng bạn lấy anh em đứng trước của nó bằng $b.prev() :D. Nhưng bạn cần nhớ: nếu bạn đang ở #second thì bạn không thể scroll lên đc (!) do ở trên không còn trang con nào cả :P, bởi vậy bạn phải check .index () của trang con đó, nếu index >1 thì mới thực thi.
    4. Khi scroll xuống, bạn làm gần giống 3. ở trên, chỉ thay $b.next(). Nhưng bạn cần nhớ: nếu bạn đang ở trang con cuối cùng thì bạn không thể scroll xuống đc, bởi vậy bạn phải check .index () của trang con đó, nếu index < giá trị tổng số trang con thì mới thực thi (giá trị này tính bằng var a = $("section").length;).
    5. Sau đó bạn set lại cái menu :P
      PHP:
      function ad(a) {
              $(
      ".nav li a").removeClass("active");
                  $(
      ".nav li a."+a).addClass("active");
          }    
    6. Bạn fải xác định loading screen biến mất thì hàm mới chạy đã nhé :D
    Bước 9: Tối ưu hoá bước 8
    Code ở bước 8 rất kinh hoàng nếu gặp bọn phá phách: cuộn chuột liên tục khiến trang bay nhảy hoài thì sao? Để giải quyết vấn đề này bạn cần thêm thắt khá nhìu (Mình lược bỏ bớt phần bên trong thực thi scroll cho dễ nhìn)
    PHP:
    $(document).ready(function() {
      var 
    timeStamp = new Date().getTime();

      
    //scrolling
      
    $(document).mousewheel( function(edelta){
       function 
    _a(){
        var 
    timeNow = new Date().getTime();

        
    //chặn scroll liên tục
        
    if (timeNow timeStamp 500) {
         
    timeStamp timeNow;
         return;
        } else {
         
    timeStamp timeNow;
         
    //scroll lên
         
    if(delta>0) {

         }
         
    //scroll xuống
         
    if(delta<0){

         }
        }
        
    _a();
       }
       
    //Hàm thực thi scroll chuột, nếu loading screen đang chạy thì chặn ko cho scroll
       
    if($("#first").css("display")=="none") {
        
    _a();
       }
      });  
    ;) Ngay timeNow - timeStamp < 500, bạn có thể chỉnh sửa con số theo ý muốn. Ở đây mình set 500 nghĩa là sau 500ms thì mới đc scroll 1 lần :P

    Bước 10: Chuyển trang con khi bấm phím up và down
    PHP:
    //bàn phím up và down
            
    $(document).keydown(function(e){       
                function 
    _b() {
                    
    e.preventDefault();
                    var 
    timeNow = new Date().getTime();
                    
    //chặn bấm phím liên tục
                    
    if (timeNow timeStamp 500) {
                        
    timeStamp timeNow;
                        return;
                    } else {
                        
    timeStamp timeNow;
                        
    //lên
                        
    if (e.keyCode == 38) {                   
                            if(
    $b.index()==1) {} else {
                                $(
    'html,body').animate({scrollTop$b.prev().offset().top}, 'slow');            
                                
    ad($b.prev().attr("id"));
                                
    $b $b.prev();
                            }
                        }
                        
    //xuống
                        
    if (e.keyCode == 40) {                    
                            if(
    $b.index()==(a-1)) {} else {
                                $(
    'html,body').animate({scrollTop$b.next().offset().top}, 'slow');
                                
    ad($b.next().attr("id"));
                                
    $b $b.next();
                            }
                        }
                    }
                }
                
    //Hàm thực thi bấm phím, nếu loading screen đang chạy thì chặn ko cho bấm
                
    if($("#first").css("display")=="none") {
                    
    _b();
                }else { 
    e.preventDefault(); }
            });
            $(
    'html, body').on('touchstart touchmove', function(e){
            
                 
    e.preventDefault();
            });
        });    
    Kỹ thuật:
    1. Mình kết hợp luôn cái chặn 500ms như bước 9 nhé ;)
    2. Bạn xài $(document).keydown(function(e){ }); để bắt sự kiện bấm phím nhé e.keyCode == 38 là bấm phím up đi lên và e.keyCode == 40 là bấm phím down đi xuống :D
    3. Bạn xài hàm xử lí gần tương đương với scroll lên và scroll xuống nhé ;)
    Kết quả:
    Bạn sẽ có đc 1 trang OnePage đơn giản như link
    (Cảm ơn Đoilơ ViệtDesigner đã tài trợ hosting :">)

    ...
    Chỉnh sửa lần cuối: 5/6/14
  2. Mèo Máy

    Mèo Máy Mới đăng kí

    Những người ko biết gì hoặc lười nghiên cứu thì thử nghịch library này xem sao :D
    //alvarotrigo.com/fullPage
  3. princenuce

    princenuce Mới đăng kí

    Phức tạp quá nhỉ, thực tế lúc mình làm giao diện responsive mình rất ngại dùng js để tự làm mà mình sẽ vác ngay e bootstrap và làm luôn :D
  4. hanuanvds

    hanuanvds Thành viên cấp 1

    có vẻ khó với những bác không biết :)):))

Ủng hộ diễn đàn