The click interactions of SVG elements are altered when switching between <img> and <object> elements

I currently have 4 SVG buttons featured in the main menu of my personal website.

https://i.stack.imgur.com/gA7En.png

/----------------------------------------------------------------------------------------------------------------------------------/

Upon clicking one button, all 4 buttons retract to the corners and reveal the corresponding section (e.g. Clicking "AboutMe" reveals the AboutMe section). https://i.stack.imgur.com/5CK9v.png

Initially, I embedded the SVG objects within an img tag:

<img class = "button active" id = "person-icon" src = "resources/main-page-icons/person-icon.svg"/>

This method was chosen because it was thought unnecessary to embed the SVG in an object or embed tag when no animation was required. However, upon deciding to add a hover effect to the SVG element, the img tag had to be changed to an object for styling and animating:

<object class = "button active" id = "person-icon" data = "resources/main-page-icons/person-icon.svg" type = "image/svg+xml"></object>

While the hover effect functioned correctly, the SVG became unclickable. It was discovered that clicks were registering on the SVG itself rather than the object it was embedded in. Even wrapping it in a div did not resolve the issue.

Question: Is there a way to animate the SVG element while also handling click events on the object element in which it is embedded?

In anticipation of the question "Why not handle the click event within the SVG element?" It was believed that allowing an SVG element's behavior to impact other elements would be illogical. For this reason, click events were managed OUTSIDE of the SVG element initially (e.g. clicking one button expands others, fades in content = undesirable). While potential solutions may exist, the original approach was deemed most appropriate at the time.

Thank you in advance for any assistance provided.

Answer №1

After spending some time searching on Google, I finally discovered the solution here:

In order for this type of tag to display on the page, it requires some content.

Your tag:

<object data="images/logo.svg" type="image/svg+xml" class="icon-logo"></object>

does not contain any inner HTML-Content, making it unclickable.

The issue lies in objects needing a form of innerHTML to be recognized by the DOM. By adding text such as

<object>Zoot!</object>
, the object becomes clickable. It's important to note that the SVG DOM functions differently than the HTML DOM and does not support innerHTML. More information on this topic can be found here.

To work around this problem, I opted for using an image tag enclosed in a div that allows for animation and styling. While this solution works well overall, I encountered an issue with shape distortion when applying transformations to a circular div (border-radius: 50%). The distortion is noticeable, especially when a background/border is included. This particular challenge will require a separate post!

Answer №2

One reason for this behavior is that events occurring on framed documents do not bubble up to the main document due to security concerns.
The content within an <object> element is considered a framed document and is subject to these restrictions as well.

To address this issue, you can attach the event directly to the element's contentWindow or any element within its contentDocument.

However, it should be noted that the document will remain inaccessible for cross-domain resources loaded into the element.

In cases where users have set focus on the element using keyboard navigation like the Tab key, there may be some false positives when trying to detect the current active element.

function attachClickEvent(obj, callback) {
  // no cross-domain restrictions
  if (obj.contentWindow) {
    obj.contentWindow.addEventListener('click', function() {
      callback();
    });
  } else {
    // workaround solution
    window.addEventListener('blur', function() {
      // activeElement may not have been updated yet
      requestAnimationFrame(function() {
        // check that our element is the active one
        if (document.activeElement === obj) {
          callback();
          // so we can detect it multiple times
          obj.blur()
        }
      });
    });
    // setting focus on the document
    var inp = document.createElement('input');
    inp.style.position = 'absolute';
    inp.style.opacity = 0;
    document.body.appendChild(inp);
    inp.focus();
    document.body.removeChild(inp);
  }

};

// call it when the element has loaded
crossDomain.onload = function() {
  attachClickEvent(this, function() {
    snippet.log('clicked on the doc')
  })
};
// handling UA case where load event may already have fired
crossDomain.data = crossDomain.data;
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

<object width="200px" id="crossDomain" data="https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg"></object>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to position a tooltip near an element for optimal visibility?

One div is located on the page as follows: <div id="tip"> Text for tip goes here... </div> And another one can be found below: <div class="element"> Text for element goes here... </div> There is also a piece of JavaScript ...

The problem with clearing floats in IE7 (as well as 6)

Currently, I am facing an issue where I have a list that I want to split into three columns by using the float left property and then clearing the first column. Everything seems to be working fine in IE8 and FF, however, IE7 is causing the second column t ...

Is there a way to use JavaScript to switch the entire div on and off

I have a function called done that I want to use to toggle the visibility of my "temp" division. tasks.innerHTML += `<div id="temp"> <span id="taskname"> ${input.value} </span> <button class="d ...

Achieving equal alignment of items with flexbox

As someone who is just starting to learn about HTML and CSS, I have been working on creating toggle buttons that I want to align dynamically in the center of the screen. I recently discovered flexbox which has made this process easier for me. However, one ...

Changing the image's flex-grow property will take precedence over the flex settings of other child

This is the error code I am encountering, where "text1" seems to be overridden <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <!--mobile friendly--> <meta name="view ...

Using HTML to execute a JavaScript function that transforms images

The script cutImageUp has been previously discussed on SE in a thread about Shattering image using canvas. However, I have encountered a different issue while attempting to use it. The HTML code I implemented seems to be ineffective, and despite my efforts ...

Verify if a checkbox is selected upon loading the page

Hey there, I have a jQuery change function set up to turn an input text box grey and read-only when a user selects a checkbox. However, I'm interested in adding a check on page load to see if the checkbox is already selected. Any suggestions for enhan ...

Working with radio buttons in a loop using PHP

I am facing an issue with a loop that iterates 3 times. In the loop, there's an HTML form containing radio buttons and I am processing the input using PHP. However, when echoing the form data, it does not display the correct values. Is there something ...

Switchable radio options

Currently, I am creating a form containing multiple options that are mutually exclusive. However, none of these options are mandatory. That is why I want to enable the user to uncheck a selected radio button by simply clicking on it again. This way, all th ...

Troubleshooting problem: Scrolling problem in IE7 and IE8 with Lightbox

The lightbox I'm using works flawlessly on all browsers, except for IE. When viewed on IE, it shows triple scroll bars. Here is the CSS code for the iframe: #wrap { float:left; width:800px; height:500px; overflow-x: hidden; overflow-y: scroll; } #co ...

Having trouble with adding the copy to clipboard feature

I'm having trouble implementing a copy to clipboard option on my color selector. The goal is to display the selected color on an h3 tag and create a background color generator. Each time a color is chosen, it should appear on screen for us to easily c ...

Understanding the behavior of the enter key in Angular and Material forms

When creating forms in my MEAN application, I include the following code: <form novalidate [formGroup]="thesisForm" enctype="multipart/form-data" (keydown.enter)="$event.preventDefault()" (keydown.shift.enter)="$ev ...

The Bootstrap Tooltip seems to be glued in place

Utilizing jQuery, I am dynamically generating a div that includes add and close buttons. Bootstrap tooltips are applied to these buttons for additional functionality. However, a problem arises where the tooltip for the first add button remains visible even ...

What is the process for dynamically assigning a color picker hex value as HTML attributes in PHP?

Is it possible to create a color picker that allows the user to select a hex value and then automatically apply it as an attribute in an HTML tag, like shown below? <p style="background-color: #FCF8C0;">TEXT GOES HERE</p> In the code example ...

How can we convert unpredictable-length JSON user input into well-structured HTML code?

Welcome to the world of web development! I am currently embarking on a project where I aim to transform JSON data into HTML structures. Specifically, I am working on creating a dynamic menu for a restaurant that can be easily updated using a JSON file. The ...

Changing a background image url using jQuery by clicking a button

I'm struggling to find a way to use jQuery to add a background image URL to my CSS. Everything I've attempted so far has been unsuccessful. let button = document.querySelector('form button.btn') button.addEventListener('click&ap ...

A method for calculating the product of two selected numbers and then adding them together

I am currently working on a form that includes two select options; one for logo design and another for letterhead design. Users should be able to choose the quantity of each design, or both if they wish. For example, a user could select 2 logo designs and ...

The submission button in Bootstrap 3 becomes disabled upon clicking, preventing the data from being successfully transferred to the database

Currently, I am in the process of developing a signup page using bootstrap. To validate my form, I have integrated the plugin. Despite all validations being successful, an issue arises when I attempt to submit the form - the submit button is disabled and ...

What is the best way to apply CSS to my HTML code?

I have the files stored within my Django project. My directory structure for templates looks like this: |base.html | |rules | |style_base.css In my base.html file, I link to the stylesheet like this: <link type="text/css" href="/rules/style_b ...

Is there a way to make the Sweetalert2 alert appear just one time?

Here's my question - can sweetalert2 be set to only appear once per page? So that it remembers if it has already shown the alert. Swal.fire({ title: 'Do you want to save the changes?', showDenyButton: true, showCancelButton: true, ...