59

I just updated jQuery from 1.8.3 to 1.9, and it started crashing all of a sudden.

This is my template:

<script type="text/template" id="modal_template">
    <div>hello</div>
</script>

This is how I read it:

modal_template_html = $("#modal_template").html();

This is how I transform it into jQuery object (I need to use jQuery methods on it):

template = $(modal_template_html);

... and jQuery crashes!

Error: Syntax error, unrecognized expression: <div>hello</div>

slice.call( docElem.childNodes, 0 )[0].nodeType;

jquery-1.9.0.js (line 3811)

However, if I declare template as a plain text variable, it starts working again:

var modal_template_html = '<div>hello</div>';

Can anyone help me to figure this out?

UPDATE: Jquery team heard and changed things back to normal in 1.10:

The biggest change you’re likely to see is that we’ve loosened up the criteria for HTML processing in $(), allowing leading spaces and newlines as we did before version 1.9

Evgeny
  • 6,071
  • 8
  • 33
  • 42
  • are you using the migrate plugin? its messages can help you find parts of your code that won't work in new version of jquery. – keune Jan 15 '13 at 21:57
  • I do, but it doesn't show any warnings. – Evgeny Jan 15 '13 at 21:57
  • At the point you are assigning `modal_template_html` has it already been rendered (or at least placed in the DOM)? And if so, is there anything preventing you accessing it directly using jQuery, rather than via the native `getElementById`? – Chamila Chulatunga Jan 15 '13 at 22:02
  • Sorry I removed and re-added your Mustache tag, but I'm in a serious doubt on why you say that's your "Mustache template" but then go about using just vanilla jQuery to access it. @EugeneXa answer is correct about the newer jQuery not supporting non ` – gonchuki Jan 16 '13 at 15:53
  • You are right, ideally I should be using Mustache to process the string right away, but there are few things in the template that I might need to change (like changing names of Mustache variables) in it based on what data 3rd-party API is sending to me, that's why I transform it to jQuery object, do some manipulations with it, and then transform back into string. – Evgeny Jan 16 '13 at 18:59

6 Answers6

122

Turns out string starting with a newline (or anything other than "<") is not considered HTML string in jQuery 1.9

http://stage.jquery.com/upgrade-guide/1.9/#jquery-htmlstring-versus-jquery-selectorstring

Evgeny
  • 6,071
  • 8
  • 33
  • 42
16

I guess your template is starting with a space or a tab.

You can use jQuery like that:

$($.parseHtml(modal_template_html)[1]);

or parse the string to remove spaces of the beginning:

$(modal_template_html.replace(/^[ \t]+/gm, ''));
Charles
  • 10,222
  • 10
  • 67
  • 107
9

EugeneXa mentioned it in a comment, but it deserves to be an answer:

var template = $("#modal_template").html().trim();

This trims the offending whitespace from the beginning of the string. I used it with Mustache, like so:

var markup = Mustache.render(template, data);
$(markup).appendTo(container);
Kevin C.
  • 2,409
  • 1
  • 27
  • 40
4

You can use

var modal_template_html = $.trim($('#modal_template').html());
var template = $(modal_template_html);
Brad
  • 146,404
  • 44
  • 300
  • 476
Eran H.
  • 1,036
  • 1
  • 8
  • 18
1

As the official document: As of 1.9, a string is only considered to be HTML if it starts with a less-than ("<") character. The Migrate plugin can be used to restore the pre-1.9 behavior.

If a string is known to be HTML but may start with arbitrary text that is not an HTML tag, pass it to jQuery.parseHTML() which will return an array of DOM nodes representing the markup. A jQuery collection can be created from this, for example: $($.parseHTML(htmlString)). This would be considered best practice when processing HTML templates for example. Simple uses of literal strings such as $("<p>Testing</p>").appendTo("body") are unaffected by this change.

voya
  • 11
  • 1
0

I had the same error:
"Syntax error, unrecognized expression: // "
It is known bug at JQuery, so i needed to think on workaround solution,
What I did is:
I changed "script" tag to "div"
and added at angular this code
and the error is gone...

app.run(['$templateCache', function($templateCache) {
    var url = "survey-input.html";
    content = angular.element(document.getElementById(url)).html()
    $templateCache.put(url, content);
}]);