2013-02-06 5 views
4

Я только начал играть с sammy.js, и первое, что я хочу сделать, это проверить, как работают изменения истории. И он работает так, как ожидалось, даже лучше, но как только я открываю IE10 и переключаюсь в режим браузера IE9, все рушится. Если я не устанавливаю ссылки с хешем, IE9 просто продолжает следовать ссылкам. Та же проблема с IE8, конечно.Маршрутизация приложения knockout.js с Sammy.js и история с поддержкой html4

На данный момент у меня только этот кусок кода, связанный с Сэмми

App.sm = $.sammy('#content', function() { 

    this.get('/', function(context) { 
     console.log('Yo yo yo') 
    }); 

    this.get('/landing', function(context) { 
     console.log('landing page') 
    }); 

    this.get('/:user', function(context) { 
     console.log(context) 
    }); 

}); 

и инициатор

$(function() { 
    App.sm.run('/'); 
}); 

Я также смотрел на эту example, который содержит три типа ссылок, нормальные, хэш и снова нормальные, но корректно работают на IE9 и IE8. что заставляет меня думать, что каким-то образом должно быть возможно сделать sammy.js поддержку html5 history и html4 в одно и то же время.

Так что мой вопрос будет, как я могу это достичь?

Update

я нашел способ заставить его работать на IE

Я просто добавил этот фрагмент:

this.bind('run', function(e) { 
     var ctx = this; 
     $('body').on('click', 'a', function(e) { 
      e.preventDefault(); 
      ctx.redirect($(e.target).attr('href')); 
      return false; 
     }); 
    }); 

Во всяком случае, я все еще возникают проблемы с входом в веб-сайт, поддерживающий браузер html5, всегда перенаправляется на домен.com, независимо от исходного URL-адреса.

Так что мне интересно, как я должен настроить sammy.js для работы peroperly. Или, может быть, кто-то может порекомендовать какой-нибудь другой маршрутизатор, который будет хорошо работать с knockout.js.

ответ

0

По ряду причин, включая пауки поисковых систем и обмен ссылками; ваш сайт должен работать без API истории. Если пользователь видит http://example.org/poodles/red и хочет показать кому-то еще красные пудели на вашем веб-сайте, они скопируют ссылку. Другой посетитель должен иметь возможность видеть один и тот же контент по одному и тому же URL-адресу; даже если они не начинаются на главной странице.

По этой причине я предлагаю использовать API истории как прогрессивное усовершенствование. Где он доступен, вы должны использовать его для обеспечения лучшего UX. Если он недоступен, ссылки должны функционировать как обычно.

Вот пример Router (например, Sammy), который просто разрешает навигацию по умолчанию, если history.pushState недоступен.

А про нокаут-часть; Я использовал это в проекте KnockoutJS, и он работает хорошо.

(function($){ 

    function Route(path, callback) { 
     function escapeRegExp(str) { 
      return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); 
     } 

     // replace "/:something" with a regular expression fragment 
     var expression = escapeRegExp(path).replace(/\/:(\w+)+/g, "/(\\w+)*"); 

     this.regex = new RegExp(expression); 
     this.callback = callback; 
    } 

    Route.prototype.test = function (path) { 
     this.regex.lastIndex = 0; 

     var match = this.regex.exec(path); 

     if (match !== null && match[0].length === path.length) { 
      // call it, passing any matching groups 
      this.callback.apply(this, match.slice(1)); 
      return false; 
     } 

    }; 

    function Router(paths) { 
     var self = this; 
     self.routes = []; 
     $.each(paths, function (path, callback) { 
      self.routes.push(new Route(path, callback)); 
     }); 

     self.listen(); 
     self.doCallbacks(location.pathname); 
    } 

    Router.prototype.listen = function() { 
     var self = this, $document = $(document); 

     // watch for clicks on links 
     // does AJAX when ctrl is not down 
     // nor the href ends in .html 
     // nor the href is blank 
     // nor the href is/
     $document.ready(function(e){ 


      $document.on("click", "[href]", function(e){ 
       var href = this.getAttribute("href"); 

       if (!e.ctrlKey && (href.indexOf(".html") !== href.length - 5) && (href.indexOf(".zip") !== href.length - 4) && href.length > 0 && href !== "/") { 
        e.preventDefault(); 
        self.navigate(href); 
       } 
      }); 
     }); 

     window.addEventListener("popstate", function(e) { 
      self.doCallbacks(location.pathname); 
     }); 
    }; 

    Router.prototype.navigate = function(url) { 
     if (window.history && window.history.pushState) { 
      history.pushState(null, null, url); 
      this.doCallbacks(location.pathname); 
     } 
    }; 

    Router.prototype.doCallbacks = function(url) { 
     var routes = this.routes; 

     for (var i=0; i<routes.length; i++){ 
      var route = routes[i]; 

      // it returns false when there's a match 
      if (route.test(url) === false) { 
       console.log("nav matched " + route.regex); 
       return; 
      } 
     } 

     if (typeof this.fourOhFour === "function") { 
      this.fourOhFour(url); 
     } else { 
      console.log("404 at ", url); 
     } 
    }; 

    window.Router = Router; 

}).call(this, jQuery); 

Пример использования:

router = new Router({ 
    "/": function() { 

    }, 
    "/category/:which": function (category) { 

    }, 
    "/search/:query": function(query) { 

    }, 
    "/search/:category/:query": function(category, query) { 

    }, 
    "/:foo/:bar": function(foo, bar) { 

    } 
}); 

router.fourOhFour = function(requestURL){ 

};