Jquery 最近的 tr 失败,为什么?

Jquery closest tr from this fails, why?

Jquery 不是我的强项。这在逻辑上似乎是正确的,尽管它不起作用。我搜索了从 find、closest、this 等所有内容。我不明白为什么这不起作用。

我想做的是在单击 this <span> 时向最近的 tr 添加一个 class。

我没有收到任何错误,但也没有收到任何结果。

代码:

$curTable .= "
    <tr bgcolor='#f2e2f2' onmouseover=style.backgroundColor='#FFFFFF'; onmouseout=style.backgroundColor='#f2e2f2';>
        <td>$typeSelect</td>
        <td>$cfilename</td>
        <td><input type='text' size='20' name='cexpDate' class='dp exp' value='$cexpDate' /><script type='text/javascript'>$('.dp').datetimepicker({format:'m/d/Y'});</script></td>
        <td>$catSelect</td>
        <td>$cdateAdded</td>
        <td>$caddedBy</td>
        <td><span class='mod' onclick=\"deleteFile('{$cid}','{$cfilename2}');\">delete</span> | <span class='mod' onclick='modFile($cid)'>modify</span></td>
    </tr>";

Jquery:

function deleteFile(fileId,fileName){
    var fileId = fileId;
    var fileName = fileName;
    var test = this;
    //alert(test);
    $(this).closest('tr').addClass("highlight");
    $('#submit').prop('disabled', true);
    $('#rmDeleteOverlay').fadeIn();
    $('#deleteFile').append("<br><br><center>"+fileName+"</center>");
}

CSS:

.highlight{
    background-color:#000;
}

感谢任何帮助。

function deleteFile(fileId,fileName){
 var fileId = fileId;
 var fileName = fileName;
 var test = this;
 //alert(test);
 $(this).closest('tr').addClass("highlight");
 $('#submit').prop('disabled', true);
 $('#rmDeleteOverlay').fadeIn();
 $('#deleteFile').append("<br><br><center>"+fileName+"</center>");
}
.highlight{
 background-color:#000;
 
}
.mod{
 cursor:pointer;
 color:#a45127;
}
.mod:hover{
 cursor:pointer;
 text-decoration: underline;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<tr bgcolor='#f2e2f2' onmouseover=style.backgroundColor='#FFFFFF'; onmouseout=style.backgroundColor='#f2e2f2';>
   <td><select name='type'><option value='spec'>SPEC</option><option selected value='clg'>CLG</option><option value='coa'>COA</option><option value='gmo'>GMO</option><option value='allergen'>ALLERGEN</option><option value='audit'>AUDIT</option><option value='cor'>COR</option><option value='organic'>ORGANIC</option><option value='kosher'>KOSHER</option><option value='oth'>OTHER</option></select></td>
   <td><a href='/uploads/rm/46/46_clg_20190620223443.pdf' target='_blank'>46_clg_20190620223443.pdf</a></td>
   
   <td><select name='cat'><option selected value='cur'>Current</option><option value='oth'>Other</option><option value='arc'>Archive</option></select></td>
   <td>2019-06-20 22:34:43</td>
   <td><a href='editUser.php?id=11'>11</a></td>
   <td><span class='mod' onclick="deleteFile('1','<a href=\'/uploads/rm/46/46_clg_20190620223443.pdf\' target=\'_blank\'>46_clg_20190620223443.pdf</a>');">delete</span> | <span class='mod' onclick='modFile(1)'>modify</span></td>
  </tr>

当您调用像 onclick="deleteFile('{$cid}','{$cfilename2}'); 这样的函数时,它不会将 this 设置为函数中的元素。您需要显式传递元素,如 onclick="deleteFile(this,'{$cid}','{$cfilename2}');.

您也没有看到 highlight class 的样式变化,因为 style="background-color: #f2e2f2" 优先。我将其移至 CSS 并使 .highlight 的样式更加具体。另外,在 CSS 中使用 :hover 而不是 onmouseover.

function deleteFile(element, fileId, fileName) {
  $(element).closest('tr').addClass("highlight");
  $('#submit').prop('disabled', true);
  $('#rmDeleteOverlay').fadeIn();
  $('#deleteFile').append("<br><br><center>" + fileName + "</center>");
}
tr {
  background-color: #f2e2f2;
}

tr:hover {
  background-color: #FFFFFF;
}

tr.highlight {
  background-color: #000;
}

.mod {
  cursor: pointer;
  color: #a45127;
}

.mod:hover {
  cursor: pointer;
  text-decoration: underline;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tr>
    <td>
      <select name='type'>
        <option value='spec'>SPEC</option>
        <option selected value='clg'>CLG</option>
        <option value='coa'>COA</option>
        <option value='gmo'>GMO</option>
        <option value='allergen'>ALLERGEN</option>
        <option value='audit'>AUDIT</option>
        <option value='cor'>COR</option>
        <option value='organic'>ORGANIC</option>
        <option value='kosher'>KOSHER</option>
        <option value='oth'>OTHER</option>
      </select>
    </td>
    <td><a href='/uploads/rm/46/46_clg_20190620223443.pdf' target='_blank'>46_clg_20190620223443.pdf</a></td>

    <td>
      <select name='cat'>
        <option selected value='cur'>Current</option>
        <option value='oth'>Other</option>
        <option value='arc'>Archive</option>
      </select>
    </td>
    <td>2019-06-20 22:34:43</td>
    <td><a href='editUser.php?id=11'>11</a></td>
    <td><span class='mod' onclick="deleteFile(this, '1','<a href=\'/uploads/rm/46/46_clg_20190620223443.pdf\' target=\'_blank\'>46_clg_20190620223443.pdf</a>');">delete</span> | <span class='mod' onclick='modFile(1)'>modify</span></td>
  </tr>
</table>

也不需要

var fileId = fileId;

函数参数已经是局部变量,您不需要re-declare它们。

为了证明@Barmar 已经说过的内容,这里是代码证明:

function foo(context) {
  context.closest('div').style.backgroundColor = 'yellow';
}
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Possimus omnis et dolorem nobis?
  <button onclick="foo()">click me</button> Harum, aspernatur molestias at asperiores veniam sit pariatur aut animi, dignissimos consequatur quam quo earum dolor quod?</div>

<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Possimus omnis et dolorem nobis?
  <button onclick="foo(this)">click me, this time passing context</button> Harum, aspernatur molestias at asperiores veniam sit pariatur aut animi, dignissimos consequatur quam quo earum dolor quod?</div>

如果你想使用 this,你需要使用 addEventListener(无论如何你应该这样做,内联事件侦听器 非常糟糕 :

function foo() {
  this.closest('div').style.backgroundColor = 'yellow';
}

baz.addEventListener('click', foo);
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Possimus omnis et dolorem nobis?
  <button id="baz">click me</button> Harum, aspernatur molestias at asperiores veniam sit pariatur aut animi, dignissimos consequatur quam quo earum dolor quod?</div>

不确定这是否是问题所在,但在 JSFiddle(以及其他地方,您可能必须将 tr 包含在 table 标签中。这对我来说似乎是个问题。

<!DOCTYPE html>
<html>
<table>
<tr id = "rowelement">
  <td><select name='type'>
  <option value='spec'>SPEC</option>
  <option selected value='clg'>CLG</option>
  <option value='coa'>COA</option>
  <option value='gmo'>GMO</option>
  <option value='allergen'>ALLERGEN</option>
  <option value='audit'>AUDIT</option>
  <option value='cor'>COR</option>
  <option value='organic'>ORGANIC</option>
  <option value='kosher'>KOSHER</option>
  <option value='oth'>OTHER</option>
  </select>
  </td>
    <td><a href='/uploads/rm/46/46_clg_20190620223443.pdf' target='_blank'>46_clg_20190620223443.pdf</a></td>

<td>
<select name='cat'>
<option selected value='cur'>Current</option>
<option value='oth'>Other</option>
<option value='arc'>Archive</option>
</select>
</td>

<td>2019-06-20 22:34:43</td>
<td><a href='editUser.php?id=11'>11</a></td>
<td><span id ="delete" class='mod' data-file = "1" data-filepath = "/uploads/rm/46/46_clg_20190620223443.pdf">delete</span> | <span id ="mod" class='mod' onclick='modFile($cid)'>modify</span>
</td>
</tr>
</table>
</html>

不确定 JS 是否适合您,但是如果您可以将函数的参数放在数据属性中,那将是一种方法。

$("#rowelement").on("mouseover", function(e) {
    $(this).css("background", "#FFFFFF");
});
$("#rowelement").on("mouseout", function(e) {
    $(this).css("background", "#f2e2f2");
});

$("#delete").on("click", function(e) {
e.preventDefault();
    var fileId = $(this).data("file");
    var fileName = $(this).data("filepath");
    $(this).closest('tr').addClass("highlight");
    // ??? $('#submit').prop('disabled', true);
    // ??? $('#rmDeleteOverlay').fadeIn();
    // ???$('#deleteFile').append("<br><br><center>"+fileName+"</center>");
});

CSS

.highlight{
    background-color: #000 !important;
}
.mod{
    cursor: pointer;
    color: #a45127;
}
.mod:hover{
    cursor: pointer;
    text-decoration: underline;
}
#rowelement {
  background: #f2e2f2;
}

感谢大家提供的所有信息!特别是@Barmar & @sscotti

事实证明问题是 3 倍。

  1. 将元素信息传递给函数并使用this。当调用点击事件背后的函数时 onClick="deleteFile()" 我试图让函数引用被点击的元素并且无知地假设元素信息是自动传递的。 @Barmar 指出我需要在函数调用中包含 this 作为参数。

  2. 我最初在 <tr> 中为 onMouse* 事件使用的语法不正确。我正在使用 onMouseOver=style.backgroundColor='#FFFFFF'; 这破坏了 <tr> 标签。我应该在 jsFiddle 中注意到这一点,但我没有。感谢@sscotti 指出这一点。该行应该是 onMouseOver="style.backgroundColor='#FFFFFF';" 并且与 onMouseOut.

  3. 类似
  4. 基于@Barmar 的进一步研究提到内联样式覆盖 CSS 导致我 CSS 特异性。特异性是具有点系统的基本浏览器规则。胜利者将是得分最多的人。行内样式=1000,id=100,class=10,元素=1.

使用onMouse*事件改变风格等于1000分。我试图通过发出一个价值 10 分的 addClass() 来更改我的函数中的相同样式。内联样式声明胜过该调用,因此 class 被忽略。

通过从 <tr> 中删除内联 onMouse* 样式声明并将它们移动到 css class 中,它们的价值从 1000 分降为 10 分。由于它们现在与 addClass() 的值相同,因此使用了另一个基本的浏览器规则。当点匹配时,最后获胜。

感谢所有贡献并帮助我找到答案的人。是的,我知道我的一些脚本是陈旧和简陋的。完美是人类的妖怪,IMO 它不存在。我以功能为先,形式为先,但我喜欢改进自己的做法。

希望这对某人有所帮助。