Skip to main content Accessibility Feedback

Handling Chinese and Cyrillic character hash and href values in JavaScript

Last week, I got a bug report on Smooth Scroll that content with Chinese and Cyrillic characters in the ID weren’t working in Safari and Firefox. The problem seemed to extend to any valid, non-ASCII characters.

I eventually discovered that when calling the hash or href of an element in JavaScript, Chrome handles non-ASCII characters quite differently (I’d argue, more correctly) than Firefox or Safari do.

In a click listener, I have this code:

// Get the clicked anchor link's hash value
var hash = event.target.hash;

If this is the clicked link…

<a href="#中文">Click Me!</a>

Chrome returns #中文, while Safari and Firefox return an encoded version of that, #%E4%B8%AD%E6%96%87. (I didn’t have access to IE or Edge to test.)

The fix to this was actually really simple. Decode the hash using decodeURIComponent().

// Get the clicked anchor link's hash value
var hash = decodeURIComponent( event.target.hash );

However, some elements have characters that decodeURIComponent() doesn’t like, so you have to do some error catching.

// Get the clicked anchor link's hash value
var hash;
try {
    hash = decodeURIComponent( event.target.hash );
} catch(e) {
    hash = event.target.hash;
}

Problem solved!


🔥 Hot off the press! I just launched a new pocket guide. Learn how to build interactive web apps with vanilla JavaScript.

Have any questions or comments about this post? Email me at chris@gomakethings.com or contact me on Twitter at @ChrisFerdinandi.

Get Daily Developer Tips