如何使用knockoutjs在页面加载上设置文本框的初始焦点

时间:2014-02-24 18:26:59

标签: jquery asp.net-mvc asp.net-mvc-3 knockout.js

使用knockout时,我无法在页面加载时将初始焦点设置为文本框。当我尝试使用knockout属性“hasfocus”设置焦点时,它什么都不做。当我再次调用jQuery函数时,它什么都不做。

我发现如果删除applyBindings调用,我的jQuery就可以了。所以看起来似乎是淘汰赛正在干扰文本框获得焦点。

我的输入文本框如下所示:

<input id="txtShippingLine" type="text" class="TextBox" data-bind="hasfocus: true, value: shipToNumber, enterKeySubmit: getDetailedShippingLineAndProcess, tabKeySubmit: getDetailedShippingLineAndProcess" />

我尝试设置焦点的jQuery看起来像这样:

$(document).ready(function() {
$('#txtShippingLine').focus();

});

我在这里有一个jsfiddle:http://jsfiddle.net/fande455/6RMk3/

我在Chrome,Firefox和IE中尝试过这种方法,每种方法都有相同的行为。

更新 所以jsFiddle现在正在使用一个文件中的所有javascript。但是,我有一个MVC视图导入脚本以及_Layout.cshtml文件导入javascript,并在每个文件中都有document.ready()函数。

Index.html视图文件的顶部如下所示:

    @section JavaScript
{
   <script type="text/javascript" src="@Url.Content("~/Scripts/Model/ShippingLine.js")"></script>
   <script type="text/javascript" src="@Url.Content("~/Scripts/Model/DetailedShippingLine.js")"></script>
   <script type="text/javascript" src="@Url.Content("~/Scripts/Model/ShippedPackage.js")"></script>
   <script type="text/javascript" src="@Url.Content("~/Scripts/Model/PackageDetail.js")"></script>
   <script type="text/javascript" src="@Url.Content("~/Scripts/Model/Address.js")"></script>
    <script type="text/javascript" src="@Url.Content("~/Scripts/ViewModel/Index.js")"></script>

    <script type="text/javascript">
        $(document).ready(function() {
            $('#txtShippingLine').focus();
            viewModel.getShippedPackages();
            ko.applyBindings(viewModel);
        });

        // create a function for getting the root path 
        $.url = function (url) {
            var path = '@Request.ApplicationPath'
            if (path != '/') path = path + '/'
            return path + url;
        };

        var viewModel = new IndexViewModel();
    </script>
}

<div class="ConfirmationDialog">
    <p><span class="ui-icon ui-icon-alert" style="float: left; margin: 0 7px 20px 0;"></span>This shipment will be permanently deleted and cannot be recovered. Are you sure?</p>
</div>

<div id="Loading" data-bind="visible: loading()">
    <img src="@Url.Content("~/Content/Images/loading.gif")" alt="Now Loading..." />
</div> 

<div id="IndexxTabs" data-bind="jQueryUITabs: true, tab3show: getShippedPackages, visible: loading() != true" class="Tabs">
    <ul>
        <li><a href="#tabs-1">Ship</a></li>
        <li><a href="#tabs-2">Find Shipping Lines</a></li>
        <li><a href="#tabs-3">Recent Shipments</a></li>
    </ul>
    <div class="tab" id="tabs-1">
        <h1>Ship</h1>
        <div class="ui-state-error ui-corner-all" style="padding: 4px" data-bind="text: tab1ErrorMessage, visible: tab1ErrorMessage().length > 0"></div>
        <div id="textboxWrapper" data-bind="visible: !detailedShippingLine().Id">
            <input id="txtShippingLine" type="text" class="TextBox" data-bind="hasFocus: setFocus, value: shipToNumber, enterKeySubmit: getDetailedShippingLineAndProcess, tabKeySubmit: getDetailedShippingLineAndProcess" />
            <button data-bind="jQueryUIButton: true, click: getDetailedShippingLine" type="button">Ship</button>
        </div>

_Layout.cshtml文件的顶部如下所示:

    <!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>@ViewBag.Title</title>
        <link href="@Url.Content("~/Content/IndexxShip.css")" rel="stylesheet" type="text/css" />
        <link href="@Url.Content("~/Content/Themes/redmond/jquery-ui-1.10.4.custom.css")" rel="stylesheet" type="text/css" />
        <script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-3.0.0.js" type="text/javascript"></script>
        <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.0.min.js" type="text/javascript"></script>
        <script src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.10.4/jquery-ui.js" type="text/javascript"></script>
        <script src="@Url.Content("~/Scripts/CustomBindings.js")" type="text/javascript"></script>
        <script src="@Url.Content("~/Scripts/Libraries/moment.min.js")" type="text/javascript"></script>
        @RenderSection("JavaScript", required: false)

        <script type="text/javascript">
            $(document).ready(function () {
                //$(".Tabs").tabs();
                //$("button").button();
                $(".ConfirmationDialog").dialog({
                    resizable: false,
                    autoOpen: false,
                    width: 640,
                    height: 480,
                    modal: true
                });

            });
        </script>
    </head>

_Layout.cshtml引用的脚本之一是CustomBindings.js,如下所示:

$(document).ready(function () {
    // A binding to apply jQueryUI Button to an element
    ko.bindingHandlers.jQueryUIButton = {
        init: function (element, valueAccessor) {
            $(element).button();
        }
    };

    // A binding to apply jQueryUI Button to an element,
    // and to allow enable / disable bindings
    ko.bindingHandlers.jQueryUIButtonEnabled = {
        init: function (element, valueAccessor) {
            $(element).button();
        },
        update: function (element, valueAccessor) {
            if (ko.utils.unwrapObservable(valueAccessor())) {
                $(element).button("enable");
            } else {
                $(element).button("disable");
            };
        }
    };

    // For jQueryUI Tabs. Handles additional bindings tab1show, tab2show, and tab3show
    // These bindings take a function as their value, and when that tab is shown, this
    // binding invokes the function
    ko.bindingHandlers.jQueryUITabs = {
        init: function (element, valueAccessor, allBindingsAccessor) {
            $(element).tabs();
            var allBindings = allBindingsAccessor();
            $(element).bind('tabsshow', function (event, ui) {
                switch (ui.index) {
                    case 0:
                        if (allBindings.tab1show) {
                            allBindings.tab1show();
                        };
                        break;

                    case 1:
                        if (allBindings.tab2show) {
                            allBindings.tab2show();
                        };
                        break;

                    case 2:
                        if (allBindings.tab3show) {
                            allBindings.tab3show();
                        };
                        break;
                }
            });
        }
    };

    // A binding to attach the ENTER key to a form field
    ko.bindingHandlers.enterKeySubmit = {
        init: function (element, valueAccessor) {
            $(element).keyup(function (e) {
                if (e.keyCode == 13) {
                    e.preventDefault();
                    valueAccessor()();
                    return false;
                };
            });
        }
    };
});

4 个答案:

答案 0 :(得分:0)

我对功能的位置做了一些更改,我也将你的就绪功能组合在一起。

寻找&lt; - 这里我放的标签。 (Stack Overflow让我无法发布jfiddle url所以我只是引用了下面的全部内容。我的appologies)

$(document).ready(function () {
    $('#txtShippingLine').focus(); // <-- here
    viewModel.getShippedPackages();
    ko.applyBindings(viewModel);

    // A binding to apply jQueryUI Button to an element
    ko.bindingHandlers.jQueryUIButton = {
        init: function (element, valueAccessor) {
            $(element).button();
        }
    };

    // A binding to apply jQueryUI Button to an element,
    // and to allow enable / disable bindings
    ko.bindingHandlers.jQueryUIButtonEnabled = {
        init: function (element, valueAccessor) {
            $(element).button();
        },
        update: function (element, valueAccessor) {
            if (ko.utils.unwrapObservable(valueAccessor())) {
                $(element).button("enable");
            } else {
                $(element).button("disable");
            };
        }
    };

    // For jQueryUI Tabs. Handles additional bindings tab1show, tab2show, and tab3show
    // These bindings take a function as their value, and when that tab is shown, this
    // binding invokes the function
    ko.bindingHandlers.jQueryUITabs = {
        init: function (element, valueAccessor, allBindingsAccessor) {
            $(element).tabs();
            var allBindings = allBindingsAccessor();
            $(element).bind('tabsshow', function (event, ui) {
                switch (ui.index) {
                    case 0:
                        if (allBindings.tab1show) {
                            allBindings.tab1show();
                        };
                        break;

                    case 1:
                        if (allBindings.tab2show) {
                            allBindings.tab2show();
                        };
                        break;

                    case 2:
                        if (allBindings.tab3show) {
                            allBindings.tab3show();
                        };
                        break;
                }
            });
        }
    };

    ko.bindingHandlers.enterKeySubmit = {
        init: function (element, valueAccessor) {
            $(element).keyup(function (e) {
                if (e.keyCode == 13) {
                    e.preventDefault();
                    valueAccessor()();
                    return false;
                };
            });
        }
    };

    ko.bindingHandlers.tabKeySubmit = {
        init: function (element, valueAccessor) {
            $('body').keyup(function (e) {
                if (e.keyCode == 9) {
                    e.preventDefault();
                    valueAccessor()();
                    return false;
                };
            });
        }
    };
});

// create a function for getting the root path <-- here
$.url = function (url) {
    var path = '@Request.ApplicationPath'
    if (path != '/') path = path + '/'
    return path + url;
}

var viewModel = new IndexViewModel(); <-- here

答案 1 :(得分:0)

在淘汰设置之后,某些东西正在将焦点从文本字段中移开,可能是jquery选项卡。异步设置。

<input ... data-bind="hasFocus: initialFocus, ..." />

并在您的javascript中

viewModel.initialFocus = ko.observable(true)
$(document).ready(
  // doesn't need to be in its own doc.ready
  function(){setTimeout(function(){viewModel.initialFocus(true);},0);
});

jsfiddle link

答案 2 :(得分:-1)

好的,所以你没有按照你认为正在运行的顺序运行东西。我建议使用像https://github.com/DegreeDev/Registrar之类的东西来按照它们应该很有趣的顺序注册和运行你的文件。例如,你有一堆$(document).ready在文件准备就绪时会被触发,它们会被异步启动,所以取决于它们完成的时间可能不在你认为它们的位置(你)焦点在底部调用)。

答案 3 :(得分:-2)

尝试使用.triggerHandler("focus")代替.focus()