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

Reading values from a properties file using HTML

Here's a snippet of my HTML code: First name: <input type = "text" > Last name: <input type = "text"> Instead of manually inputting the field values (First name, Last name) in the HTML, I am interested in reading them ...

Customize your Bootstrap 4 accordion cards with added margin and a sleek design without the usual bottom

After incorporating Bootstrap's accordion component, I made a custom adjustment by including spacing between the cards to achieve this layout (the - and + symbols were my addition and not important here): https://i.stack.imgur.com/5nRrP.png However, ...

If the text is too wide for the parent div width, wrap it in a child div

<div class='jfmfs-friend' id='123'> <input type='checkbox'/> <img src='id.jpg'/> <div class='friend-name'>Himanshu Yadav</div> </div> I am looking to modify the st ...

Finding a nested HTML element within a frame using Selenium without the presence of an iframe

Currently, I am delving into the world of Selenium using python to automate form filling on a particular website. However, my efforts have hit a roadblock as I am struggling to identify any elements within a frame and encountering a dreaded NoSuchElementEx ...

The "Location..." header always points me back to the same destination

Hope you're all doing well. I've been having some trouble with using header("Location...") to redirect from one page to another on my website. For some reason, it keeps redirecting me back to the same page. I've gone through my code multiple ...

What are the steps to add a Search Box to my HTML Website?

Currently, I am in search of a way to incorporate a "Search" feature on my website that is built solely with HTML. I have added a Search box for the users but I'm uncertain about how to proceed next. Can I use PHP to enable the Search functionality o ...

The Python socket fails to receive a valid response after sending an HTTP 1.1 CONNECT request

I am attempting to create a simple program that establishes an https tunnel with www.google.com on port 443. Initially, I used the code below: import socket def main(): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(("www.google. ...

Customize the position of the date picker for HTML native <input type="date">

I have implemented the HTML native input date element (found here- https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date) and encountered an issue in Safari on macOS where my date picker is being displayed off-screen. How can I resolve this ...

What is the best method to deactivate zoom in/out buttons using JavaScript?

As a newcomer to Phonegap, I've managed to implement zoom in/out functionality using websettings in the .java file. However, I now face a challenge where I need to disable/enable the zoom in/out buttons and stop scrolling at a specific point. I attemp ...

Dynamic content alongside a stationary sidebar that adjusts in width

Attempting to create a switchable sidebar (toggling between short and long form) using bootstrap, multiple examples, and online resources. The width of the sidebar changes when toggled, and I want the content to appear next to it regardless of its length. ...

Field for user input along with a pair of interactive buttons

I created a form with one input field and two buttons - one for checking in and the other for checking out using a code. However, when I submit the form, it leads to a blank page in the php file. What could be causing this issue? UPDATE After changing fro ...

Adjust the dimensions of the dropdown menu

Objective: How can I adjust the width of a select dropdownlist that is utilizing bootstrap v2? Challenge: I am uncertain about how to modify the width in the context of bootstrap. Additional Information: Keep in mind that there are three dropdownli ...

What improvements does IE7 offer compared to IE6?

Many developers in the web development industry often express frustration when it comes to developing for IE6. But when working with a powerful JavaScript framework such as jQuery, does the process of developing for IE6 differ significantly from that of ...

Bootstrap-tour is incompatible with a row within a table structure

Is there a way to highlight a table row effectively? I've been struggling with it and tried using the fix mentioned in this bootstrap-tour issue here Check out this demonstration on jsFiddle: jsFiddle JAVASCRIPT $("#dialog").dialog(); var t = new ...

Fancybox overlay not adjusting to full height

When working with JavaScript: $(document).ready(function() { $(".fancybox").fancybox({ helpers: { overlay: { opacity: 0.4, css: { 'background-color': '#FFF' ...

Remove the concluding statement from the HTML string if it exceeds the capacity of the iPhone's webView

I have an array of content with certain sections in bold. The bold parts can be located anywhere within the text, so I am utilizing a webView to display an HTML string with appropriate bold tags. However, I am encountering issues where the webViews do not ...

"Adding a large amount of HTML using .append() is causing slow performance in Internet Explorer 10

Lately, I've been encountering some challenges with jQuery code in my workplace. Unfortunately, I don't have the exact code on hand at the moment, but I'll do my best to provide pseudo-code. Being relatively new to JavaScript, there may be e ...

Instructions for including a script and stylesheet exclusively on a single page of a website

I need to incorporate these two lines onto a single page of my website: <script src="//cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/owl.carousel.js"></script> As well as <link href="//cdnjs.cloudflare.com/ajax/libs/OwlCa ...

Angular 2 Typeface Delivery to the Server

I'm experiencing an issue with the font when trying to access it from the server. It works fine on localhost, but on the server with a different directory structure, it fails to load properly. The same problem occurs with the logo as well. @font-face ...

Automatically generating new lines of grid-template-columns with CSS grid

I am new to using grid in CSS and there are still some concepts that I don't quite understand. Below is the container I am working with: <section class="css-grid"> <div class="css-item"><img src="1.jpg" / ...