Вопрос касается JS + SVG. Долго думал сюда написать, но уже несколько дней не могу найти решение, прошу помочь разобраться.
Примерный код я напишу внизу, но суть следующая: есть обёртка, в которой находятся 2 элемента, картинка и иконка из SVG
. Иконка спозицирнирована абсолютно (в примерном коде будет иначе) поверх картинки. При наведении на картинку иконка меняется посредством замены пути в USE
. При клике на обёртку должно рпоисходить некое действие.
На практике же у меня получается либо изменить иконку, либо выполнить действие при клике. Конечно, можно заменить SVG
и картинку единой картинкой, которая меняется при наведении курсора посредством CSS
, но я бы предпочёл всё же SVG
. Ради интереса пробовал на цветных квадратах всё делать и заметил, что если менять цвет квадрата через свойства CSS
(..style.backgroundColor
и даже картинки можно), то клик работает. Также пробовал использовать setTimeout
, но использование под вопросом, т.к. задержка при наведении срабатывает, да и клик не всегда пройдёт, прям русская рулетка. А чтобы боле менее проходила, нужна и задержка нормальная.
В общем, идеи иссякли, если знаете что нужно дописать, подскажите.
var wrapper = document.querySelector(".wrapper");
var image = document.querySelector(".image");
var icon_svg = document.querySelector(".icon-svg");
image.addEventListener('mouseover', function() {
if (!icon_svg.firstElementChild.classList.contains('#play_icon_active')) {
icon_svg.firstElementChild.setAttribute('xlink:href', 'svg_sprite.svg#play_icon_active');
}
});
image.addEventListener('mouseout', function() {
icon_svg.firstElementChild.setAttribute('xlink:href', 'svg_sprite.svg#play_icon');
});
wrapper.addEventListener('click', function() {
alert("OK");
});
.wrapper {
width: 50vw;
height: 30vh;
background-color: green;
}
.image {
width: 50%;
height: 100%;
margin: 0 auto;
background-color: blue;
}
.icon-svg {
width: 50%;
height: 50%;
}
<object type="image/svg+xml" data="svg_sprite.svg">
</object>
<div class="wrapper">
<div class="image">
<svg class="icon-svg">
<use xlink:href="svg_sprite.svg#play_icon">
</use>
</svg>
</div>
</div>
Разметка не совсем такая, как у вас, но проблема понятна.
Дело в том, что у вас не верно условие if (!icon_svg.firstElementChild.classList.contains('#play_icon_active'))
. Из-за этого постоянно срабатывает событие mouseover
и меняет атрибут, как следствие клик просто не происходит.
Решение:
.icon-svg
стиль pointer-events: none;
что бы событие клика не обращало внимание на svg
.Пример.
var wrapper = document.querySelector(".wrapper");
var image = document.querySelector(".image");
var icon_svg = document.querySelector(".icon-svg")
image.addEventListener('mouseover', function() {
if (icon_svg.firstElementChild.getAttribute('href') !== '#play_icon_active') {
icon_svg.firstElementChild.setAttribute('href', '#play_icon_active');
}
});
image.addEventListener('mouseout', function() {
icon_svg.firstElementChild.setAttribute('href', '#play_icon');
});
wrapper.addEventListener('click', function() {
console.log("OK");
});
.wrapper {
width: 50vw;
height: 30vh;
background-color: green;
}
.image {
width: 50%;
height: 100%;
margin: 0 auto;
background-color: blue;
}
.icon-svg {
width: 50%;
height: 50%;
pointer-events: none;
/* Делаем "прозрачным" для событий*/
}
<svg xmlns="w3.org/2000/svg" style="display:none;">
<symbol id="play_icon" viewBox="0 0 171 170"><circle fill="none" stroke="#FFF" stroke-width="14" stroke-miterlimit="10" cx="86" cy="85" r="77.5"/><circle opacity=".35" fill="#138ACE" cx="85.5" cy="84.5" r="75.5"/><path fill="#FFF" d="M58.5 121.9L128 85.6 58.6 48.9z"/>
</symbol>
<symbol id="play_icon_active" viewBox="0 0 169.8 170"><circle fill="none" stroke="#2b93d4" stroke-width="14" stroke-miterlimit="10" cx="84.8" cy="85" r="77.5"/><circle opacity=".4" fill="#fff" cx="84.3" cy="84.5" r="75.5"/>
<path fill="#2b93d4" d="M57.3 121.9l69.5-36.3-69.4-36.7z"/>
</symbol>
</svg>
<div class="wrapper">
<div class="image">
<svg class="icon-svg">
<use href="#play_icon" />
</svg>
</div>
</div>
Подвесил на кнопку Next слайдера Slick свой обработчик события ClickОн срабатывает один раз, а потом перестает
Создаю игру на node jsВ качестве соединения использую socket io
Можно ли как-нибудь задать название массива значением переменной?
image_url получаю из json но при загрузке к данному пути в начале прибавляется путь самого html файла