在table或div元素上使用hasFocus绑定

时间:2015-11-17 15:28:43

标签: javascript jquery html knockout.js

所以基本上我有这个输入文本框:

 <input id="usersInputField" data-bind="hasFocus: isSearchInputFocused"/>

只要输入字段具有焦点,就会弹出一个表格:

<div data-bind="visible: isSearchInputFocused">
   <table>
       <tbody data-bind="foreach: usersFromSearch">
           <!-- some info -->
       </tbody>
   </table>
</div>

......效果很好。虽然,我希望表格保持可见,以防用户点击div。

而不是表绑定中的isSearchInputFocused observable,我尝试使用ko.computed observable,如果文本框或用户表被聚焦并添加了hasFocus绑定,则返回true在它上面,但这似乎不起作用。我假设hasFocus绑定优先于click绑定。

当表格或输入具有焦点时,如何保持div打开?

3 个答案:

答案 0 :(得分:2)

默认情况下,表格不可聚焦,因此您的第一个想法将无效。但是,如果添加tabindex属性,则可以安全地将焦点设置在表格上。因此,如果你这样做,你可以为每个元素使用焦点可观察,并使用一个计算器来确定它们中的任何一个是否被聚焦以保持div可见。

var vm = {
  inputHasFocus: ko.observable(),
  tableHasFocus: ko.observable(),
};

// Don't take completing a model like this as a good practice:
vm.somethingHasFocus = ko.pureComputed(function() {
  var inputHasFocus = vm.inputHasFocus(); // ensures subscription
  var tableHasFocus = vm.tableHasFocus(); // ensures subscription
  return  inputHasFocus || tableHasFocus;
}, vm);

ko.applyBindings(vm);

// IE Hack
$('table *').on('click', function() { vm.tablehasFocus(true); })
table {
  border: solid 1px black;
  border-collapse: true;
  width: 80%;
  margin: 20px 0;
}

*:focus {
  border-color: #FF0000;
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(255, 0, 0, 0.6);
  outline: none;
}

div {
  background-color: silver;
  margin: 20px 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<input tabindex="0" type="text" data-bind="hasFocus: inputHasFocus"/>


<table tabindex="1" data-bind="hasFocus: tableHasFocus">
  <tr>
    <td>I'm a table cell</td>
    <td>I'm another</td>
  <tr>
</table>

<div data-bind='visible: inputHasFocus'>Input has focus</div>
<div data-bind='visible: tableHasFocus'>Table has focus</div>
<div data-bind='visible: somethingHasFocus'>Something has focus</div>

注意:像往常一样,IE有一个奇怪的行为:至少IE10允许专注于表格单元格。脚本中包含的解决方案是黑客攻击。有更聪明的选择:

  • 创建自定义绑定elementOrDescendantHasFocus,这应该不会太困难:您可以使用委派事件处理来检测表或子项中的焦点事件
  • 为每个表格单元格创建一个hasFocus数组,并根据它们计算所有的计算结果(我宁愿实现黑客攻击)
  • 通过向其添加否定tabindex属性使细胞无法聚焦

因此,如果您必须支持IE(至少IE10),请选择其中任何一种解决方案,包括黑客攻击。在Chrome和Firefox中没有这样的问题

答案 1 :(得分:1)

idk如果你想这样做,但是你可以这样做,这样桌子就会在输入焦点上打开并保持打开状态直到你关闭它。

&#13;
&#13;
// Here's my data model
var ViewModel = function() {
    var self = this;
    
    self.focusMePlease = ko.observable(false);
    self.focusMePlease.subscribe(function() {
    	if (self.focusMePlease() == true) {
        	self.isSearchInputFocused(true);
        }
    });
    self.isSearchInputFocused = ko.observable(false);
    
    self.close = function() {
    	self.isSearchInputFocused(false);
    };
    
};
 
ko.applyBindings(new ViewModel());
&#13;
td {
    border: 1px solid black;
    padding: 5px;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script><input id="usersInputField" data-bind="hasFocus: focusMePlease"/>
<br/><br/>
<div data-bind="visible: isSearchInputFocused">
   <table>
       <tr><td>stuff</td><td>stuff</td></tr>
   </table>
    <button data-bind="click: close">X</button>
</div>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

也许你可以使用焦点事件解决这个问题,比如以下例子:

http://jsbin.com/jewozilofe/edit?html,js,output