代码之家  ›  专栏  ›  技术社区  ›  Jeremy Walters Hill Hubery

Vue文本突出显示事件

  •  0
  • Jeremy Walters Hill Hubery  · 技术社区  · 7 年前

    我有一个 data table 包含可单击行。一切正常,我遇到了一个问题。如果我想突出显示行上的文本, click event 被触发。我发现唯一有帮助的是 .exact 修饰语。 希望在突出显示文本时忽略单击处理程序。但是 单击事件 仍被触发。

    我的问题 :是否可以在不触发单击事件的情况下突出显示项目上的文本。

    预期结果 使用 @click.exact 突出显示文本时不会激发单击事件

    实际结果 :突出显示文本时激发Click事件,事件使用 点击准确

    边注 :它设法突出显示文本,但一旦放开鼠标按钮,它就会触发单击事件。

    <v-data-table
        v-show="model.id && !editMode"
        :headers="bagHeaders"
        :items="bags"
        class="elevation-1"
        item-key="id"
        :loading="bagsStatus.loading"
        :pagination.sync="pagination"
        >
            <template slot="items" slot-scope="props">
                <tr @click.exact="onBagClick(props.item.id)">
                    <td class="text-xs-left" v-for="header in bagHeaders" :key="header.id">{{ formatColumn(header, props.item) }}</td>
                </tr>
            </template>
    </v-data-table>
    

    编辑 : 其他尝试 : @click.prevent 也不工作

    迄今为止最好的工作: https://codepen.io/anon/pen/YBNLLy

    1 回复  |  直到 7 年前
        1
  •  1
  •   Yom T.    7 年前

    好吧,试试看 @click.stop TD 停止事件传播到父tr的。

    由于要在特定条件下保留正常的行单击行为,因此可以添加一个方法来检查单击时是否进行了任何文本选择,并继续停止事件传播,否则调用 onBagClick() 父级的方法 TR :

    new Vue({
      el: '#app',
    
      methods: {
        onBagClick(id) {
          alert('Bag Click');
        },
    
        checkMouseAction(e) {
          const isTextHighlighting = window.getSelection().toString().trim() !== '';
    
          if (!isTextHighlighting) {
            e.target.parentElement.click();
    
            // Or call the this.onBagClick() instead
          }
        }
      }
    })
    table {
      border-collapse: collapse;
    }
    
    table td {
      border: 1px solid;
      padding: 10px;
    }
    
    table td:first-child {
      background-color: lavender;
    }
    
    table td:last-child {
      background-color: pink;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    
    <div id="app">
      <table>
        <tr @click="onBagClick">
          <td @click.stop="checkMouseAction">Selectable text. Left-click and drag these lines with your mouse.</td>
          <td>Hardly selectable text. An alert dialog will get in the way by popping up.</td>
        </tr>
      </table>
    </div>

    编辑

    上面的内容也可以,但实际上我找到了另一个明显的解决方法:在表格行级别上检查文本选择:

    工作演示

    new Vue({
      el: '#app',
      data() {
        return {
          headers: [
            {
              text: 'Dessert (100g serving)',
              align: 'left',
              sortable: false,
              value: 'name'
            }, 
            {
              text: 'Calories',
              value: 'calories'
            }, 
            {
              text: 'Fat (g)',
              value: 'fat'
            }, 
            {
              text: 'Carbs (g)',
              value: 'carbs'
            }, 
            {
              text: 'Protein (g)',
              value: 'protein'
            }, 
            {
              text: 'Iron (%)',
              value: 'iron'
            }
          ],
          desserts: [
            {
              name: 'Frozen Yogurt',
              calories: 159,
              fat: 6.0,
              carbs: 24,
              protein: 4.0,
              iron: '1%'
            }, 
            {
              name: 'Ice cream sandwich',
              calories: 237,
              fat: 9.0,
              carbs: 37,
              protein: 4.3,
              iron: '1%'
            }, 
            {
              name: 'Eclair',
              calories: 262,
              fat: 16.0,
              carbs: 23,
              protein: 6.0,
              iron: '7%'
            }, 
            {
              name: 'Cupcake',
              calories: 305,
              fat: 3.7,
              carbs: 67,
              protein: 4.3,
              iron: '8%'
            }, 
            {
              name: 'Gingerbread',
              calories: 356,
              fat: 16.0,
              carbs: 49,
              protein: 3.9,
              iron: '16%'
            }, 
            {
              name: 'Jelly bean',
              calories: 375,
              fat: 0.0,
              carbs: 94,
              protein: 0.0,
              iron: '0%'
            }, 
            {
              name: 'Lollipop',
              calories: 392,
              fat: 0.2,
              carbs: 98,
              protein: 0,
              iron: '2%'
            }, 
            {
              name: 'Honeycomb',
              calories: 408,
              fat: 3.2,
              carbs: 87,
              protein: 6.5,
              iron: '45%'
            }, 
            {
              name: 'Donut',
              calories: 452,
              fat: 25.0,
              carbs: 51,
              protein: 4.9,
              iron: '22%'
            }, 
            {
              name: 'KitKat',
              calories: 518,
              fat: 26.0,
              carbs: 65,
              protein: 7,
              iron: '6%'
            }
          ]
        }
      },
      methods: {
        onBagClick(id) {
          const isTextHighlighting = window.getSelection().toString().trim() !== '';
    
          if (!isTextHighlighting) {
            alert("Bag Click");
          }
        }
      }
    })
    @import url('https://fonts.googleapis.com/css?family=Roboto|Material+Icons');
    <link href="https://cdn.jsdelivr.net/npm/vuetify@1.4.4/dist/vuetify.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vuetify@1.4.4/dist/vuetify.min.js"></script>
    
    <div id="app">
      <v-app id="inspire">
        <v-data-table :headers="headers" :items="desserts" class="elevation-1">
          <template slot="items" slot-scope="props">
            <tr @click="onBagClick(props.item.id)"> 
              <td class="text-xs-left" 
                v-for="header in props.item" 
                :key="header.id">{{header}}</td>
            </tr>
          </template>
        </v-data-table>
      </v-app>
    </div>

    我在用 window.getSelection() 用于阅读所选文本。如果你想支持IE8(及以下),请看 this post 对于回退文本选择获取方法。

    推荐文章