Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用AngularJS的AngularUI路由器在一个页面上显示多个历史视图_Javascript_Angularjs_Angular Ui Router - Fatal编程技术网

Javascript 使用AngularJS的AngularUI路由器在一个页面上显示多个历史视图

Javascript 使用AngularJS的AngularUI路由器在一个页面上显示多个历史视图,javascript,angularjs,angular-ui-router,Javascript,Angularjs,Angular Ui Router,在我的AngularJS应用程序中,我有一个关于页面,其中有几个小节。所有这些子部分都位于同一页面上,并且是同一模板的一部分。但是,我想通过它自己的URL访问每个部分,如果匹配,该URL将向下滚动到正确的部分 我将各州设置为: .state('about', { url: "/about", templateUrl: "partials/about.html", }) .state('about.team', { url: "/about/team", templ

在我的AngularJS应用程序中,我有一个关于页面,其中有几个小节。所有这些子部分都位于同一页面上,并且是同一模板的一部分。但是,我想通过它自己的URL访问每个部分,如果匹配,该URL将向下滚动到正确的部分

我将各州设置为:

.state('about', {
    url: "/about",
    templateUrl: "partials/about.html",
})
.state('about.team', {
    url: "/about/team",
    templateUrl: "partials/about.html"
})
.state('about.office', {
    url: "/about/office",
    templateUrl: "partials/about.html"
})
.state('about.other', {
    url: "/about/other",
    templateUrl: "partials/about.html"
});
在“关于”页面上,我有一个菜单,如:

<div class="menu">
    <a ui-sref-active="selected"
    ui-sref="about.team">The Team</a>
    <a ui-sref-active="selected"
    ui-sref="about.office">The Office</a>
    <a ui-sref-active="selected"
    ui-sref="about.other">Other</a>
</div>

您可以在此处看到该应用程序:


对于类似()的示例,您可以看到它在页面加载后根据url向下滚动到正确的部分。。。并且不使用散列,而是使用实际的url。

我将使用window.scrollTo或jquery scrollTo插件创建一个scrollTo指令

例如: 使用window.scrollTo

Jquery滚动到插件:

在页面加载时,滚动到由hashtag或任何其他url参数定义的视图。例子:
www.sample.com#aboutUs或www.samplecom?view=aboutUs

您可以尝试这种方法,创建一个指令,在单击时触发滚动。 您可以将此指令作为属性添加到链接中。其中,sref属性将是目标div的id

app.directive('scrollTo', function() {
  return {
    link: function(scope, element, attrs) {
    element.bind('click', function() {
      var divPosition = $(attrs.sRef).offset();
      $('html, body').animate({
      scrollTop: divPosition.top
      }, "slow");

    });
   }
  };
});

在滚动时,我应该:

1. bind to "scroll" events, 
2. compare if I reached the position of each headers, using "element.offset().top"
(将此标题设置为指令后。(我应该将标题设置为指令,检查如何从ngtutorial.com/learn/scope生成目录)

加载时(我更喜欢使用hashtags,因为我可以只使用$anchorScroll()或使用.when()),无论如何,加载时更新的示例如下:

1. http://ngtutorial.com/guide.html#/learn-filter.html
2. http://ngtutorial.com/learn/route.html#/_tblcontents_5
如果你不喜欢hashtags,你可以解析location.url()

我在自己的应用程序中用来做滚动控制(和滚动间谍的东西),而不是使用locationHash。我自己还没有尝试过这个解决方案,但我想它会起作用

您需要在重要div(滚动到的位置)上声明某种类型的条目id

然后,您可以使用url/about/:locale声明状态“about.stately”(在ui中,路由器stateParams不必是整数)。然后在about.stately的控制器中,您可以执行以下操作(从角度滚动自述文件):


根据控制器中的$stateParams.locale选择要滚动到的元素。请小心等待,直到所有子指令和内容加载完毕-您可能需要$evalAsync才能使其正常工作。但我认为这就是它的要点。

这就是我目前尝试的:

// get the current path
var x=$location.path();
// say x='about/team'
//read the last tag and set scrollTo to the top offset of desired div
if(lasttag(x)==team){
scroll to top offset of TEAM div;
}
else if(lasttag(x)==office){
scroll to top offset of OFFICE div;
}
var scrolled = false;

var listenToScroll = false;

$('.subsection').each(function(i) {
    var position = $(this).position();
    $(this).scrollspy({
        min: position.top,
        max: position.top + $(this).outerHeight(),
        onEnter: function(element, position) {
            if(element.id){
                if(listenToScroll) {
                    scrolled = true;
                    $state.transitionTo('about.'+element.id);
                }
            } else {
                if(listenToScroll) {
                    scrolled = true;
                    $state.transitionTo('about');
                }
            }
        }
    });
});

$scope.startListenToScroll = function() {       

    listenToScroll = true;
}

$scope.stopListenToScroll = function(){

    listenToScroll = false;
}

$scope.$on('$stateChangeStart', function(){

    $scope.stopListenToScroll();

});

$scope.$on('$stateChangeSuccess', function(){

    console.log(scrolled);

    if( !scrolled ) {
        var link = $state.current.name.split('.');
        if(link.length>1){
            var divPosition = $( '#' + link[1] ).offset();
            $('body').stop(true,true).animate({ scrollTop: divPosition.top }, "fast", function(){
                $scope.startListenToScroll();
                scrolled = false;
            });
        } else {
            $('body').stop(true,true).animate({ scrollTop: 0 }, "fast", function(){
                $scope.startListenToScroll();
                scrolled = false;
            });
        }
    } else {
        $scope.startListenToScroll();
        scrolled = false;
    }

});
正如你所看到的,我听stateChangeSuccess而不是点击!这样我就可以连接到任何状态更改,不管它们是由链接还是浏览器历史按钮调用的,并根据需要执行滚动

我会在开始更改时立即关闭scrollspy,这样滚动动画就不会调用另一个状态更改(因为您可能会滚动其他部分以创建假历史记录条目)。然后在动画完成后再次打开scrollspy,以便我可以再次侦听滚动事件

stateChangeSuccess在页面加载时触发,因此它可以处理URL的任何粘贴

我有一个名为
scrolled
的变量,这样我就可以跟踪状态更改是否是由用户滚动引起的。这是因为我不需要在用户滚动自己时设置scrollTop的动画


想法?

您需要做的是在页面顶部创建一个指令,该指令位于ui路由器之外,用于监视状态,然后根据正确的定位点滚动。无需使用TemplateURL,因为您尝试实现的是某种平滑。

ui路由器不会对状态设置限制您的状态对象的签名,因此您可以简单地添加属性:

  .state('about.office', {
     url: "/about/office"
    ,templateUrl: "partials/about.html"
    ,scrollToId = "divAboutOffice";
  })
然后,控制器可以在注入$state服务时访问此数据

  $('html, body').animate({
    scrollTop:  $($state.current.scrollToId).offset().top
  }, "slow");
假设您在HTML中包含了
id=“divaboutofice”
(假设我的jQuery引用是正确的;我不使用jQuery,所以我不确定。) 根据您的需要,您可以将该
动画()


另外:你不必像我一样使用“id”——如果你真的想按属性搜索元素,你可以利用现有的
ui-sref
。在您的示例中,它似乎与
$state.current.name

匹配,它不应该依赖于hashtags或查询参数,而是实际的URL,无论我是否使用HTML5模式!您可以在url中将分隔符添加到单独的部分。e、 g.
#关于/home
<代码>#关于/office
。然后,您可以将
散列
/
进行拆分,并在有分区时滚动到所需位置。这不是我想做的!它应该是一个URL,而不是依赖于散列
/about/your opportunity
https://devart.withgoogle.com/#/about/your-opportunity
,但格式类似于url的一部分。这是因为他们关闭了HTML5模式。在我的实现中,HTML5模式将被打开,因此不能依赖哈希。@Jashwant你能举例说明你的意思吗?它在HTML5模式下如何工作?谢谢。你能详细说明代码的哪些部分可以做什么吗?(最好将最重要的片段复制到答案中)好的,我已经设法让它滚动,它自然地更新了URL,因为上面有href。但我需要它来处理历史记录和页面加载。那么我该如何调用滚动呢?为此,您可以在AppCtrl中创建一个基本控制器,您可以使用该逻辑函数AppCtrl($state){var divPosition=$('#'+$state.name).offset();$('html,body').animate({scrollTop:divPosition.top},“slow”)}请展示一个示例,然后我可以更新示例应用程序中的代码来测试它。请记住,它需要在页面加载时启动,如果用户使用浏览器的后退和前进按钮。T
  .state('about.office', {
     url: "/about/office"
    ,templateUrl: "partials/about.html"
    ,scrollToId = "divAboutOffice";
  })
  $('html, body').animate({
    scrollTop:  $($state.current.scrollToId).offset().top
  }, "slow");