Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.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 角度ui路由器滚动到顶部,而不是ui视图_Javascript_Angularjs_Angular Ui_Angular Ui Router - Fatal编程技术网

Javascript 角度ui路由器滚动到顶部,而不是ui视图

Javascript 角度ui路由器滚动到顶部,而不是ui视图,javascript,angularjs,angular-ui,angular-ui-router,Javascript,Angularjs,Angular Ui,Angular Ui Router,我刚刚从0.2.0升级到ui-router 0.2.8,我注意到当状态改变时,滚动位置会跳到新状态的主题子ui-view的顶部 这很好,但我有两个问题: 1) 我在页面顶部和ui视图之间有30px的填充,我希望它滚动到页面顶部,留下一个间隙。目前,它正好位于ui视图的顶部,看起来很难看。要实现这一点,我想我需要知道如何让它滚动到ui视图所在的div顶部(而不是浏览器视口),或者我需要了解如何覆盖$uiviewcoll滚动到ui视图减去30px 我尝试了$uiViewScrollProvider.

我刚刚从
0.2.0
升级到
ui-router 0.2.8
,我注意到当状态改变时,滚动位置会跳到新状态的主题子
ui-view
的顶部

这很好,但我有两个问题:

1) 我在页面顶部和
ui视图之间有30px的填充,我希望它滚动到页面顶部,留下一个间隙。目前,它正好位于
ui视图的顶部,看起来很难看。要实现这一点,我想我需要知道如何让它滚动到ui视图所在的div顶部(而不是浏览器
视口
),或者我需要了解如何覆盖
$uiviewcoll
滚动到
ui视图
减去30px

我尝试了
$uiViewScrollProvider.useAnchorScroll()但如果我这样做,它根本不会滚动。我也试过
,这也会完全停止滚动

2) 此时它实际上并没有滚动,只是跳跃。是应该滚动还是由开发人员通过CSS转换来完成

任何帮助都将不胜感激:)

1)我认为最简单的方法是将
autoscroll=“false”
放在ui视图上,并在
$viewContentLoaded
事件中操纵滚动


2) 这是浏览器在锚上的默认行为

当路径更改时,路由器会广播一个事件:$stateChangeSuccess,即url已更改,因此只需收听它并使用jquery滚动到页面顶部

$rootScope.$on('$stateChangeSuccess',function(){
    $("html, body").animate({ scrollTop: 0 }, 200);
})
把上面的代码放在里面

yourAppName.run(function(){

    //the above code here
 })

另一种方法是修饰默认的
$uiViewScroll
服务,有效地覆盖默认行为

app.config(function ($provide) {
  $provide.decorator('$uiViewScroll', function ($delegate) {
    return function (uiViewElement) {
      // var top = uiViewElement.getBoundingClientRect().top;
      // window.scrollTo(0, (top - 30));
      // Or some other custom behaviour...
    }; 
  });
});

正如Hubrus所提到的,对于您不希望申请的任何
,只需添加
autoscroll=“false”
。我还没有很好地研究实际的滚动实现,我只是觉得我应该提到装饰方式(这很有趣)作为替代。我相信您可以计算出确切的滚动行为

因为在当前AngularJS(如1.2.x)中,
$stateChangeSucture
似乎不再可用,所以我更改了
app.config(function ($provide) {
  $provide.decorator('$uiViewScroll', function ($delegate) {
    return function (uiViewElement) {
      // var top = uiViewElement.getBoundingClientRect().top;
      // window.scrollTo(0, (top - 30));
      // Or some other custom behaviour...
    }; 
  });
});
Rishul Mattas举了一个对我来说很好的例子:

app.run(function ($rootScope) {
  $rootScope.$on('$viewContentLoaded',function(){
    jQuery('html, body').animate({ scrollTop: 0 }, 200);
  });
});

所以我也有同样的问题。我有一个固定顶部导航栏。如果我在ui视图中输入autoscroll=“true”,它将滚动到顶部减去滚动条的高度

所以我去掉了在顶部导航栏的主体上添加填充物的样式

// fixed navigation at top
//body { padding-top: 100px; }
并将其应用于ui视图

[ui-view=main] {
    padding-top: 100px;
}

现在autoscroll=“true”按预期工作。

如果结合了角度+材质设计,也需要滚动到顶部:

app.run(function ($rootScope) {
    $rootScope.$on('$viewContentLoaded', function () {
        $("md-content").animate({ scrollTop: 0 }, "fast"); /* <------- Notice this line */
        jQuery('html, body').animate({ scrollTop: 0 }, 200);
    });
});
app.run(函数($rootScope){
$rootScope.$on(“$viewContentLoaded”,函数(){

$(“md content”).animate({scrollTop:0},“fast”);/*我认为如果导航状态为子状态,则不需要滚动到顶部,因此我编写了以下代码:

$rootScope.$on('$stateChangeSuccess',function(_, _, _, os){
    if(!$state.includes(os) || $state.is(os))
        $("html, body").animate({ scrollTop: 0 }, 200);
});

大多数时候,仅仅滚动到页面顶部是不够的。尊重锚链接并滚动到加载内容中由位置哈希指定的特定位置总是一个好主意

以下是我用于实施此策略的代码:

module.run(函数(
$rootScope,
$timeout,
$location,
$uiViewScroll
) {
//屏幕更改时滚动。
$rootScope.$on(“$viewContentLoaded”,函数(){
$timeout(performautoscoll,0);
});
函数性能MAUTOSCROL(){
var hash=$location.hash();
变量元素=
findDomElement(“#”+散列)
||findDomElement('a[name=“”+hash+'“]”)
||元素(window.document.body)
;
$uiViewScroll(元素);
}
});
$viewContentLoaded
是Angular在
ui视图
元素中加载内容时生成的事件。实际上,我们需要推迟代码的执行,以便将其移动到下一个摘要周期。这样,视图元素的内容将实际放置在DOM树中,以便我们可以查询它。
$timeout
具有零延迟技巧用于此目的

$uiViewScroll
服务,由UI路由器提供,用于实际执行滚动。我们可以将jQuery/jqLite元素传递给它,它将滚动到它的上边框

我们正在从
$location
服务获取currect散列,并使用它在DOM树中查找正确的元素。它可以是具有
id
属性的元素,也可以是具有
name
属性的链接。如果找不到要滚动到的元素,我们将返回到
body
元素(即,将滚动至页面顶部)

findDomElement
只是一个语法糖。它的定义如下:

/**
*@param{string}选择器
*@returns{jQuery | null}
*/
函数findDomElement(选择器){
var结果=$(选择器);
返回值(result.length>0?结果为空);
}
我希望这种方法是有意义的,并且对其他人有用。干杯!

放在首位

<div id="top">.....

如果希望有条件地对视图执行此操作,可以将其放置在控制器视图中,如下所示:

.state('exampleState', {
    url: '/exampleURL',
    controller: 'ExampleCtrl as examplectrl',
    onEnter: function($rootScope) {
            $rootScope.$on('$viewContentLoaded',function(){
            jQuery('html, body').animate({ scrollTop: 0 }, 200);
        });
    }
}).
或者,也可以选择将state.js文件放在给定视图的控制器中:

function ExampleCtrl ($scope, $rootScope) {

    $rootScope.$on('$viewContentLoaded',function(){
            jQuery('html, body').animate({ scrollTop: 0 }, 200);
        });
}

希望这对其他人有所帮助,如果我遗漏了什么,请告诉我。我使用了后者,对我来说效果很好。

你能提供一个现场演示吗?如果不让我的整个应用程序进入plunker,这非常困难。我会尝试,但不确定如何简化它。好吧,简化它可能是解决问题的第一步。它将帮助你掌握瘦我可能可以编写滚动代码,但不确定在代码中的何处连接到$viewContentLoaded(我实际上不知道它存在),这听起来像是一个好建议,尽管它是一个可滚动的div,我需要转到t