admin管理员组

文章数量:1278978

I have a select tag with an option tag that has a value of "\n". When that option is selected and I get the value using jQuery, JavaScript seems to be treating it as a string literal and not interpreting it as a linefeed.

I have tried escaping, unesacping, escaping then unescaping, using the jQuery htmlEncoding technique, the jQuery htmlDecoding technique, and even tried concatenating with an empty string. I'm pulling my hair out. This should be so simple.

At least 5 workarounds pop into my head almost imediately with various levels of elegance, but at this point, I'm more interested in why this behavior exists. Is there something simple I'm missing? My real question is "why does JavaScript treat a string of \n one way in one context, but differently in another", not "how do I just get it to work".

Here is the code

Html

<select id="delimiter">
  <option value="\n">New Line</option> <!--This should produce a linefeed-->
  <option value=",">, (Comma)</option>
  <option value=";">; (Semicolon)</option>
  <option value="\t">Tab</option>
</select>
<button  onclick="doit()">
  Check It
</button>

JavaScript

function doit(){
  var delimiter = $("#delimiter").val();

  console.debug("\n"); //produces an actual linefeed character
  console.debug(delimiter); //this produces the string "\n"
}

I have a codepen of it here:

I have a select tag with an option tag that has a value of "\n". When that option is selected and I get the value using jQuery, JavaScript seems to be treating it as a string literal and not interpreting it as a linefeed.

I have tried escaping, unesacping, escaping then unescaping, using the jQuery htmlEncoding technique, the jQuery htmlDecoding technique, and even tried concatenating with an empty string. I'm pulling my hair out. This should be so simple.

At least 5 workarounds pop into my head almost imediately with various levels of elegance, but at this point, I'm more interested in why this behavior exists. Is there something simple I'm missing? My real question is "why does JavaScript treat a string of \n one way in one context, but differently in another", not "how do I just get it to work".

Here is the code

Html

<select id="delimiter">
  <option value="\n">New Line</option> <!--This should produce a linefeed-->
  <option value=",">, (Comma)</option>
  <option value=";">; (Semicolon)</option>
  <option value="\t">Tab</option>
</select>
<button  onclick="doit()">
  Check It
</button>

JavaScript

function doit(){
  var delimiter = $("#delimiter").val();

  console.debug("\n"); //produces an actual linefeed character
  console.debug(delimiter); //this produces the string "\n"
}

I have a codepen of it here: https://codepen.io/codysechelski/pen/MoJKMB?editors=1111

Share Improve this question edited Jun 17, 2017 at 12:39 Cody asked Jun 17, 2017 at 12:23 CodyCody 853 silver badges7 bronze badges 4
  • 2 HTML doesn't have escape sequences like \n or \t. codepen.io/tarabyte/pen/RgKZwd?editors=1111 So it is not javascript that does it :) – Yury Tarabanko Commented Jun 17, 2017 at 12:38
  • But once we get the value of the option in JavaScript, it's just a string right? I would think that it would be the same as var s = '\n'. But that seems not to be the case – Cody Commented Jun 17, 2017 at 12:41
  • Yep a string of length 2 consisting of two chars \ and n which translated to string literals should be '\\n'. Try console.debug(delimiter.split(''), delimiter === '\\n') – Yury Tarabanko Commented Jun 17, 2017 at 12:44
  • Thanks, that explanation is sort of what I was suspecting, but what is so magical about var s = "/n". To me, it looks like a string contains two chars as well. Yet it produces a single linefeed char. Not trying to be difficult here, I just really want to understand what JS is doing behind the curtains. Does var delimiter = $("#delimiter").val(); produce a string that is somehow different that var s = '\n'. Also, is there any way to convert the string that is currently being returned and translated as "//n" to a linefeed? – Cody Commented Jun 17, 2017 at 12:58
Add a ment  | 

3 Answers 3

Reset to default 4

"why does JavaScript treat a string of \n one way in one context, but differently in another"

First you should understand that string literal is not actual string in memory but a part of js syntax to create strings. So escape sequences starting with "\" character signals to js engine to treat next char in different way.

HTML doesn't have this special syntax. So "\" is just "\" and "\n" is "\n". When this string cross html-js boundary via DOM API (which is not a part of js syntax) it remains the "same" two letter string.

By the way there are different ways to encode new line in js that produces the same string in memory

const withEscSequence = '\n'

// es2015
const usingStringTemplate = `
`
// directly from char code
const fromCharCode = String.fromCharCode(10)

// using unicode escape sequence
const unicodeEscSequence = '\u000A'

// using hex escape sequence
const hexEscSequence = '\x0A'


console.log(withEscSequence === usingStringTemplate, withEscSequence === fromCharCode, withEscSequence === unicodeEscSequence, withEscSequence ===  hexEscSequence)

replace "\n" in your value by the new line code : "&#13;" In HTML tag attribute you must use HTML character entity for special character.

Why does JavaScript treat a string of \n one way in one context, but differently in another?

Because it's not JavaScript, and not a string literal. <option value="\n"> is plain HTML, and the backslash is not an escape character in HTML. You can use a literal linebreak or a character entity instead.

I have tried escaping…

But apparently not the right one. It always depends on the context which escaping to use, and sometimes you even need to chain them. Some suitable solutions:

  • Literal characters in the HTML source:

    <option value="
    ">New Line</option>
    <option value=",">Comma</option>
    <option value=" ">Tab</option>
    

    selectEl.value
    
  • Character entity references in the HTML source, to avoid the weird formatting:

    <option value="&#x000A;">New Line</option> <!-- or &#10; -->
    <option value=",">Comma</option>
    <option value="&#x0009;">Tab</option> <!-- or &#9; -->
    

    selectEl.value
    
  • JSON literals in the HTML source to avoid knowing charcodes:

    <option value="&quot;\n&quot;">New Line</option>
    <option value="&quot;,&quot;">Comma</option>
    <option value="&quot;\t&quot;">Tab</option>
    

    JSON.parse(selectEl.value)
    
  • JSON string contents in the HTML source:

    <option value="\n">New Line</option>
    <option value=",">Comma</option>
    <option value="\t">Tab</option>
    

    JSON.parse('"'+selectEl.value+'"')
    

本文标签: jqueryquotnquot being treated as a string literal in JavaScriptStack Overflow