0

独自の jQuery ウィジェットを作成しようとしています。私はすべての HTML と jQuery を記述しており、次を使用してページに動的に追加しようとしています。

<div class='searchbar'></div>

このウィジェットは、Knockout.js と、私が自分で書いた大量のコードを使用しています。私が直面している問題 [私が疑う] は、スクリプトのロード順序に関するものです。

これは私が得ているエラーです:

Timestamp: 11/20/2012 9:26:13 AM
Error: Error: Unable to parse binding attribute.
Message: SyntaxError: syntax error;
Attribute value: value: query, valueUpdate: 
Source File: http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-1.2.1.js
Line: 44

Knockout バインディング ブロックをコメント アウトすると、すべてが機能します (ドロップダウンの値を除く)。このコードでうまくいかない理由がわかりません。

私のjQueryは以下にありますが、現在行っていることのライブバージョンはHERE . これは、すべてを動的にロードしようとせずに動作するバージョンです。

(function() {

    var jQuery;

    /******** Load jQuery if not present *********/
    if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.8.0') {
        var script_tag = document.createElement('script');
        script_tag.setAttribute("type","text/javascript");
        script_tag.setAttribute("src",
            "http://code.jquery.com/jquery-1.8.0.min.js");
        if (script_tag.readyState) {
          script_tag.onreadystatechange = function () { // For old versions of IE
              if (this.readyState == 'complete' || this.readyState == 'loaded') {
                  scriptLoadHandler();
              }
          };
        } else {
          script_tag.onload = scriptLoadHandler;
        }
        (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
    } else {
        jQuery = window.jQuery;
        main();
    }

    /******** Called once jQuery has loaded ******/
    function scriptLoadHandler() {
        jQuery = window.jQuery.noConflict(true);
        main(); 
    }

    /******** Our main function ********/
    function main() { 
        jQuery(document).ready(function($) {

            $("head").append("<link href='style.css' rel='stylesheet' type='text/css' />");         
            $.getScript("http://knockoutjs.com/js/jquery.tmpl.js", function(){});
            $.getScript("http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-1.2.1.js", function(){});

            $(".searchBox").append("<div id='refine'>Creator</div>");
            $(".searchBox").append("<input class='inline' placeholder='Search...' size='30' type='text' id='search' data-bind='value: query, valueUpdate: 'keyup'' autocomplete='off' />");
            $(".searchBox").append("<div id='submit'>Search</div>");
            $(".searchBox").append("<div id='refineDropdown'><ul id='refineList'></ul></div>");
            $(".searchBox").append("<div id='dropdown'><ul data-bind=\"template: { name:'obj', foreach:objects }, click: function(){ $('.listObjItem').on('click', function(){ $('#search').val($(this).text()); $('#dropdown').hide(); $('#search').focus();});}\"></ul></div>");
            $(".searchBox").append("<script type='text/html' id='obj'><li class='listObjItem'><span data-bind='text: name'></span>&nbsp;in&nbsp;<strong data-bind='text: type'></strong></li></script>");

            /* Begin Knockout Bindings */

            var objects = [
              {name:"Pacers Game",              type:"Activities"},
              {name:"Colts Game",               type:"Activities"},
              {name:"Ice Game",                 type:"Activities"},
              {name:"Indians Game",             type:"Activities"},
              {name:"Fever Game",               type:"Activities"},
              {name:"Purdue Game",              type:"Activities"},
              {name:"Campaign Posters",         type:"Projects"},
              {name:"Campaign Media",           type:"Projects"},
              {name:"Event Booking",            type:"Projects"},
              {name:"New Product Seminar",      type:"Projects"},
              {name:"State Fair",               type:"Projects"},
              {name:"Draft Designs",            type:"Tasks"},
              {name:"Design Posters",           type:"Tasks"},
              {name:"Review Designs",           type:"Tasks"},
              {name:"Book Venue",               type:"Tasks"},
              {name:"Decorate ICC",             type:"Tasks"},
              {name:"Book Live Music",          type:"Tasks"},
              {name:"Arrange for DJ Payment",   type:"Tasks"},
              {name:"Event Cleanup",            type:"Tasks"}
            ];

            var viewModel = { query: ko.observable('') };

            viewModel.objects = ko.dependentObservable(function() {
                var search = this.query().toLowerCase();
                return ko.utils.arrayFilter(objects, function(obj) {
                    return obj.name.toLowerCase().indexOf(search) >= 0;
                });
            }, viewModel);

            ko.applyBindings(viewModel);

            /* End Knockout Bindings */

            var refine = ["All", "ID", "Creator", "Name", "Description", "Last Modified"];

            refine = refine.sort();
            for (var i = 0; i < refine.length; i++)
                $('#refineList').append('<li>' + refine[i] + '</li>');

            testLength();
            $("#dropdown").hide();
            $("#refineDropdown").hide();

            if($.browser.chrome) {
                $('#search').css('height','26px');
                $('#search').css('padding','0px 5px 0px 5px');
                $('#refine').css('margin-right','-3px');
            }
            else if($.browser.mozilla) {
                $('#search').css('height','25px');
                $('#search').css('padding','0px 5px 0px 5px');
                $('#search').css('margin-top','-6px');
                $('#refine').css('margin-right','-1px');
            }
            else if($.browser.msie) {
                $('#search').css('height','22px');
                $('#search').css('padding','4px 5px 0px 5px');
            }

            var $hidden = $('#hidden');
            $("input").keyup(function(e) {
                testLength();
                $('#refine').removeClass('refineClicked');
                $('#refineDropdown').hide();
                if (this.value.length) {
                    var that = this;
                    $("#dropdown li").each(function() {
                        if ($(this).html().toLowerCase().indexOf(that.value.toLowerCase()) == -1) $(this).appendTo($hidden);
                    });
                    $('#hidden li').each(function() {
                        if ($(this).html().toLowerCase().indexOf(that.value.toLowerCase()) !== -1) $(this).appendTo('#list');
                    });
                    $("#search").css('border-bottom-right-radius', '0px');
                    $("#dropdown").show();
                }
                else {
                    $("#dropdown").hide();
                }
                if (e.which !== 40 && e.which !== 38) {
                    $('#dropdown li,#hidden li').each(function() {
                        $(this).removeClass('selected');
                    });
                    liSelected = null;
                }
            });

            $('#dropdown li').click(function() {
                $('#search').val($(this).text());
                $('#search').focus();
                $("#dropdown").hide();
            });

            var li = $('li');
            var liSelected;

            $('input').keydown(function(e) {
                liSelected = $('#dropdown .selected');

                if (e.which === 40) { // down-arrow
                    if (liSelected.length) {
                        var next = liSelected.next();

                        if (next.length) {
                            liSelected.removeClass('selected');
                            liSelected = next.addClass('selected');
                        }
                    }
                    else {
                        liSelected = $('#dropdown li').eq(0).addClass('selected');
                    }
                }
                else if (e.which === 38) { // up-arrow
                    if (liSelected.length) {
                        var prev = liSelected.prev();

                        if (prev.length) {
                            liSelected.removeClass('selected');
                            liSelected = prev.addClass('selected');
                        }
                        else {
                            liSelected = $('#dropdown li').eq(-1).addClass('selected');
                        }
                    }
                    else {
                        liSelected = li.last().addClass('selected');
                    }
                }
                else if (e.which === 13) {
                    $('#search').val(liSelected.text());
                    $("#dropdown").hide()
                    $('#search').blur();
                }
            });

            $('#refine').click(function() {
                $("#dropdown").hide();
                if (!$('#refine').hasClass('refineClicked')) {
                    $('#refine').addClass('refineClicked');
                    $('#refineDropdown').show();
                }
                else {
                    $('#refine').removeClass('refineClicked');
                    $('#refineDropdown').hide();
                }
            });

            $('#refineDropdown li').click(function() {
                var tmp = $('#refine').width();
                $('#refine').html($(this).text());
                $('#refine').removeClass('refineClicked');
                $("#refineDropdown").hide();
                testLength();
                $('#search').css('width', $('#search').width() + (tmp - $('#refine').width()));
            });

            $('#submit').click(function() {
                alert('Searching for ' + $('#search').val() + '...');
            }); 

            function testLength() {
                if ($('#refine').text().length > 7) {
                    $('#refine').html($('#refine').text().substring(0, 6) + "...");
                }
                $('#dropdown').css('width', $('#search').width() + 4);

                if($.browser.chrome)
                    $('#dropdown').css('margin-left', $('#refine').width() + 11);
                else
                    $('#dropdown').css('margin-left', $('#refine').width() + 13);
            }
        });
    }
}());
4

2 に答える 2

0

私は解決策を考え出しました。スクリプトを動的にロードする代わりに、スクリプトを HTML ページの先頭に直接挿入します。外部ライブラリがロードされているかどうかを確認するためのチェックをスクリプト ファイルに追加することもできますが、多くの余分な不要な作業が発生することになると思います。

この質問への将来の訪問者にとって、以下のスクリプトの順序は、ノックアウトで何かが機能するために絶対に必要です. また、jQuery tmpl の読み込みが Knockout.js よりも遅いことにも注意してください。それらを動的にロードしようとすると、外部ライブラリのロードが終了したときに起動する関数がありました。tmpl が最初にリストされていても、Knockout は常に最初にロードされていました (ブラウザーが最後のアラートを最初に処理してから前のアラートにロールバックしない限り...これが間違っている場合は修正してください)。

    <head>
        <title>Search Prototype</title>
        <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
        <script type="text/javascript" src="https://raw.github.com/jquery/jquery-tmpl/master/jquery.tmpl.js"></script>
        <script type="text/javascript" src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.2.0.js"></script>
        <script type="text/javascript" src="search.js"></script>
    </head>
于 2012-11-20T15:37:29.893 に答える