Skip to main content Skip to secondary navigation 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.

Hey there! If you can hack together some jQuery but feel like you don't really know JavaScript, I've written a step-by-step training guide to help you master vanilla JavaScript. Start learning today →

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!

If you liked this article, you might also enjoy Ditching jQuery, a step-by-step training guide to help you master vanilla JavaScript. Start learning today →

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

Get the Spare Parts Newsletter

Every week, I send out a short email packed with web development resources and interesting stuff from around the web.