我有一个使用flexbox的表,其中填充了d3.js.可以通过单击标题行对列进行排序. 我在其中一行中有一个 Select .当我单击收件箱时,我不希望对表进行排序.但如果我单击收件箱外部的标题行,我确实希望它进行排序.这可行吗?

data = [
      {
        "name": "Dave",
        "dept": "Marketing",
        "region": "South",
        "items": 28
      },
      {
        "name": "Amy",
        "dept": "IT",
        "region": "West",
        "items": 46
      },
      {
        "name": "John",
        "dept": "Sales",
        "region": "North",
        "items": 35
      },
      {
        "name": "Sarah",
        "dept": "Communications",
        "region": "North",
        "items": 13
      }
    ]

    drawTable(data)
    sortTable(data)

    function drawTable(data) {

      // not working
      // when redrawing table, trying to re-initialize sort function
      sortTable(data)

      d3.select('#data-table').remove()

      let table = d3.select('#table').append('div').attr('id', 'data-table')

      let row = table.selectAll('.row')
        .data(data)
        .enter()
        .append('div')
        .attr('class', 'row')

      let grid = row
        .append('div')
        .attr('class', 'grid')

      let name = grid.append('div')
        .attr('class', 'box')
        .html(d => d.name)

      let dept = grid.append('div')
        .attr('class', 'box')
        .html(d => d.dept)

      let state = grid.append('div')
        .attr('class', 'box')
        .html(d => d.region)

      let initiative = grid.append('div')
        .attr('class', 'box')
        .html(d => d.items)

    }

    function sortTable(data) {
      d3.selectAll(".name,.dept,.region,.items").on('click', function () {
        d3.select(this).classed("sortAsc", d3.select(this).classed("sortAsc") ? false : true);

        let sortClasses = d3.select(this).attr("class")
        let splitSortClasses = sortClasses.split(' ')
        let sortVar = splitSortClasses[2]

        if (sortClasses.includes('sortAsc')) {
          data.sort((a, b) => d3.ascending(a[sortVar], b[sortVar]))
        } else {
          data.sort((a, b) => d3.descending(a[sortVar], b[sortVar]))
        }

        drawTable(data)
      })
    }
.grid {
      display: flex;
      flex-wrap: wrap;
      flex-direction: row;
    }

    .grid>div {
      display: flex;
      flex-basis: calc(100%/4 - 28px);
      justify-content: center;
      flex-direction: column;
      padding: 10px;
    }

    .box {
      margin: 0;
    }

    .box {
      color: #000;
      border: .5px solid #ccc;
    }

    .hrbox {
      background-color: #ddd;
      color: #111;
      font-weight: bold;
      background-size: 1.5rem;
      background-repeat: no-repeat;
      background-position: center right;
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%234f4f4f' d='M16.29 14.29L12 18.59l-4.29-4.3a1 1 0 00-1.42 1.42l5 5a1 1 0 001.42 0l5-5a1 1 0 00-1.42-1.42zM7.71 9.71L12 5.41l4.29 4.3a1 1 0 001.42 0 1 1 0 000-1.42l-5-5a1 1 0 00-1.42 0l-5 5a1 1 0 001.42 1.42z'/%3E%3C/svg%3E");
      text-align: left !important;
    }

    .hrbox.sortAsc {
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%234f4f4f' d='M11.29 11.46a1 1 0 001.42 0l3-3A1 1 0 1014.29 7L12 9.34 9.71 7a1 1 0 10-1.42 1.46zm3 1.08L12 14.84l-2.29-2.3A1 1 0 008.29 14l3 3a1 1 0 001.42 0l3-3a1 1 0 00-1.42-1.42z'/%3E%3C/svg%3E");
    }

    .hrbox.sortDesc {
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%234f4f4f' d='M12.71 12.54a1 1 0 00-1.42 0l-3 3A1 1 0 009.71 17L12 14.66 14.29 17a1 1 0 001.42 0 1 1 0 000-1.42zm-3-1.08L12 9.16l2.29 2.3a1 1 0 001.42 0 1 1 0 000-1.42l-3-3a1 1 0 00-1.42 0l-3 3a1 1 0 001.42 1.42z'/%3E%3C/svg%3E");
    }

    #attr {
      width: 60px;
      margin-left: 20px;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.0.0/d3.min.js"></script>
<div id="table">
    <div class="grid">
      <div class="box hrbox name">
        <div style="display: flex;">
          <div>name</div>
          <select id="attr"></select>
        </div>
      </div>
      <div class="box hrbox dept">
        <div>dept</div>
      </div>
      <div class="box hrbox region">
        <div>region</div>
      </div>
      <div class="box hrbox items">
        <div>items</div>
      </div>
    </div>
    <div id="data-table"></div>
  </div>

推荐答案

data = [
      {
        "name": "Dave",
        "dept": "Marketing",
        "region": "South",
        "items": 28
      },
      {
        "name": "Amy",
        "dept": "IT",
        "region": "West",
        "items": 46
      },
      {
        "name": "John",
        "dept": "Sales",
        "region": "North",
        "items": 35
      },
      {
        "name": "Sarah",
        "dept": "Communications",
        "region": "North",
        "items": 13
      }
    ]

    drawTable(data)
    sortTable(data)

    // Let's prevent parent's onClick from firing
    d3.selectAll("#attr").on('click', function (e) { e.stopPropagation(); })

    function drawTable(data) {

      // not working
      // when redrawing table, trying to re-initialize sort function
      sortTable(data)

      d3.select('#data-table').remove()

      let table = d3.select('#table').append('div').attr('id', 'data-table')

      let row = table.selectAll('.row')
        .data(data)
        .enter()
        .append('div')
        .attr('class', 'row')

      let grid = row
        .append('div')
        .attr('class', 'grid')

      let name = grid.append('div')
        .attr('class', 'box')
        .html(d => d.name)

      let dept = grid.append('div')
        .attr('class', 'box')
        .html(d => d.dept)

      let state = grid.append('div')
        .attr('class', 'box')
        .html(d => d.region)

      let initiative = grid.append('div')
        .attr('class', 'box')
        .html(d => d.items)

    }

    function sortTable(data) {
      d3.selectAll(".name,.dept,.region,.items").on('click', function () {
        d3.select(this).classed("sortAsc", d3.select(this).classed("sortAsc") ? false : true);

        let sortClasses = d3.select(this).attr("class")
        let splitSortClasses = sortClasses.split(' ')
        let sortVar = splitSortClasses[2]

        if (sortClasses.includes('sortAsc')) {
          data.sort((a, b) => d3.ascending(a[sortVar], b[sortVar]))
        } else {
          data.sort((a, b) => d3.descending(a[sortVar], b[sortVar]))
        }

        drawTable(data)
      })
    }
.grid {
      display: flex;
      flex-wrap: wrap;
      flex-direction: row;
    }

    .grid>div {
      display: flex;
      flex-basis: calc(100%/4 - 28px);
      justify-content: center;
      flex-direction: column;
      padding: 10px;
    }

    .box {
      margin: 0;
    }

    .box {
      color: #000;
      border: .5px solid #ccc;
    }

    .hrbox {
      background-color: #ddd;
      color: #111;
      font-weight: bold;
      background-size: 1.5rem;
      background-repeat: no-repeat;
      background-position: center right;
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%234f4f4f' d='M16.29 14.29L12 18.59l-4.29-4.3a1 1 0 00-1.42 1.42l5 5a1 1 0 001.42 0l5-5a1 1 0 00-1.42-1.42zM7.71 9.71L12 5.41l4.29 4.3a1 1 0 001.42 0 1 1 0 000-1.42l-5-5a1 1 0 00-1.42 0l-5 5a1 1 0 001.42 1.42z'/%3E%3C/svg%3E");
      text-align: left !important;
    }

    .hrbox.sortAsc {
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%234f4f4f' d='M11.29 11.46a1 1 0 001.42 0l3-3A1 1 0 1014.29 7L12 9.34 9.71 7a1 1 0 10-1.42 1.46zm3 1.08L12 14.84l-2.29-2.3A1 1 0 008.29 14l3 3a1 1 0 001.42 0l3-3a1 1 0 00-1.42-1.42z'/%3E%3C/svg%3E");
    }

    .hrbox.sortDesc {
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%234f4f4f' d='M12.71 12.54a1 1 0 00-1.42 0l-3 3A1 1 0 009.71 17L12 14.66 14.29 17a1 1 0 001.42 0 1 1 0 000-1.42zm-3-1.08L12 9.16l2.29 2.3a1 1 0 001.42 0 1 1 0 000-1.42l-3-3a1 1 0 00-1.42 0l-3 3a1 1 0 001.42 1.42z'/%3E%3C/svg%3E");
    }

    #attr {
      width: 60px;
      margin-left: 20px;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.0.0/d3.min.js"></script>
<div id="table">
    <div class="grid">
      <div class="box hrbox name">
        <div style="display: flex;">
          <div>name</div>
          <select id="attr"></select>
        </div>
      </div>
      <div class="box hrbox dept">
        <div>dept</div>
      </div>
      <div class="box hrbox region">
        <div>region</div>
      </div>
      <div class="box hrbox items">
        <div>items</div>
      </div>
    </div>
    <div id="data-table"></div>
  </div>

由于select元素是div元素的一部分,因此onClick监听器也会触发父div元素的onClick.

More info here: How do I prevent a parent's onclick event from firing when a child anchor is clicked?

Javascript相关问答推荐

为什么剧作家在导航时会超时?

ChartJS:分组堆叠条形图渲染错误

当我使用jQuery时,我的图标显示为[对象对象]

Node.JS ws包中是否有Webocket的错误代码列表?

用户单击仅在JavaScript中传递一次以及其他行为

reaction useEffect KeyDown for each 条目配音输出

我的glb文件没有加载到我的three.js文件中

为什么getRecord()会因为与_logger相关的错误而失败?(使用Hedera SDK)

可以的.是否可以在不预编译的情况下使用嵌套 Select 器?

使用JavaScript单击上一个或下一个特定按钮创建卡滑动器以滑动单个卡

成帧器运动中的运动组件为何以收件箱开始?

模块与独立组件

单击子元素时关闭父元素(JS)

判断表格单元格中是否存在文本框

在vercel throws上部署带有gunjs的sveltekit应用无法找到模块./' lib/文本编码'

Angular 17—每当一个布尔变量变为真时触发循环轮询,只要它保持为真

第一项杀死下一项,直到数组长度在javascript中等于1

使用Document.Evaluate() Select 一个包含撇号的HTML元素

将基元传递给THEN处理程序

Node.js API-queryAll()中的MarkLogic数据移动