【问题标题】:Table Cell color highlight and un-highlight on select jQuery选择 jQuery 的表格单元格颜色突出显示和取消突出显示
【发布时间】:2018-03-12 14:13:10
【问题描述】:

我设计了一个表格日历,在表格主体下有一堆 TD / TR 元素。

我希望在表格的每一天都进行交互,例如当我单击一个 td 元素(即一天)时,它将用边框突出显示,当我移动光标并单击其他一天时,这一天将突出显示,前一天将突出显示不突出。我的代码是这样的,但问题是 .off 点击功能。它不是取消突出显示,因此所有表格单元格都会突出显示并保留。我如何使用 jQuery 来解决这个问题?

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>

    $(document).ready(function(){

 $("td.PTDC").on("click",function(){  

  $(this).css("background-color", "#0093e0");
  $(this).css("padding", "5px");
  console.log("onclick");
    }); 

 $("tbody").off("click",function(){  
  $(this).css("background-color", "#ffffff");
  $(this).css("padding", "0px");
  console.log("offclick");
    }); 
});

    </script>

============================= 我在源代码中观察到在点击之前它有:

<td class="PTDC PTLC OOCT" id="db_saw_1883_7_1_6" style="border-style:none;border-right:solid 1px #DADADB;border-bottom:solid 1px #DADADB;">

点击后有:

<td class="PTDC OOCT" id="db_saw_1883_7_1_5" style="border-style: none solid solid none; border-right-width: 1px; border-right-color: rgb(218, 218, 219); border-bottom-width: 1px; border-bottom-color: rgb(218, 218, 219); background-color: rgb(0, 147, 224); padding: 5px;">

但由于我在日历中的所有 30 天就像每个 td 元素一天一样,因此当其他 td 元素单击时很难解除格式的关联。

【问题讨论】:

  • .off() 方法会删除使用 .on() 附加的事件处理程序

标签: jquery html html-table cell highlight


【解决方案1】:
$(function(){
$("table tr td").on("click",function(){
    $("td").removeClass("active");
    $(this).addClass("active");
})

})


//CSS

td.active{
  background: blue;
  color: #fff;
}

工作小提琴https://jsfiddle.net/o2gxgz9r/15797/ 您只需要从每个 td 中删除活动类,然后添加当前单击的 td。

【讨论】:

  • 您的解决方案非常好,这是我正在尝试的,我发现其他用户在此之前提供了相同的解决方案:但不知何故它不适合我。我的问题是,我在现有工具生成的代码之上编写的代码肯定会以某种方式被工具代码覆盖...但是感谢您对双重确认的回复,这是最简单的方法...谢谢! stackoverflow.com/questions/30072039/…
  • 感谢您的赞赏。继续编码:)
  • 实际上我正在尝试操作工具生成的代码,因此下面的代码可以正常工作...不幸的是,我无法使用您的代码从类中引用并打开和关闭...基本上现有的工具代码不喜欢它:我得到的唯一问题是:当我单击其他单元格时,它不会删除以前的单元格颜色:是否有任何其他使用 css 的解决方法,如果我遗漏了什么:$(document).ready(function() { $("td.PTDC").on("click", function() { $( this ).css({ "background-color": "#0093e0", "border": "10px" }); }) ;
  • @pauldx 我已经为您发布了另一个答案。请检查一下。
【解决方案2】:

更新 2

OP 正在使用类样式无法覆盖的原始应用程序。我从有关工具的各种线索中推断出(OP 含糊不清): = 生成...HTML 表格 - 它使用内联样式 - 如果是这样,那么这将解释为什么使用类进行样式设计非常困难。 - 内联样式(例如 &lt;div style='color:blue'&gt;)不能被样式表中的规则集覆盖,甚至不能被 &lt;style&gt; 块覆盖,!important 是例外。 Demo 3将演示两种处理内联样式属性的方法。

$('td').on('click', function(e) {
  var tgt = e.target;
  e.stopImmediatePropagation();
  $('td').each(function(idx, cell) {
    cell.style.backgroundColor = '#fff';
    cell.style.borderColor = '#000';
    if ($(cell).hasClass('today')) {
      cell.style.backgroundColor = 'rgba(0, 0, 255, 1)';
      cell.style.borderColor = '#aae1ff';
    }
  });
  tgt.style.backgroundColor = '#0093e0';
  tgt.style.borderColor = '#09e';
});
  1. e.target 是用户点击的&lt;td&gt;
  2. e.stopImmediatePropagation(); 防止事件冒泡并被任何其他侦听器听到。
  3. $('td').each(function(idx, cell) {... 每个&lt;td&gt; 都会运行一个函数。
  4. 每个单元格(即&lt;td&gt;)都将其内联样式属性设置为:

     cell.style.backgroundColor = '#fff';
    
     cell.style.borderColor = '#000';
    
  5. 如果此特定单元格具有.today 类,则:

    if ($(cell).hasClass('today')) {
      cell.style.backgroundColor = 'rgba(0, 0, 255, 1)';
      cell.style.borderColor = '#aae1ff';
    }
    
  6. for 循环完成后,更改e.target 样式:

     tgt.style.backgroundColor = '#0093e0';
    
     tgt.style.borderColor = '#09e';
    


更新 1

我误解了这个问题:OP 的期望行为是一次只有一个单元格可以拥有 .lit 类。使用.addClass().removeClass().not() 可以轻松修改。请参阅演示 2。

/* Delegate the click event on all
|| td (cell).
|| Remove the .lit class on every <td>
|| and add .lit class for the clicked <td>
*/
$('td').on('click', function() {
    var that = $(this);
  $('td').not(that).removeClass('lit');
    that.addClass('lit');
});

问题

"...但问题是 .off 的点击功能。它不会取消突出显示,因此所有表格单元格都会突出显示并持续存在。如何使用 jQuery 解决此问题?"

OP 提到的行为称为切换,它是在 2 个 “状态” 之间来回切换的能力(例如,状态处于 offon,或 lightdark 等)。在这种情况下,它是 2 个背景的切换。

.on() 方法是一个添加事件监听器的函数on 任何给定的个人或元素组(例如$('td'))。

.off() 方法是一个删除任何给定单个或一组元素的事件侦听器关闭 的函数。 .off() 不会撤消 .on() 所做的任何事情,.off() 删除 .on()。所以每次点击&lt;td&gt; 都会丢失注册到它的事件监听器。


解决方案

  1. 避免使用.css() 方法来设置一组元素的样式
  2. 操作类的效率要高得多。在这个演示中.lit 是另一个状态,默认状态是&lt;td&gt; 没有类.lit
  3. .toggleClass() 是用于执行此操作的方法。

以下演示中的主要功能解决了 OP 解释的问题。 作为奖励,我添加了以下功能:

  • 今天的单元格亮点
  • 为每月的每一天生成一个数字

详情在demo中注释

演示 1(切换类)

// Make a Date Object
var d = new Date();
// Get today's day as a number
var today = d.getDate();

/* Find the cell at the index number 
|| (which is eq -1) and add thr .today class
*/
$('td').eq(today - 1).addClass('today');

/* On each cell, add the day number, unless
|| the cell has class .empty
*/ // Note: the syntax of string on line 19
// is ES6 Template Literal see post for ref.
$('td').each(function(index, day) {
  if ($(this).hasClass('empty')) {
    return
  }
  $(this).append(`<b>${index+1}</b>`);
});

/* Delegate the click event on all
|| td (cell).
|| callback on each td is to 
|| toggle the .lit class
*/
$('td').on('click', function() {
  $(this).toggleClass('lit');
});
.month {
  table-layout: fixed;
  width: 90%;
  min-height: 250px;
  border-spacing: 1px;
  border: 3px outset grey
}

caption {
  font-variant: small-caps
}

.month td {
  border: 2px inset black;
  background: #fff;
  cursor: pointer;
}

td.lit {
  background-color: #0093e0;
  border-color: #09e;
}

td.today {
  background: rgba(0, 0, 255, 1);
  border-color: #aae1ff;
}

td.today.lit {
  background: tomato;
  border-color: red
}

td b {
  font-size: .3em;
  color: #123;
  vertical-align: top;
  display: inline-block;
  margin: -7px 0 0 -5px;
}

td.today b {
  color: #fff
}

.empty {
  /* Prevents any mouse events 
|| i.e unclickable
*/
  pointer-events: none;
  cursor: default;
}
<table class='month'>
  <caption>October</caption>
  <thead>
    <tr>
      <th>SUN</th>
      <th>MON</th>
      <th>TUE</th>
      <th>WED</th>
      <th>THU</th>
      <th>FRI</th>
      <th>SAT</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td class='empty' colspan='4'>&nbsp;</td>
    </tr>
  </tbody>
</table>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

Demo 2(专属类)

// Make a Date Object
var d = new Date();
// Get today's day as a number
var today = d.getDate();

/* Find the cell at the index number 
|| (which is eq -1) and add thr .today class
*/
$('td').eq(today - 1).addClass('today');

/* On each cell, add the day number, unless
|| the cell has class .empty
*/// Note: the syntax of string on line 19
// is ES6 Template Literal see post for ref.
$('td').each(function(index, day) {
  if ($(this).hasClass('empty')) {
    return
  }
  $(this).append(`<b>${index+1}</b>`);
});

/* Delegate the click event on all
|| td (cell).
|| Remove the .lit class on every <td>
|| and add .lit class for the clicked <td>
*/
$('td').on('click', function() {
	var that = $(this);
  $('td').not(that).removeClass('lit');
	that.addClass('lit');
});
.month {
  table-layout: fixed;
  width: 90%;
  min-height: 250px;
  border-spacing: 1px;
  border: 3px outset grey
}

caption {
  font-variant: small-caps
}

.month td {
  border: 2px inset black;
  background: #fff;
  cursor: pointer;
}

td.lit {
  background-color: #0093e0;
  border-color: #09e;
}

td.today {
  background: rgba(0, 0, 255, 1);
  border-color: #aae1ff;
}

td.today.lit {
  background: tomato;
  border-color: red
}

td b {
  font-size: .3em;
  color: #123;
  vertical-align: top;
  display: inline-block;
  margin: -7px 0 0 -5px;
}

td.today b {
  color: #fff
}

.empty {
/* Prevents any mouse events 
|| i.e unclickable
*/
  pointer-events: none;
  cursor: default;
}
<table class='month'>
  <caption>October</caption>
  <thead>
    <tr>
      <th>SUN</th>
      <th>MON</th>
      <th>TUE</th>
      <th>WED</th>
      <th>THU</th>
      <th>FRI</th>
      <th>SAT</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td class='empty' colspan='4'>&nbsp;</td>
    </tr>
  </tbody>
</table>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

演示3

// Make a Date Object
var d = new Date();
// Get today's day as a number
var today = d.getDate();

/* Find the cell at the index number 
|| (which is eq -1) and add thr .today class
*/
$('td').eq(today - 1).addClass('today');

/* On each cell, add the day number, unless
|| the cell has class .empty
*/ // Note: the syntax of string on line 19
// is ES6 Template Literal see post for ref.
$('td').each(function(index, day) {
  if ($(this).hasClass('empty')) {
    return
  }
  $(this).append(`<b>${index+1}</b>`);
});

/* Delegate the click event on all
|| td (cell).
|| See post update for details
|| 
*/
$('td').on('click', function(e) {
  var tgt = e.target;
  e.stopImmediatePropagation();
  $('td').each(function(idx, cell) {
    cell.style.backgroundColor = '#fff';
    cell.style.borderColor = '#000';
    if ($(cell).hasClass('today')) {
      cell.style.backgroundColor = 'rgba(0, 0, 255, 1)';
      cell.style.borderColor = '#aae1ff';
    }
  });
  tgt.style.backgroundColor = '#0093e0';
  tgt.style.borderColor = '#09e';
});
.month {
  table-layout: fixed;
  width: 90%;
  min-height: 250px;
  border-spacing: 1px;
  border: 3px outset grey
}

caption {
  font-variant: small-caps
}

.month td {
  border: 2px inset black;
  background: #fff;
  cursor: pointer;
}

td.lit {
  background-color: #0093e0;
  border-color: #09e;
}

td.today {
  background: rgba(0, 0, 255, 1);
  border-color: #aae1ff;
}

td.today.lit {
  background: tomato;
  border-color: red
}

td b {
  font-size: .3em;
  color: #123;
  vertical-align: top;
  display: inline-block;
  margin: -7px 0 0 -5px;
  background: rgba(0, 0, 0, 0);
  pointer-events: none;
}

td.today b {
  color: #fff
}

.empty {
  /* Prevents any mouse events 
|| i.e unclickable
*/
  pointer-events: none;
  cursor: default;
}
<table class='month'>
  <caption>October</caption>
  <thead>
    <tr>
      <th>SUN</th>
      <th>MON</th>
      <th>TUE</th>
      <th>WED</th>
      <th>THU</th>
      <th>FRI</th>
      <th>SAT</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td class='empty' colspan='4'>&nbsp;</td>
    </tr>
  </tbody>
</table>














<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

参考

时间 Date(), .getDate()

DOM 集合 .eq(), .each()

类操作 .toggleClass(), .addClass(), .removeClass(), .hasClass()

事件委托 .on(), .off()

杂项 .append(), ES6 Template Literals .not()

【讨论】:

  • 好吧@zer00ne。但这是我的问题。我仍然可以复制这里显示的内容,但是我希望它在我点击不同的日期时在每次点击时都保持蓝色,而不是每天都保持蓝色。基本上,当我点击 15th 时,它会突出显示,当我点击 20th 时,它应该为 15th 的白色背景,但 20th 的蓝色背景。所以我想我不想切换。此外,当我在所有其他日子都是白色的情况下单击第 15 天时,我希望突出显示第 15 天,当我一次又一次地单击第 15 天时,我希望它保持蓝色而不是白色。我很确定修改您的代码可以对此有所帮助。谢谢
  • @pauldx 如你所说的一个简单的修改,查看演示 2。
  • 实际上我正在尝试操作工具生成的代码,因此下面的代码可以正常工作...不幸的是,我无法使用您的代码从类中引用并打开和关闭...基本上现有的工具代码不喜欢它:我得到的唯一问题是:当我单击其他单元格时,它不会删除以前的单元格颜色:是否有任何其他使用 css 的解决方法,如果我遗漏了什么:$(document).ready(function() { $("td.PTDC").on("click", function() { $( this).css({ "background-color": "#0093e0", "border": "10px" }); }) ;
  • 我相信那句话看起来是正确的,除了可能使用"border-width" 什么工具?你是说控制台?
  • 你说的是今天吗?您所指的行为是否发生在堆栈 sn-p 中?这是我可以帮助你的唯一环境。您在我的代码中引入的任何其他因素都必须被视为可能的原因。我不知道您的环境的全部范围或知道涉及“工具”...非常模糊的信息¯\_(ツ)_/¯
【解决方案3】:
$(function() {
  $("table tr td.PTDC").on("click", function() {
    //This css will be applied across all table td's so make it specific
    $("table tr td").css({
      "background-color": "#fff",
      "border": "1px solid red"
    });
    $(this).css({
      "background-color": "#0093e0",
      "border": "1px solid red"
    });
  })
})

https://jsfiddle.net/o2gxgz9r/15797/

根据您的代码更新了小提琴。检查这是否满足。但是请确保我在通用表 tr td 上应用 CSS,所以要具体说明

【讨论】:

    猜你喜欢
    • 2011-04-12
    • 2014-01-18
    • 1970-01-01
    • 2015-11-24
    • 2013-05-17
    • 2014-02-21
    • 1970-01-01
    • 2020-03-08
    • 1970-01-01
    相关资源
    最近更新 更多