如何将Jquery滚动事件绑定到动态添加的元素?

时间:2014-07-25 18:29:37

标签: javascript jquery ember.js scroll ember-data

我正在创建一个Ember组件,我需要将scroll事件绑定到动态创建的div。

我的车把代码如下:

<div class="searchbarContainer" tabindex="0" bubbles=false>
    {{input type="search" name="searchFor" class="searchTextField" placeholder="Search..." value=searchKey}}

    {{#if searchKeyNotNull}}
    <div class="searchResultsContainer box-shadow" {{bind-attr id="searchBarID"}}>
        {{!-- BINDS ID TO searchBarID for searchResultsContainer--}}
            {{#if noResults}} {{!-- Then say : "No Results. " --}}
                      <div class="applicantsName noResults">
                        No Results found.
                      </div>      
            {{else}}
                {{!-- For each Row, include visual elements. --}} 
                {{#each toSearch }}
                    <div> ... </div>
                {{/each}}
            <div class='endOfResults'>
                End of Results
            </div> 
            {{/if}}
    </div>
    {{/if}}
</div>

设置逻辑,以便根据输入部分输入的内容,searchKeyNotNull更新为'true'或'false',noResults也是如此。

当它现在起作用时,div searchResultsContainer将填充包含结果的div,并且有一个最大高度。我还启用了溢出功能,因此用户可以滚动查看结果。

我需要将一个scroll事件绑定到这个div,这样当它到达结尾时,就会触发一个动作。

现在,这是我开始使用的事件代码:

        $('#searchBarID').bind('scroll',function(){
        if($(this).scrollTop() + $(this).innerHeight()>=$(this)[0].scrollHeight)
        {
          alert('end reached');
        }
      });

哪个有效。不幸的是,当运行此代码片段时,尚未创建div,因此此事件永远不会被绑定。我也尝试使用jQuery.on函数,但似乎滚动没有冒泡,所以

        $('body').on('scroll','#searchBarID', function(){
        if($(this).scrollTop() + $(this).innerHeight()>=$(this)[0].scrollHeight)
        {
          alert('end reached');
        }
      });

不起作用。

我在我的智慧结束时试图找到解决方法;我需要:  a)找到一种方法将滚动绑定到动态添加的元素,或  b)找出Ember何时创建元素,这样我就可以插入这个绑定代码了。

执行这两项任务的解决方案对我有很大帮助!

3 个答案:

答案 0 :(得分:1)

我反复讨论过这个问题几次。我发现隐藏元素最简单,而不是将其放在if块中。

您可以通过扩展bind-attr

来实现
<div class="searchResultsContainer box-shadow" {{bind-attr id="searchBarID" class="searchKeyNotNull::hidden"}}>

hidden在哪里是将display设置为none的类。 这将导致元素只渲染一次,允许您像这样使用didInsertElement钩子:

onDidInsert: function () {
    var element = $('#searchBarID', this.$());
    element.on('scroll', function () {
        // your impl.
    })
}.on('didInsertElement')

在你的组件中。

我使用bind-attr隐藏元素(而不是不渲染它!)的原因是因为每次searchKeyNotNull更改时,ember都会创建一个新元素。 didInsertElement挂钩只会触发一次。

答案 1 :(得分:0)

scrollloaderror事件未冒泡(请参阅:https://developer.mozilla.org/en-US/docs/Web/Events/scroll),因此您必须在添加可滚动元素时更新处理程序。

答案 2 :(得分:0)

大多数情况下,有一种方法可以在jQuery中使用Ember视图挂钩,操作和事件来执行您通常所做的操作。

另一种方法是将该DOM节点包装在{{#view}}中,然后使用didInsertElement挂钩。例如,让我们将其包装在{{#view App.SearchResultsView}}

<div class="searchbarContainer" tabindex="0" bubbles=false>
    {{input type="search" name="searchFor" class="searchTextField" placeholder="Search..." value=searchKey}}

    {{#if searchKeyNotNull}}
      {{#view App.SearchResultsView}}
        <div class="searchResultsContainer box-shadow">
          <!-- MORE HBS HERE -->
        </div>
      {{/view}}
    {{/if}}
</div>

现在,让我们定义App.SearchResultsView

App.SearchResultsView = Ember.View.extend({
  didInsertElement: function () {
    this.$('.searchResultsContainer').on('scroll', function (e) {
      // scrolling...
    });
  }
});

希望有所帮助!如果我能进一步解释,请告诉我。