【问题标题】:How to set initial focus of textbox on page load using knockoutjs如何使用 knockoutjs 在页面加载上设置文本框的初始焦点
【发布时间】:2014-03-26 14:20:56
【问题描述】:

在使用敲除时,我无法在页面加载时将初始焦点设置为文本框。当我尝试使用淘汰属性“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;
                };
            });
        }
    };
});

【问题讨论】:

  • 如果你使用 hasFocus 绑定而不需要调用 jquery focus 函数,hasFocus 会做技巧。检查这个小提琴jsbin.com/niqurilo/1/edit hasFocus 是否正常工作。
  • 那么解释一下为什么 hasfocus 在我的 jsFiddle 上不起作用?

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


【解决方案1】:

我对函数的位置做了一些更改,还结合了你的准备函数。

寻找我放置的

$(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

【讨论】:

  • 这是否为您解决了问题?我将您的代码粘贴到 jsfiddle 中,结果相同。准备好两个文件不是问题。那是因为我从其他脚本中粘贴了代码以确保完整性。同样,当我注释掉视图模型创建和应用绑定代码时,焦点就起作用了。
  • 是的,确实如此。它适用于 chrome,即和 firefox,我现在将通过链接 - jsfiddle.net/6RMk3/17 - 就像有人说的那样,你的东西似乎没有按照你认为的顺序运行。
  • 好的,它现在确实在 jsfiddle 中修复了它。由于某种原因,它以前并不令人耳目一新。正如你所说,这似乎是一个订单问题。我现在唯一遇到的问题是那些文档准备好在多个文件中被带入页面。我将它们粘贴到 jsfiddle 中以获得一个工作示例。我现在正在努力将这个 javascript 拆分为多个文件,但仍然在正确的时间运行焦点。
  • 好的,看看这个网址,jsfiddle.net/6RMk3/42,我现在把它放在哪里都没关系。最初的问题是 IndexViewModel 没有实例化并且没有定义,所以它在达到焦点功能之前就被炸毁了。我相信这是您遇到的问题,您在某处运行任何代码之前就已经崩溃了。检查您的代码和实例化。
【解决方案2】:

在敲除设置后,有些东西正在将焦点从您的文本字段上移开,可能是 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

【讨论】:

    【解决方案3】:

    好的,所以您并没有按照您认为它们运行的​​顺序运行事物。我建议使用https://github.com/DegreeDev/Registrar 之类的东西按照有趣的顺序注册和运行您的文件。例如,您在 $(document).ready 上有一堆在文档准备好时被触发,它们被异步启动,因此取决于它们何时完成事情可能不在您认为的位置(您底部的焦点呼叫)。

    【讨论】:

      【解决方案4】:

      尝试使用.triggerHandler("focus") 而不是.focus()。

      【讨论】:

      • 这并不能解决问题。
      • 它更像是一个研究方向。仅调用焦点不会触发焦点事件,您还有两个文档准备调用。不过,我确实看到了两者的焦点调用。快速查看link 即可了解原因。
      • 问题不在于 jQuery。当不涉及淘汰赛时,专注确实有效。这就是为什么我在上面的问题中提到了这一点。淘汰赛似乎有干扰,淘汰赛的hasfocus不起作用。
      猜你喜欢
      • 2011-11-13
      • 2011-02-12
      • 1970-01-01
      • 2011-03-23
      • 2014-01-23
      • 1970-01-01
      • 1970-01-01
      • 2013-08-21
      • 2013-07-10
      相关资源
      最近更新 更多