【问题标题】:How to highlight and get element of html element when mouse hover in vue鼠标悬停在vue中时如何突出显示和获取html元素的元素
【发布时间】:2022-01-06 00:24:10
【问题描述】:

这是一个简单的导航标题html,我使用vue用v-html显示它。

这是演示 - https://shuffle.dev/preview?project=12e60d2546392911632c3b5d1576766424f55da0&page=index.html&screen=main

<section class="text-gray-700 font-heading font-medium relative bg-gray-50 bg-opacity-50">
  <nav class="flex justify-between px-6 lg:px-12 py-8">
      .......
      .......
      <div class="mt-auto px-10">
        <button class="py-3 px-5 mt-6 w-full font-body font-bold uppercase tracking-wide text-sm border-2 border-gray-200 hover:border-gray-300 border-opacity-50 rounded-full">
          <span class="block mt-px">New project</span>
        </button>
      </div>
    </nav>
  </div>
</section>

我想要做的是将鼠标悬停在每个html元素上,例如&lt;svg&gt;&lt;button&gt;&lt;div&gt;,突出显示该元素并在控制台中输出html元素。

如意结果将类似于下图,在“新工具”文本上突出显示。

一个简单的解决方案是给所有元素一个类并添加鼠标悬停侦听器,但是它提出了一个问题,即对于具有父元素和子元素的复杂 html 元素,当鼠标悬停在子元素上时,父元素和子元素子元素会受到影响,如何只突出子元素而不突出父元素是我想弄清楚的。

【问题讨论】:

  • 这是一个重复的问题你可以找到更多信息here

标签: html vue.js


【解决方案1】:

您可以在按钮上添加eventListener。使用 CSS,您只能设置 span 子元素的样式。事件处理程序可以控制任何你想要的。

<!-- Use preprocessors via the lang attribute! e.g. <template lang="pug"> -->
<template>
  <div id="app">
    <section class="text-gray-700 font-heading font-medium relative bg-gray-50 bg-opacity-50">
      <nav class="flex justify-between px-6 lg:px-12 py-8">

          <div class="mt-auto px-10">
            <button class="py-3 px-5 mt-6 w-full font-body font-bold uppercase tracking-wide text-sm border-2 border-gray-200 hover:border-gray-300 border-opacity-50 rounded-full">
              <span class="highlight block mt-px">New project</span>
            </button>
            
            <button class="py-3 px-5 mt-6 w-full font-body font-bold uppercase tracking-wide text-sm border-2 border-gray-200 hover:border-gray-300 border-opacity-50 rounded-full">
              <span class="block mt-px">New tools</span>
            </button>            
          </div>
        </nav>
      
    </section>

  </div>
</template>

<script>
export default {
  data() {
    return {      
    };
  },
  methods: {

  },
  mounted() {
    //const btns = document.querySelectorAll('button');
    const btns = document.querySelectorAll('button');
    btns.forEach(b => {
      b.addEventListener('mouseover', (e) => {
        let span = e.target.children[0];        
        console.log('child Element from hovering button', span);
      })  
    })
    
    console.log(btns)
  }
};
</script>

<!-- Use preprocessors via the lang attribute! e.g. <style lang="scss"> -->
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

a,
button {
  color: #4fc08d;
}
button:hover .highlight {
    background: red;
}

button {
  background: none;
  border: solid 1px;
  border-radius: 2em;
  font: inherit;
  padding: 0.75em 2em;
}
</style>

【讨论】:

  • 首先我不仅尝试仅突出显示按钮,其次我使用 v-html 来呈现页面
【解决方案2】:

解决方案:

使用 Vue 组件的挂载钩子来获取动态 HTML 子树,然后为子树的合格节点元素添加 'Click' 事件处理程序以触发元素选择。

另外使用 mouseover 和 mouseout 事件处理程序来切换交互样式

第 1 步: 使用 v-html 使用 vue 组件设置项目

<div id="app">
  Create designs using Uinel
  <div id="interactivecanvas" v-html="dynamicHTML"></div>
  <div id="selectedElement">Selection: {{selectedElement.tagName}}</div>
</div>

第 2 步:添加 CSS 样式以指示可选元素

.selectable{ 
  box-shadow: 0 0 0 2px green;
}

第 3 步:添加挂载钩子以获取动态 HTML 子树

 mounted(){
  
    // List of selectable Elements. Uses css selector syntax
    let selectableElements = ['li', 'span', 'button']
    selectableElements[0] = '#interactivecanvas '+selectableElements[0]

    let canvasContents = document.querySelectorAll(selectableElements.join(',
     #interactivecanvas '))
  .....

第 4 步:遍历子树元素并添加用于选择的事件处理程序

mounted(){
...
 for(let i=0; i<canvasContents.length; i++){
...
  canvasContents[i].addEventListener('click',e=>{
    e.stopPropagation();
    this.selectElement(e)
  })
...
}

第 5 步: 可选!您可以添加 mouseover 和 mouseout 事件处理程序来切换交互式样式。

检查下面的示例。整页查看。

new Vue({
  el: '#app',
  data() {
    return {
      selectedElement: {},
      dynamicHTML: `
        <div class="header">
          <nav class="nav">
            <ul id="nav">
              <li>Home</li>
              <li>Contact Us</li>
              <li>About Us</li>
            </ul>
            <div id="card">
              <div id="usercard">
                <span>Sona</span>
                <span>&#x25BC;</span>
              </div>
              <button>New Project</button>
            </div>
          <nav>
        </div>
      `
    }
  },
  mounted(){
  
    // List of selectable Elements. Uses css selector syntax
    let selectableElements = ['li', 'span', 'button']
    selectableElements[0] = '#interactivecanvas '+selectableElements[0]

    let canvasContents = document.querySelectorAll(selectableElements.join(', #interactivecanvas '))
    for(let i=0; i<canvasContents.length; i++){
    
      // Add mouseover & mouseout event Handler to toggle styles
      canvasContents[i].addEventListener('mouseover',(e)=>{
        e.stopPropagation();
        e.currentTarget.classList.add("selectable")
      })
      canvasContents[i].addEventListener('mouseout',(e)=>{
        e.stopPropagation();
        e.currentTarget.classList.remove("selectable")
      })
      
      // Event to fire Selection action. Use 'hover' or 'click'
      canvasContents[i].addEventListener('click',e=>{
        e.stopPropagation();
        this.selectElement(e)
      })
    }
  },
  methods:{
    selectElement(e){
      console.log('Selected '+e.currentTarget)
      this.selectedElement = e.currentTarget
    }
  }
})
* {
  box-sizing: border-box;
}

body {
  font-family: 'Verdana'
}

ul {
  list-style: none;
}

.header {
  background: rgba(245,246,247);
  padding: 20px;
}

.nav {
  display: flex;
}

.nav > ul > li {
  display: inline;
  margin: 20px;
}

.nav button {
  border: 2px solid gray;
  border-radius: 9999px;
  padding: 12px 20px;
}

.nav #card {
  display: flex;
  align-items: center;
}

#usercard {
  margin: 20px;
  padding: 10px;
}

.selectable{ 
  box-shadow: 0 0 0 2px green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  Create designs using Uinel
  <div id="selectedElement">Selection: {{selectedElement.tagName}}</div>
  <div id="interactivecanvas" v-html="dynamicHTML"></div>
</div>

【讨论】:

    【解决方案3】:

    您可以使用 /deep/ 选择器来应用您的样式:

    <div class="description" v-if="description" v-html="description"></div>
    
    
    .description {
      /deep/ p {
        margin-bottom: 10px;
      }
    }
    

    【讨论】:

      【解决方案4】:

      你可以像这样创建一个highlighted 类:

      .highlighted { border: 1px dashed green; }

      然后将 2 个函数添加到您的组件中:

      highlight(event) {
         console.log(event.target);
         event.target.classList.add("highlighted");
      },
      removeHighlight(event) {
         event.target.classList.remove("highlighted");
      },
      

      并将这些属性添加到要突出显示的元素并输出到控制台:

      @mouseenter="highlight($event)" @mouseleave="removeHighlight($event)"

      【讨论】:

      • 谢谢,另外一个问题是我如何将这个 html sn-p 遍历到一个元素数组中并为每个元素添加类。我发现 var elementList = document.getElementsByTagName("*"); for(var i = 0; i
      • 将 @mouseenter="highlight($event)" 添加到 html 元素似乎不起作用,应该使用 addlistener 吗?
      • 也许我一开始不明白你想做什么。如果你通过 v-html 添加所有的 html,那么它的内容可能不会被 Vue 解析,所以是的,你需要添加一个常规的 javascript 事件监听器。
      • 关于您的第一个问题,您正在使用一个选择器来获取页面中的所有元素。您应该使用更具体的选择器。您可以使用 document.querySelectorAll("#your-desired-id *") 而不是 getElementsByTagName("*")
      • 你给的解决方案对我有问题,在html中有父元素和许多子元素,很多时候我只想突出显示子元素但似乎也可能突出其父元素我不会发生这种情况。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-11
      • 1970-01-01
      • 1970-01-01
      • 2017-08-05
      • 2017-02-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多