Как привязать события к необработанному (импортированному) html с помощью кода?

#javascript #vue.js

#javascript #vue.js

Вопрос:

Я импортирую html, содержащий SVG-код, и визуализирую его с помощью директивы v-html, но мне нужно привязать события щелчка к тегам a-html из этого файла, которые не являются частью моего шаблона.

  • Как мне получить все a-теги из этого импортированного файла?

  • И как мне привязать события к этим элементам без использования директивы v-on?

Шаблон

             <v-flex mt-2 px-0 xs6 
                    ref="map_svg"
                    v-html="mapHTML">
            </v-flex>
  

Фрагмент импортированного файла

 <svg>
  <g>
     <g>
        <a target="_blank" xlink:href="url to a subsite" >
            <!-- content path which shows a circle -->
         </a>
     </g>
     <g>
        <a target="_blank" xlink:href="url to a differnt subsite" >
            <!-- content path which shows a circle -->
         </a>
     </g>

     <!-- many more elements like shown on the top -->
  </g>
</svg>
  

Мне нужно было бы привязать событие click к этим a-тегам и удалить или перезаписать атрибут xlink: href, чтобы щелчок не открывал другую вкладку в браузере.

Редактировать

В итоге я сделал это следующим образом:

   mounted() {

    const that = this;
    const links = this.$el.querySelectorAll('#map_svg svg > g > g > a');

    links.forEach(el => {
      const url = el.getAttribute('xlink:href');
      if (url) {
        // el.addEventListener('click', that.stationClick(url));
        el.onclick = function (){
          that.stationClick(url);
        }
        el.removeAttribute('xlink:href');
      }
      el.removeAttribute('target');
    });
  },
  

Ответ №1:

Вы можете привязать события щелчка к этим элементам после загрузки вашего svg:

 export default {
  name: "App",
  data() {
    return {
      mapHTML: null
    };
  },
  methods: {
    async loadSvg() {
      // Here, you load your svg
      this.mapHTML = `
        <a href="https://google.fr" _target="blank">Google</a> 
      `;

      // You need to use $nextTick in order to wait for the DOM to be refreshed
      this.$nextTick(() => { 
        this.bindClicks() // You bind click events here
      })

    },
    bindClicks () {
      // You search for all the a tags in your svg_container
      this.$refs.map_svg.querySelectorAll('a').forEach(el => {
        el.removeAttribute('_target') // You remove the _target attribute
        el.addEventListener('click', this.handleClick) // You bind an event listener to the element
      })
    },
    handleClick (e) {
      // You handle the click like you would normally do
      e.preventDefault()
    }
  }
};
  

Комментарии:

1. Спасибо за ваш подробный ответ. <code> el.addEventListener()</code> по какой-то причине не сработал, пришлось использовать <code>el.onclick = function () { // … }</code> Интересно, почему?

Ответ №2:

Вы можете использовать ref заданный вами и обычный JS для привязки к тегам.

 this.$refs.map_svg.querySelectorAll('a').forEach(item => item.addEventListener('click', this.callback) )
  

Комментарии:

1. Ах да, по какой-то причине я думал, что должен vue.js способ сделать это, и я пропустил, что я мог бы использовать обычный JS для этого: D Спасибо