1

jQuery Mobile / Knockout.js/iScrollViewを使用してWebアプリを構築しています。Knockout.jsforeachを使用して入力しているリストがあります。ajaxリクエストを作成し、JSONオブジェクトを取得し、それを監視可能な配列にプッシュして、必要な方法ですべてを表示することでページを更新します。

ここで、iScrollViewを使用して、リストが大きくなるにつれて、スムーズにスクロールダウンして、プルアップまたはプルダウン機能を利用できるようにします。

$(element).iscrollview('refresh')アイテムが追加された後にスクロールウィンドウのサイズを調整するために、適切なタイミングで呼び出す適切な方法がわからないようです。

アイテムがすべてDOMに挿入されてからが呼び出されるまで待つ方法はありますか$(element).iscrollview('refresh')

これが私のHTMLです

<div data-role="page" id="List" data-bind="event: {pageshow: loadItems}">
      <div data-role="content" data-iscroll>
      <button value='load' data-bind="event: {click: loadItems}">load more stuff</button>
        <ul data-role="none" class="list" data-bind="foreach: items">
            <li style="visibility:hidden">
                <div class="header">
                    <h3 data-bind="text: name"></h3>
                    <p></p> 
                </div>
                <div class="feat-list-btn feat-list-action">
                    <img src="image.png" />
                </div>
                <div class="feat-list-btn feat-list-comments">
                    <img src="image.png" />
                </div>
                    <img data-bind="attr: {src: imageurl}" />
            </li>
        </ul>
      </div>
</div>

コンテンツの取得方法は次のとおりです。

function List(){
    var self = this;
    self.loadItems = function(){
        $('#List [data-role="content"]').fadeOut(0);
        $.mobile.showPageLoadingMsg();
            jQuery.ajax({
                url: mybackend.php',
                type: 'POST',
                data: 'howMany=10',
                dataType: 'jsonp',
                jsonp: 'jsoncallback',
                success: function(data, textStatus, jqXHR){
                        for (i=0;i<data.items.length;i++){
                            self.items.push(data.items[i]);
                            }   
                    },
                complete: function(){
                    $.mobile.hidePageLoadingMsg();
                    }
                });
        };
    self.items = ko.observableArray();
    self.updateScroller = function(){
        //????????
        };
    }

私はこれを行うことで解決できます

setTimeout(function(){$('#List [data-role="content"]').iscrollview('refresh');}, 1000);

しかし、私はこのようなことを行うためにsetTimeOutに依存したくありません。

4

2 に答える 2

0

ですから、これは思ったよりもずっと簡単でした。何が起こっているのかというと、画像がまだメモリに読み込まれていないため、Knockoutによって生成されたマークアップには画像がボリュームを与えるはずの場所が何もないことに気付きました。ローカルソースから取得したフィラー画像を入力しましたが、必ずしも正しいサイズであるとは限らず、スクロールの高さが不正確になる可能性があります。

私が試した結果、最終的には機能するようになりましたが、ko.Observablearrayに画像を追加する前に、画像をプリロードすることでした。だから私はこの単純な画像プリローダーをjQueryプラグインとして書きました:

(function($) {
    $.fn.preload = function( callback ) {           
        var count = 0,
            $this = this;
        for (i=0;i<this.length;i++){        
            var image = new Image();        
            $(image).on('load error', function(e){count++; if (count === $this.length){if ($.isFunction(callback)){callback.call()}}});
            image.src = this[i];;
            }
        }
    })(jQuery); 

これにより、基本的に、すべての画像がメモリに読み込まれるまで待つことができます

次に、ko.Observablearrayに追加します。これにより、画像が配置されたマークアップが挿入されます...次に、次のようにREFRESHを呼び出します。

        success: function(data, textStatus, jqXHR){
            var myImages = [];
            for (i=0;i<data.urls.length;i++){
                myImages.push(data.urls[i]);
                }
                $(myImages).preload(function(){ //only execute insertion after all images are preloaded into memory
                    for (i=0;i<data.items.length;i++){
                        self.items.push(data.items[i]);
                        }   
                        $('#featList [data-role="content"]').iscrollview('refresh');//refresh iScroll
                        $.mobile.hidePageLoadingMsg(); 
                    });         
            },

おそらくもう少し最適化できるかもしれませんが、それは実用的な解決策です...

于 2013-02-20T14:30:20.147 に答える
0

次の行を挿入するだけです。

$('#List [data-role="content"]').iscrollview('refresh');

for成功コールバックのループ後:

success: function(data, textStatus, jqXHR){
    for (i=0;i<data.items.length;i++){
        self.items.push(data.items[i]);
    }
    $('#List [data-role="content"]').iscrollview('refresh');
},
于 2013-02-20T11:08:45.400 に答える