2013-01-22 24 views
-1

我仍在學習javascript,並且正在構建一個從外部文件(例如test1.php,test2.php)爲每個頁面加載內容的ajax網站。我花了幾個小時拼湊了一些可行的代碼,但感覺真的很笨拙。有關如何簡化它的任何建議?或者我正在做的事情很愚蠢,應該以不同的方式做?是否可以簡化我的AJAX導航代碼?

JS:

$(document).ready(function() { 

var hash = window.location.hash.substr(1); 

var projectID = $('#topNav a').each(function(){ 
    var projectID = $(this).attr('id'); 
    if(hash==projectID){ 
     var toLoad = hash+'.php .content'; 
     $('.content').load(toLoad); 
     $(this).siblings().removeClass('active'); 
     $(this).addClass('active'); 
    }       
}); 

$('#topNav a').click(function(){ 

    var toLoad = $(this).attr('href')+' .content', 
     newId = $(this).attr('rel'),   
     oldHeight = $('#shell').css("height"),  
     viewportHeight = $(window).height() 

    if (!$(this).hasClass("active")) { 

     $(this).siblings().removeClass('active'); 
     $(this).addClass('active'); 

     $('<div/>', { 
      id: newId, 
      class: 'content' 
     }).css({ top: viewportHeight + "px", display: "none" }).appendTo('#shell').load(toLoad); 

     $('#' + newId).show(function() { 
      $(this).animate({ top: "0px", queue: false}, 600); 
      $('#shell > div:first').animate({ top: "-" + oldHeight, queue: false}, 600, function() { 

       $('#shell > div:first').remove() 
      }); 
     }); 

     var newHash = $(this).attr('id'); 
     window.history.pushState(null, "", "#" + newHash); 

    } 

    return false; 
}); 

window.addEventListener("popstate", function(e) { 

    var hash = window.location.hash.substr(1), 
     oldHeight = $('#shell').css("height"),  
     viewportHeight = $(window).height() 

    var projectID = $('#topNav a').each(function(){ 
     var projectID = $(this).attr('id'); 
     if(hash==projectID){ 
      var toLoad = hash+'.php .content' 

      $(this).siblings().removeClass('active'); 
      $(this).addClass('active'); 

      $('<div/>', { 
       id: hash, 
       class: 'content' 
      }).css({ top: viewportHeight + "px", display: "none" }).appendTo('#shell').load(toLoad, function() { 

       $(this).show(function() { 
        $(this).animate({ top: "0px", queue: false}, 600); 
        $('#shell > div:first').animate({ top: "-" + oldHeight, queue: false}, 600, function() { 

         $('#shell > div:first').remove() 
        }); 
       }); 

      }); 

     }       
    }); 

}); 

});

HTML:

<nav id="topNav"> 
<a href="test1.php" id="test1" rel="content1" class="active">Test 1</a> 
<a href="test2.php" id="test2" rel="content2">Test 2</a> 
<a href="test3.php" id="test3"rel="content3">Test 3</a> 
</nav> 

<div id="shell"> 

<div id="content1" class="content"> 

    <p>Here is the first page</p> 

</div> 

</div> 

CSS:

#topNav { 
position: fixed; overflow: auto; top: 0; left: 0; 
width: 100%; z-index: 100; background: #fff; height: 80px; 
} 
#topNav a { margin-right: 30px; color: #a9a9a9; } 
    #topNav a.active { color: #333; } 

#shell { margin: 0px; padding: 0px; width: 100%; height: 100%; } 

.content { 
    position: absolute; margin: 0px; padding-bottom: 0px; 
    width: 100%; height: 100%; 
} 
#content1 { background: #000; color: #fff; } 
#content2 { background: red; } 
#content3 { background: blue; } 
+2

看起來不錯,雖然你可能會逃避使用現有的插件,給你的社區已經完全測試了相同的功能,如History.js。這種問題更適合http://codereview.stackexchange.com,如果您只想獲得關於您當前代碼的意見或簡化它。 –

回答

1

要點:

  • 大量的代碼被複制 - >識別模式&做一個插件
  • 你不要緩存你的jQuery對象
  • 你不使用。對(&委託事件)
  • 你不這樣做你的鏈jQuery方法

沿着這些線路的重組(這只是沒有經過測試核心&而應該是一個很好的重新啓動點)

$.fn.extend({ 

    tofocus : function() { 

     var $tofocus=$(this); 
     //put your animations/effects/your browser history management stuff 
    //addcclass/removeclass 
    //chain everything .end() if necesary (like after .siblings()) 
    return $tofocus; 


    },  

    loadcontent : function(id) { 
     var $t=$(this); 
     //look if this content was already loaded 
     //if loaded $("#'+id+'").tofocus() 

     //if not -> 
     var viewportHeight=$(window).height(); 
     var $divcontent = $('<div/>', { 
        "id" : "content-"+id, 
        "class": 'content' 
        }).css({ 
         top: viewportHeight + "px", display: "none"  
       }).appendTo($t).load(id+'.php',function() { 
         $(this).tofocus(); 
     }); 
     return $t; 
    } 
}) 



$(document).ready(function() { 
    //cache your content container 
    // it will be used every time a nav button is clicked/at init & if using back/fw button -> you'll spare as much access to the dom to create the object 
    var $ctt=$("#shell"); 
    //load first page (id from hashtag on page load ?) 
    var hashfirst=... 
    $ctt.loadcontent(hashfirst); 


    $(document).on("click","#topNav a",function(e) { 
      $ctt.loadloadcontent(this.id); 
      return false 
    }) 

    window.addEventListener("popstate", function(e) { 

      var hash = window.location.hash.substr(1), 
      $ctt.loadcontent(hash); 

      }); 
}); 
+0

感謝您的反饋,我很感激! – MJR

+0

@MJR無後顧之憂; loadcontent中存在一個錯誤(它將nav id設置爲相同的id - 編輯。希望你得到插件的想法 – mikakun