部分jQuery代码的奇怪行为

时间:2012-08-07 20:32:48

标签: javascript jquery

好的,让我们开始吧。

此代码在控制台中正常工作,从中执行所需操作。

$('#tasks-table input').parent().html($('#tasks-table input').siblings('textarea').val())

但是在这样的调用中它甚至都没有执行。控制台是沉默的。所有其他功能代码都正确执行

updateTask.call(this, 131)

任何想法?

更新

$('#tasks-table input').parent().html($('#tasks-table input').siblings('textarea').val())

是此

的一部分
updateTask.call(this, 131)

并在updateTask中被忽略 这条指令可以从控制台上运行得很好,但是当它是updateTask的一部分

时却没有

html是一个4行的php生成的表,其中包含一行典型的

<tr>
  <td><?php echo $task->id ?></td>
  <td onclick='projects.editTask.call(this, <?php echo $task->id ?>)'><?php echo $task->text ?> </td>
  <td><?php echo $task->status ?></td>
  <td><?php echo $task->controls ?></td>
</tr>

editTask是一个简单的替换函数(td的内容变成了textarea)

if(block || !($(this).attr('incomplete'))) return; //only one is allowed
block = true;
if(!$(this).children('textarea').length) {
   $(this).html('<textarea style="width: 100%; height: 110px;">'+$(this).html()+'</textarea><br/><input type="button" value="Сохранить" onclick="projects.updateTask.call(this, '+parseInt(id)+')" />');
} 

updateTask的目标是将td中的任何内容替换回textarea的内容,并使用$ .post将更新请求发送回服务器 updateTask的内容

var text = $(this).siblings('textarea').val();
//does not work only here, but works anywhere else
$('#tasks-table input').parent().text($('#tasks-table input').siblings('textarea').val())
$.post('/projects/ajax/', {
   ajax: true,
   command: 'update',
   id: id,
   text: text }
  , function() { 
     block = false; 
  }); 

当我采用更复杂的方式时,它有效。这个更简单的方式:

$(this).parent().html(text)

也不起作用

1 个答案:

答案 0 :(得分:0)

修改 重新审视你的问题,看起来我关注的重点可能不是问题。我不会删除它,因为它是您发布的代码的有效问题。 textarea值未被查询或修改的问题很可能是因为您在DOM加载后添加了textarea。您应该能够在桌面上使用jquery.live()事件或在本文末尾使用委托事件。两者都适用于任何当前或未来的DOM元素。在执行任何DOM操作或基于ajax的HTML更新时,这些都可以节省生命。这也可以解释为什么你能够在控制台而不是代码中执行操作。

原始回答: 我不确定这是否会完全有用,但我认为阻止代码执行的是:

if(block || !($(this).attr('incomplete'))) return;

当您的表格单元格没有该属性时,您实际上正在执行:

if( block || !(undefined) ) return;

由于!(undefined)为真,因此总是如此。你很可能想要强制一个布尔值:

if( block || !!(undefined) ) return;

如果您只期望undefined和任何文本值,那么这很好。修改此条件的更好方法是明确检查您期望的值(我假设您期望为“true”):

if(block || ($(this).attr('incomplete') === "true") ) return;

<强>建议:

我要做的一个建议是使用HTML5 data- *属性来存储数据并在一个地方执行代码,而不是内联onclick函数。这有助于将JavaScript保留在一个位置,并且不会在整个HTML中混合使用。

例如,您可以为每个表格单元格生成data-id属性,并使用data-edit-cell="true"

将表格行标记为可编辑
<table>
<tr data-edit-cell="true">
  <td data-id="1">cell one</td>
  <td data-id="2">cell two</td>
  <td data-id="3">cell three</td>
  <td data-id="4">cell four</td>
</tr>
</table>​

然后,第二个建议,而不是将click事件绑定到每个单元格,您可以使用jquery.delegate()将事件绑定到行,该here监视事件的冒泡事件(单击)由选择器( td )定义的子项:

var block = false;
$('tr[data-edit-cell=true]').delegate('td', 'click', function() {
    if (block || $(this).attr('incomplete') === "true" ) return; //only one is allowed
    block = true;
    console.log('clicked: ' + $(this).attr('data-id'));
});​

我已经创建了一个jsfiddle {{3}},因此您可以检查此代码。