找到合适的DOM元素

以下是我的模型:

            

和我的viewmodel:

 function TimeCardViewModel() { var self = this; self.teamMembers=ko.observableArray(); } function TeamMemberViewModel(data){ var self=this; self.days=ko.observableArray(); for (var i=0; i<7; i++) { self.days.push(new DayViewModel(...); } } function DayViewModel(shifts){ var self=this; self.shifts=ko.observableArray(); for (var i=0; i<shifts.length; i++) { self.shifts.push(new ShiftElementsViewModel(...); } } function ShiftElementsViewModel(a,b,c,d) { var self=this; self.startTime=ko.observable(a); self.endTime=ko.observable(b); } var timeCardViewModel=new TimeCardViewModel(); ko.applyBindings(timeCardViewModel); 

对于每个成员,我们(一周中的七天中的每一天)都有一些class次。 对于每个class次,我们都有成对的startTime-endTime输入。 就视觉结果而言,存在包括成员的每周轮class的行,并且可能是每个成员每天多次轮class的情况。 如果我们查看列,这些列包括某一天所有成员的所有class次。
我的问题是,只要在endTime的DOM元素上有blur事件,我就会想要垂直关注startTime的DOM元素。 例如,如果我们在星期一并且第一个成员有两个class次我想要关注第一个成员的第二个class次的startTime,当第一个class次的结束时间发生模糊,然后是第一个class次的开始时间在第二个成员的星期一,当第一个成员的第二个class次的结束时间发生模糊时。 周二等同样如何实现呢? 目前,光标正在水平移动。

这对你有用……

 jQuery(function($) { $('body').on("blur", "input[data-bind*='value: endTime']", function() { var $t = $(this), // Current input $td = $t.closest('td'), // Current input's parent td i = $td.find('input[data-bind*="value: endTime"]').index($t), // Index of current input = current shift index $target = $td.find('input[data-bind*="value: startTime"]').eq(i + 1); // Target is current shift + 1 if ($target.length) { $target.focus(); } }); }); 

我们的想法是将事件处理程序绑定到模糊包含value: endTime的每个输入的事件value: endTime data-bind属性中的value: endTime
如果这个处理程序,我们在白天找出endTime输入的索引,向它添加1并将具有该索引的startTime输入聚焦在同一个td(day)😉

由于元素在加载文档之后不存在(但是由knockout渲染),我们将处理程序绑定到body,用于input[data-bind*='value: endTime']选择的input[data-bind*='value: endTime']

在这里,我通过使用所有knockout向您展示其中一种方法。 它向您展示了如何实现您的逻辑,因为我没有您的数据样本,您可能需要根据您的数据对其进行修改

工作示例 : https : //jsfiddle.net/kyr6w2x3/48/

HTML:

 

JS:

 var data ={ teamMembers: [{ Name: "Member A", id:1, days: [{startTime: '8:00',endTime: "4:00" ,name:'Monday',parentId:1},{startTime: '8:00',endTime: "4:00",name:'Tuesday',parentId:1},{startTime: '8:00',endTime: "4:00",name:'Wednesday',parentId:1},{startTime: '8:00',endTime: "4:00",name:'Thursday',parentId:1},{startTime: '8:00',endTime: "4:00",name:'Friday',parentId:1},{startTime: '8:00',endTime: "4:00",name:'Saturday',parentId:1},{startTime: '8:00',endTime: "4:00",name:'Sunday',parentId:1}] }, { Name: "Member B", id:2, days: [{startTime: '8:00',endTime: "4:00" ,name:'Monday' ,parentId:2},{startTime: '8:00',endTime: "4:00",name:'Tuesday' ,parentId:2},{startTime: '8:00',endTime: "4:00",name:'Wednesday',parentId:2},{startTime: '8:00',endTime: "4:00",name:'Thursday',parentId:2},{startTime: '8:00',endTime: "4:00",name:'Friday',parentId:2},{startTime: '8:00',endTime: "4:00",name:'Saturday',parentId:2},{startTime: '8:00',endTime: "4:00",name:'Sunday',parentId:2}] }, { Name: "Member C", id:3, days: [{startTime: '8:00',endTime: "4:00" ,name:'Monday',parentId:3},{startTime: '8:00',endTime: "4:00",name:'Tuesday',parentId:3},{startTime: '8:00',endTime: "4:00",name:'Wednesday',parentId:3},{startTime: '8:00',endTime: "4:00",name:'Thursday',parentId:3},{startTime: '8:00',endTime: "4:00",name:'Friday',parentId:3},{startTime: '8:00',endTime: "4:00",name:'Saturday',parentId:3},{startTime: '8:00',endTime: "4:00",name:'Sunday',parentId:3}] },] } var memberViewModel = function(data) { var self = this ; self.days = ko.observableArray([]); self.name = ko.observable(data.Name); self.id = ko.observable(data.id); self.days($.map(data.days, function (item) { return new daysViewModel(item); })); } var daysViewModel = function (data){ var self = this ; self.getFocus = ko.observable(false); self.startTime = ko.observable(data.startTime); self.endTime = ko.observable(data.endTime); self.name = ko.observable(data.name) self.parentId = ko.observable(data.parentId); } function ViewModel() { var self = this; self.teamMembers = ko.observableArray([]); self.teamMembers($.map(data.teamMembers, function (item) { return new memberViewModel(item); })); self.endTimeBlur = function(data){ ko.utils.arrayFirst(self.teamMembers(), function (item,i) { if (item.id() == data.parentId() && self.teamMembers()[i+1] ) { //here you set getFocus to true to make next member 's monday gets focus self.teamMembers()[i+1].days()[0].getFocus(true); return; } }); } } ko.applyBindings(new ViewModel()); 

我的建议是使用计算的tabindex属性。

  • 在你的$root viewmodel中,我们将计算一个shift.startend observables数组,就像你希望它们在焦点方面一样。
  • 我们还将创建一个工厂方法,为每个 bind返回一个计算索引。
  • 每个输入都有一个attr: { 'tabindex': getTabIndex() }绑定,确保索引保持最新

此方法适用于使用Tab键在表单中导航的人员。 最重要的是; 既然您有一个已排序的输入可观察量的计算列表,您可以轻松绑定到事件以选择上一个/下一个。

这是一个例子:

 var Root = function() { this.members = ko.observableArray([]); for (var i = 0; i < 5; i += 1) { this.members.push(new Member()); } // Note: you could do this in less lines of code, but I wanted // to be extra transparent to show the structure of the data // transform. var orderedShiftInputs = ko.pureComputed(function() { // We want the days to be leading, so we create a // two-dimensional array: [[meber1day1, member2day1], [member1day2], etc] // Note: members _cannot_ skip days var mergedDays = []; this.members().forEach(function(member) { member.days().forEach(function(day, index) { if (!mergedDays[index]) { mergedDays[index] = []; } mergedDays[index] = mergedDays[index].concat(day); }); }); // We flatten the 2d-array of days to a list of shifts: // [member1day1shift1, member1day1shift2, member2day1shift1, etc] var mergedShifts = mergedDays.reduce(function(shifts, days) { var allShifts = days.reduce(function(all, day) { return all.concat(day.shifts()); }, []); return shifts.concat(allShifts); }, []); // We flatten the shifts into an array of start and end observables: // [member1day1shift1start, member1day1shift1end, etc.] return mergedShifts.reduce(function(inputs, shift) { return inputs.concat([shift.start, shift.end]); }, []); }, this); this.getTabIndex = function(data) { return ko.computed(function() { // Find the start or end data in our sorted array. // In this example, we can start with index 1. In your app, // there might be other input elements before the shifts... var START_TAB_INDEX = 1; return orderedShiftInputs().indexOf(data) + START_TAB_INDEX; }, this); }.bind(this); } var Member = function() { this.days = ko.observableArray([]); for (var i = 0; i < 2; i += 1) { this.days.push(new Day()); } } var Day = function() { this.shifts = ko.observableArray([]); for (var i = 0; i < 3; i += 1) { this.shifts.push(new Shift()); } } var Shift = function() { this.start = ko.observable(1); this.end = ko.observable(2); } ko.applyBindings(new Root()); 
 td { border: 1px solid black } input { display: inline; width: 30px; }