JQuery + SVG object: Capture click event properly

2019-02-23 19:40发布

问题:

Ok, i'm trying to capture click events on menu items

Here's my html:

<nav>
<ul>
    <li class="active left" id="profileLink">
        <object type="image/svg+xml" data="public/img/nav/profile.svg">    
                <img src="public/img/nav/profile.png" alt="Blue Square"/>     
        </object>
    </li>
    <li class="left" id="suggestionsLink">
        <object type="image/svg+xml" data="public/img/nav/suggestions.svg">    
                <img src="public/img/nav/suggestions.png" alt="Blue Square"/>     
        </object>
    </li>
    <li class="right" id="settingsLink">
        <object type="image/svg+xml" data="public/img/nav/settings.svg">    
                <img src="public/img/nav/settings.png" alt="Blue Square"/>     
        </object>
    </li>
    <li class="right" id="statisticsLink">
        <object type="image/svg+xml" data="public/img/nav/statistics.svg">    
                <img src="public/img/nav/statistics.png" alt="Blue Square"/>     
        </object>
    </li>

    <li class="middle" id="friendsLink">
        <object type="image/svg+xml" data="public/img/nav/friends.svg">    
                <img src="public/img/nav/friends.png" alt="Blue Square"/>     
        </object>
    </li>
</ul>

And here's the script i'm using:

    $("#wrapper").on("click", '#friendsLink', function(){
       console.log('test');
       loadFriends();
    });

When i use the script to select a plain a-tag it works just fine, but on this svg object it doesn't work at all. Note that it does work when clicking on the padding area of the li-element. but not when clicking in the svg-image area.

A post in this thread suggests the svg dom is different from the html dom and thus jquerys events fail.

jQuery Selector + SVG Incompatible?

What is the way to go when trying to handle click events on svg elements?

Help is seriously appreciated

回答1:

If you want to use <object> you'll have to put the click handling on the svg contents i.e. the <svg> root element of public/img/nav/profile.svg etc.

If want to keep the handling as-is then you'll need to use an <image> element as the <svg> container rather than an <object> element. That comes with its own restrictions though such as no scripting and no fallback.

A third option might be to put an absolutely positioned transparent div over each svg element and have the onclick handled on that.

You'll have to chose whatever solution fits your needs best.