skip to Main Content

I have created a simple code to mess around and learn with SVG files and eventlisteners.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SVG Mouse Pointer Change</title>
<style>
    #svg5 {
        width: 50%; /* Adjust the width as needed */
        height: auto; /* Maintain aspect ratio */
    }
</style>
<script>
    window.onload = function() {
        var svgObject = document.getElementById('svg5');
        svgObject.addEventListener('load', function() {
            var svgDocument = svgObject.contentDocument;
            var rect = svgDocument.getElementById('rect237');

          // Function to change mouse pointer to crosshair
            function changeCursorToCrosshair() {
                console.log("Mouse entered rect237");
                document.body.style.cursor = 'crosshair';
            }

            // Function to change mouse pointer to default
            function changeCursorToDefault() {
                console.log("Mouse left rect237");
                document.body.style.cursor = 'default';
            }

            // Add event listener for mouse enter
            rect.addEventListener('mouseenter', function() {
                console.log("Mouse entered rect237");
                changeCursorToCrosshair();
            });

            // Add event listener for mouse leave
            rect.addEventListener('mouseleave', function() {
                console.log("Mouse left rect237");
                changeCursorToDefault();
            });

        });
    };
</script>
</head>
<body>

<object id="svg5" type="image/svg+xml" data="./img/simple_pitch.svg"></object>

</body>
</html>

However when testing the code nothing occurs. I have added some console logs but nothing is shown. I hope someone can let me know what I’m missing.

Thanks

2

Answers


  1. Two things: Since the <object>‘s data is set inline in the markup, the window.load event will wait for the <object>‘s load event before it fires. So when you are in the window.load event handler, the <object>‘s one has already fired and won’t again until its data attribute changes.
    This means that the svgObject‘s load event won’t fire and your callback won’t be called.
    So remove the line svgObject.addEventListener('load', ... and call directly your code in the window.onload event handler.

    Then, document.body.style.cursor = 'crosshair'; will set the cursor of the outer HTML document’s <body> tag, but the element you are hovering is the inner SVG document’s <rect> element. Both documents are isolated and the <object>‘s inner document will capture the pointer events, including the setting of the cursor.
    If you want to change the cursor, you can set it to svgDocument.documentElement.style.cursor = ....
    (Obviously you could also have achieved the same with a simple rect { cursor: crosshair } CSS rule, but I get it’s just a test to use events.)

    Login or Signup to reply.
  2. It is not clear from the question if you are running the HTML and SVG document from a web server. To make this work (to get the load event to fire on the object element) you need to run a web server. The load event will not fire and you cannot get access to the contentDocument if you just open the HTML file from the file system.

    And in regards to the comments about the order of events. You must wait till the DOM is loaded (either setting the window.onload or using the addEventListener() method) before you can add an event listener to the object element — just like you already did.

    Here is an example, where I changed the way that the crosshair style is set. The style of the cursor is not "tied to" the events of the mouse entering and leaving an element. If an element has a cursor style, then the cursor will change when the element is hovered. And then you can have the enter and leave events do something else (like, typically change the DOM).

    <!DOCTYPE html>
    <html>
    
    <head>
      <script>
        document.addEventListener('DOMContentLoaded', e => {
          document.querySelector('object').addEventListener('load', e => {
            let svgDocument = e.target.contentDocument;
            let rect = svgDocument.getElementById('rect237');
            
            // change the style of the rect
            rect.style.cursor = 'crosshair';
            
            // add eventlisteners for rect
            rect.addEventListener('mouseenter', mouseEnterHandler);
            rect.addEventListener('mouseleave', mouseLeaveHandler);
          });
        });
    
        function mouseEnterHandler(e) {
          console.log("Mouse entered " + e.target.id);
        }
    
        function mouseLeaveHandler(e) {
          console.log("Mouse left " + e.target.id);
        }
      </script>
    </head>
    
    <body>
      <object width="400" height="200" data="svg.svg" type="image/svg+xml"></object>
    </body>
    </html>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search