在jQuery中获取数据的替代方法,而不是重复使用parent()和next()?

时间:2015-05-12 12:21:53

标签: javascript jquery

我有一个任务列表数据的HTML表,我试图获取所有数据值,并在单击一行时将它们存储到对象。

我有一些HTML和下面的JavaScript演示,它们都在我需要的时候运行。

问题在于我知道jQuery部分的质量非常差,因为它会调用这样的东西......

$taskEl.parent().parent('td').next().next().next().text()

我觉得这些可以改进,但我不知道是怎么回事。大部分已经完成了我正在尝试清理的现有项目,而这一部分真的让我烦恼。

我很感激您可以通过其他方式获取数据吗?

或者,这是否是最有效的方式?

此外,如果需要添加新ID或数据属性,我还需要修改一些HTML。

JSFiddle演示 ...当您单击任务标题中的链接时,它会将其选择的值打印到DOM以用于演示目标...:DEMO

演示JavaScript从DOM任务列表中获取任务数据并使用它创建一个JS对象:

//Open Task Modal when a Task record is clicked in Task List
$('body').on('click', '.taskName', function() {


    // Set and Cache Task ID from clicked on Task Item
    var taskId = $(this).parent().parent().parent().dataAttr('task-id');

    var $taskEl = $(this);

    // Populate Task Data Object from DOM values
    taskDataObject = {
        //projectId: projectTaskModal.cache.projectId,
        taskId: taskId,
        taskName: $taskEl.text(),
        taskDescription: $taskEl.next('.description').text(),
        taskStatus: $taskEl.parent().parent('td').next().text(),
        taskPriority: $taskEl.parent().parent('td').next().next().text(),
        taskTags: $taskEl.parent().parent('td').next().next().next().text(),
        taskCreatedDate: $taskEl.parent().parent('td').next().next().next().next().text(),
        taskModifiedDate: $taskEl.parent().parent('td').next().next().next().next().next().text(),
        taskDueDate: $taskEl.parent().parent('td').next().next().next().next().next().next().text(),
    };

});

演示任务列表HTML

<span id="projectIdPlaceholder" data-project-id="1234"></span>

  <table>

  <!-- test task list record 1 -->
  <tr id="task-row-1414135033730" data-task-id="1414135033730">
    <td width="1%" class="task-checkbox">
      <div class="status_update status-checkbox-Not-Started" data-id="1414135033730" data-status="Not Started" id="1414135033730"></div>
    </td>

    <td width="59%" class="task-name">
      <div><span id="1414135033730-taskName" class="taskName strikethrough">Add a Plugin System similar to WordPress Action and Filter Hooks
        <span class="open-description-icon open-description-icon-close" title"toggle="" description="" view"="">+</span>
        </span>
        <div id="1414135033730-taskDescription" class="description" style="display: block;">Project module will Fire Events before and After key events and Plugins in a custom/modulename/plugins/ folder will load and be able to Listen for these Event Hooks and then run it;s own code before and after these actions are executed!</div>
      </div>
    </td>
    <td width="10%">
      <div id="1414135033730-status" class="Not Started status">                 Not Started</div>
    </td>
    <td width="10%">
      <div id="1414135033730-taskPriority" class="priority">Low</div>
    </td>
    <td width="10%">
      <div class="type">Other</div>
    </td>
    <td width="10%">
      <div id="1414135033730-createdDate" class="createdDate">2014-10-24 07:18:41</div>
    </td>
    <td width="10%">
      <div id="1414135033730-modifiedDate" class="modifiedDate">2014-10-24 07:18:41</div>
    </td>
    <td width="10%">
      <div id="1414135033730-dueDate" class="dueDate">None</div>
    </td>
  </tr>

  <!-- test task list record 2 -->
  <tr id="task-row-1414135033731" data-task-id="1414135033731">
    <td width="1%" class="task-checkbox">
      <div class="status_update status-checkbox-Completed" data-id="1414135033731" data-status="Completed" id="1414135033731"></div>
    </td>

    <td width="59%" class="task-name">
      <div>
        <span id="1414135033731-taskName" class="taskName">Testing Task Record Number 2
        <span class="open-description-icon open-description-icon-close" title"toggle="" description="" view"="">+</span>
        </span>
        <div id="1414135033731-taskDescription" class="description" style="display: block;">My project task description for demo testing task record number 2!</div>
      </div>
    </td>
    <td width="10%">
      <div id="1414135033731-status" class="Completed status">Completed</div>
    </td>
    <td width="10%">
      <div id="1414135033731-taskPriority" class="priority">High</div>
    </td>
    <td width="10%">
      <div class="type">Magento</div>
    </td>
    <td width="10%">
      <div id="1414135033731-createdDate" class="createdDate">2014-10-27 03:10:14</div>
    </td>
    <td width="10%">
      <div id="1414135033731-modifiedDate" class="modifiedDate">2014-10-27 03:22:24</div>
    </td>
    <td width="10%">
      <div id="1414135033731-dueDate" class="dueDate">06/21/2015</div>
    </td>
  </tr>
</table>

4 个答案:

答案 0 :(得分:3)

由于您有可用的任务ID且div都有ID,我会直接定位元素ID。在jQuery中,你可以越具体,越好。

$('body').on('click', '.taskName', function() {

    // Get the task (row) that will be used for running all the selections
    var taskid = $(this).closest("tr").dataAttr('task-id');
    var taskSel = "#" + taskid + "-";

    // Populate Task Data Object from DOM values
    taskDataObject = {

        taskId: taskid;,
        taskName: $(taskSel + "taskName").text(),
        taskDescription: $(taskSel + "taskDescription").text(),
        taskStatus: $(taskSel + "taskStatus").text(),
        taskPriority: $(taskSel + "taskPriority").text(),
        taskTags: $(taskSel + "taskTags").text(),
        taskCreatedDate: $(taskSel + "taskCreatedDate").text(),
        taskModifiedDate: $(taskSel + "taskModifiedDate").text(),
        taskDueDate: $(taskSel + "taskDueDate").text(),
    };
});

答案 1 :(得分:2)

您的不同值在divspan中,并带有描述性的类名,您可以使用find()选择它们,并在单击的行中选择它们的className。

这样的事情:

//Open Task Modal when a Task record is clicked in Task List
$('body').on('click', '.taskName', function() {

    // Get the task (row) that will be used for running all the selections
    $task = $(this).closest("tr");

    // Populate Task Data Object from DOM values
    taskDataObject = {
        //projectId: projectTaskModal.cache.projectId,
        taskId: $task.data('task-id'),
        taskName: $task.find(".taskName").text(),
        taskDescription: $task.find(".description").text(),
        taskStatus: $task.find(".status").text(),
        taskPriority: $task.find(".priority").text(),
        taskTags: $task.find(".type").text(),
        taskCreatedDate: $task.find(".createdDate").text(),
        taskModifiedDate: $task.find(".modifiedDate").text(),
        taskDueDate: $task.find(".dueDate").text()
    };

});

修改:为了保持一致,我将$(this).text()替换为$task.find(".taskName").text(),将$(this).next(".description").text()替换为$task.find(".description").text()。并删除了taskIdtaskEl,因为它们是多余的。

Edit2:将$(this).parent().parent().parent()替换为$(this).closest("tr")。这样,如果HTML结构将来发生变化(并且父项数量发生变化),仍然会选择任务行,代码应该没有问题。

答案 2 :(得分:0)

我建议您使用data-*属性来存储值并使用JavaScript动态构建对象,而不是手动选择每个元素,例如:

HTML:

<table id="table">
    <tr>
        <td data-name="taskName" data-value="Test">
            <div class="foo">Test</div>
        </td>
        <td data-name="taskDate" data-value="1439275213">
            <div class="foo">2014-10-24 07:18:41</div>
        </td>
    </tr>
</table>

JavaScript的:

var $nodes = $('#table').find('td[data-name]'); // find TDs with 'data-attr'
var attributes = {};
$nodes.each(function() { // generate object with all data-name/data-value pairs
    var $node = $(this);
    attributes[$node.attr('data-name')] = $node.attr('data-value');
});
console.log(attributes); // prints { taskName: "Test", taskDate: "1439275213" }

演示:http://jsfiddle.net/andunai/uu65ntks/

P上。 S.此方法还允许您显示与其值不同的值,例如,显示人类可读的日期,但将其序列化为unix时间戳。

答案 3 :(得分:0)

这里有各种选择,取决于你需要什么,

这个例子不是最快的,但是最好的表现是关闭的, 很好用的是从$ selectors重新加载DOM元素,这意味着处理DOM的并行事件将呈现相同的东西, 而不是$ this = $(this),重新选择你的dom元素,再次不是性能方面的最佳实践(在dom中搜索),仍然提供了比动态修改的html更好的结果。

您的电话:

$('body').on('click', '.taskName', function() {

    var taskId = $(this).attr('id').replace('-taskName', '');
    taskDataObject = {
        //projectId: projectTaskModal.cache.projectId,
        taskId: taskId,
        taskName: $(this).text(),
        taskDescription:$('[id="' + taskId + '-taskDescription"').text(),
        taskStatus:$('[id="' + taskId + '-status"').text(),
        taskPriority: $('[id="' + taskId + '-taskPriority"').text(),
        taskTags: "undefined please defeine corect atribute on div",
        taskCreatedDate: $('[id="' + taskId + '-createdDate"').text(),
        taskModifiedDate: $('[id="' + taskId + '-modifiedDate"').text(),
        taskDueDate: $('[id="' + taskId + '-dueDate"').text(),
    };

        deepTrim(taskDataObject);
        printObjectToDom(taskDataObject);
});

您可以在主要的父HTML上编写自定义选择器,类似于我的示例

var T_REX = $(this).parent().parent()... whatever;

var T_REX_CUBS = TREX.children();

var taskname = T_REX_CUBS[0].find("div.taskName").text();

或最简单的

var T_REX = $(this).closest('tr');

var taskid = T_REX.attr('data-task-id');

var taskname = T_REX.find("div.taskName").text();

现在最快的选择是保存主要父对象,而不是应用jquery自定义选择器,但如果表中的数据实时更改,则不建议这样做。