【问题标题】:Defer updating DOM推迟更新 DOM
【发布时间】:2019-03-22 18:00:11
【问题描述】:

OP 说明: 我不是在询问内置的淘汰赛延迟设置,除非可以通过某种方式对其进行操作


我有一个应用程序,它加载了所有可能的屏幕并最初绑定到视图模型。视图模型上的属性之一控制用户可以看到哪些“屏幕”。

出于纯粹的病态好奇心,我想知道是否有一种内置的或相对简单的方法来告诉 knockout 停止操作 DOM 的某些部分,“仅当 X 属性等于此值时才更新此块”。甚至更好 - 如果在 KO 中关闭此元素的可见性,则不要操作任何子元素。

最终结果将是不可见的“屏幕”不会更新,而视图模型上的可观察对象仍将在后台执行它们的操作。然后当屏幕发生变化时,该新可见屏幕的 DOM 将被更新。

许多屏幕使用相同的 observables,所以我认为不经常重新操作 DOM 可能会提高性能 - 例如更新当前对用户不可见的 HTML 列表同时弄乱另一个屏幕中的设置。

或者性能优势可以忽略不计,因为浏览器不会重绘隐藏元素。你可以告诉我很多。

运行 KnockoutJS 3.4.x,如果这很重要。

【问题讨论】:

  • 完全忽略 javascript,浏览器很难确定什么是“可见的”。 Z-Index、Opacity、Transforms、Display、Visibility,我的意思是有很多方法可以隐藏某些东西,在没有浏览器帮助的情况下试图弄清楚这一点几乎是不可能的。唯一的好方法是让您根据逻辑 UX 跟踪应该绑定和不绑定的内容。
  • @ErikPhilips 使用敲除可见属性绑定,因此它会保持一致并与敲除知道的东西相关联,而不是试图根据 css/html/viewport/etc 确定当前对用户的可见性。

标签: javascript knockout.js knockout-3.0


【解决方案1】:

查看 Knockout 的控制流绑定。 ififnotwith绑定可以决定是否渲染被绑定的dom节点包围的DOM元素。我认为这将是您最好的选择。

由于你不想渲染不必要的 dom 节点,所以不要使用可见绑定,因为它只是隐藏了 dom 节点,但它仍然在 DOM 中渲染

【讨论】:

    【解决方案2】:

    正如 Nathan 所说,if/with 绑定是一个很好的起点。对于更复杂的场景,我通常会使用模板绑定来完成这类事情。每个子元素都有自己的视图模型,根视图模型将有一个 CurrentPage 可观察对象,它包含“可见”页面。这是一个更复杂的设置,但是当您有许多页面的标记时,它可以使代码更简洁。

    function viewModel(){
    	var self = this;
    
    	this.PageOne = new pageOneVM();
    	this.PageTwo = new pageTwoVM();
    	
    	this.CurrentPage = ko.observable(this.PageOne);
    	this.CurrentTemplate = ko.pureComputed(function(){
    		return self.CurrentPage().TemplateName;
    	});
    }
    
    function pageOneVM(){
    	var self = this;
    	
    	this.TemplateName = 'viewOne';
    }
    
    function pageTwoVM(){
    	var self = this;
    	
    	this.TemplateName = 'viewTwo';
    }
    
    ko.applyBindings(new viewModel());
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
    
    <label>Select a page:</label><input type="button" data-bind="click: function(){CurrentPage(PageOne)}" value='1'/><input type="button" data-bind="click: function(){CurrentPage(PageTwo)}" value='2'/>
    <br/><br/>
    
    
    <div style="border: 1px solid blue;" data-bind="template: { data: CurrentPage, name: CurrentTemplate }"></div>
    
    
    <script type="text/html" id="viewOne">
    	<h4>Page One</h4>
    </script>
    
    <script type="text/html" id="viewTwo">
    	<h4>Page Two</h4>
    </script>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-04
      • 1970-01-01
      • 1970-01-01
      • 2015-01-18
      • 1970-01-01
      相关资源
      最近更新 更多