Реагировать appendChild на svg

Я новичок в React и сейчас работаю над интерактивной картой мира. Я использую встроенный svg. Я добавил немного css, поэтому, когда я наводил курсор на континенты, они преобразовывались: масштаб (1.1) Я понял, что какой-то континент находится сзади. При наведении на них они масштабируются, но выглядит это странно.

Здесь вы можете увидеть Европу, Азию и Африку без зависания.

Когда вы зависаете над Азией, вы можете видеть, что она увеличивается, но она находится позади Африки.

это из-за порядка рендеринга svg 1.1

3.3 Порядок рендеринга

Элементы во фрагменте документа SVG имеют неявный порядок отрисовки, с "окрашиванием" первых элементов фрагмента документа SVG первый. Последующие элементы красятся поверх окрашенных ранее элементы.

К сожалению, svg 1.1 не поддерживает z-index. Насколько мне известно, я вообще не изучал svg 2.0 (который будет поддерживать z-index).

поэтому я читал несколько тем о том, как можно было бы упорядочить континенты при наведении, чтобы зависший был впереди.

Я нашел Как вывести элементы svg на передний план

И начал пробовать делать это с React. Я использую событие onMouseEnter на пути, который вызывает функцию handleHover и передает событие, внутри функции я вызываю свойство parentElement для currentTarget и appendChild для currentTarget.

function MapComponent() {

  function handleHover(event) {
    event.currentTarget.parentElement.appendChild(event.currentTarget);
  }

  return (
    <svg version = "1.1" id = "World" viewBox = "0 0 1920 1080">
      <a href = "/Australia" title = "Australia" className = "nav-link">
        <path
          id = "Australia"
          onMouseEnter = {(event) => handleHover(event)}
          d = "..."
        />
      </a>
    </svg>
  );
}

Но это не работает, как ожидалось. При наведении на путь (континент) он все еще находится сзади.

Обновлено: при замене appendChild() на removeChild() континент исчезает при вводе мыши. Это говорит мне, что выбран правильный элемент.

Я тоже пробовал совсем по другому, как описано здесь(в первом примере). К сожалению, это тоже не работает.

  const [isHovered, setHovered] = useState(false);


  return (
    <svg version = "1.1" id = "World" viewBox = "0 0 1920 1080">
      <a href = "/Australia" title = "Australia" className = "nav-link">
        <path
          id = "Australia"
          onMouseEnter = {() => setHovered(true)}
          onMouseLeave = {() => setHovered(false)}
          d = "..."
        />
        {isHovered && (
          <path
            id = "Australia"
            onMouseEnter = {() => isHovered(true)}
            onMouseLeave = {() => isHovered(false)}
            d = "..."
          />
        )}

С вашим текущим кодом (1-й пример) вы копируете элемент, который вызывает дублирование идентификатора. Возьмите атрибуты вашей текущей цели и создайте с ними новый путь. Используйте уникальный идентификатор для нового пути, который вы используете в качестве селектора для применения вашей CSS-анимации. В целях тестирования вы можете использовать другой цвет для вновь созданного пути, чтобы увидеть, находится ли он поверх оригинала.

mirja-t 23.04.2023 10:48

Я не совсем понимаю причину, по которой вам нужно перемещать элементы в порядке, чтобы они анимировались при наведении.. но для вашего первого примера кажется, что вы добавляете дочерний элемент к элементу a (<a href = "/Australia"), у которого уже есть только один дочерний элемент, и вы должны присоединяться к корню

paulitto 23.04.2023 10:48

@paulitto это просто порядок путей в svg. при зависании остаются сзади. Я добавил несколько фотографий.

Louis Eiden 23.04.2023 11:16

Вы переопределяете путь внутри a, но это ничего не делает. Вам нужно добавитьChild к родительскому элементу.

Robert Longson 23.04.2023 11:23

Наконец-то у меня было время проверить это. @paulitto & @ Robert Longson Вы были совершенно правы, нужно было добавить к родительскому элементу элемент. Большое спасибо!

Louis Eiden 23.04.2023 15:06
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
5
86
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

это работает благодаря @paulitto и @Robert Longson

Мне просто нужно было скопировать прослушиватель событий onMouseEnter в элемент a.

вот рабочий код:

function MapComponent() {

  function handleHover(event) {
    event.currentTarget.parentElement.appendChild(event.currentTarget);
  }

  return (
    <svg version = "1.1" id = "World" viewBox = "0 0 1920 1080">
      <a href = "/Australia" title = "Australia" className = "nav-link" 
       onMouseEnter = {(event) => handleHover(event)}>
        <path id = "Australia" d = "..."/>
      </a>
    </svg>
  );
}

Другие вопросы по теме