为什么你不能通过连续调用.text()JQuery来逃避?

时间:2016-03-21 17:38:43

标签: javascript jquery dom

我正在使用jQuery转义表单输入,如下所示

var escapedStr = $('<div>').text(formInput).html(); 

工作得很好,很开心。

但为什么以下不起作用?

var escapedStr = $('<div>').text(formInput).text(); 

如果var formInput = '<h1>',那么$('<div>').text(formInput).text();应该将转义的h1标记插入div,然后抓取转义文本本身?相反,第二个text()抓取一个HTML标记,该标记在添加到DOM时呈现。

这里发生了什么?谁能解释一下?这是一个JS小提琴,有各种例子。我对第二种情况感到困惑。 https://jsfiddle.net/EmOnTheWeb/72sbypg7/9/

2 个答案:

答案 0 :(得分:1)

考虑此代码对源文本<h1>am I rendering?执行的操作。

var escapedStr = $('<div>').text(formInput).html();
  1. formInput 作为文字插入div
  2. 这会产生:

    <div>&lt;h1&gt;am I rendering?</div>
    
    1. 获取div
    2. HTML 内容

      这会产生:

      &lt;h1&gt;am I rendering?
      

      如果您将.html()替换为.text(),则表示“获取div的文本内容”。所以它应该与中作为文本相同。

      <h1>am I rendering?
      

      这看起来有点令人困惑,但这只是因为你的文字 HTML。行为是正确的。也许这些方法令人困惑地命名。以下是另一种思考方式:

      div.text()    ~= htmlDecode(div.innerHTML)
      div.text(str) ~= div.innerHTML = htmlEncode(str)
      div.html()    ~= div.innerHTML
      div.html(str) ~= div.innerHTML = str
      

      (请注意,上面的内容不太准确,因为text()实际上为您提供了元素及其所有子元素的连接文本节点,但对于只包含文本而没有子元素的HTML元素,它是正确的)

答案 1 :(得分:0)

在你的JS Fiddle示例中,第二个示例只有看起来,因为你正在使用jQuery append()方法,因为转义失败了。

jQuery DOM操作方法需要整个DOM节点,因此当您调用append()时,它会自动插入结束</h1>标记。

var str = '<h1>am I rendering?'; 

/* 
  text(str) calls document.createTextNode(str), which escapes the markup
  html() gets the innerHTML property of the div which at this point is "&lt;h1&gt;hello"
*/
var attemptEsc = $('<div>').text(str).html(); 
$('body').append('1. insert with text() grab out with html() gives: ' +attemptEsc);  

/* 
  text(str) calls document.createTextNode(str), which escapes the markup
  text() gets the textContent property of the div, which at this point is "<h1>hello" 
  because textContent unescapes HTML entities  
*/ 
var attemptEsc1 = $('<div>').text(str).text();
$('body').append('<br> 2. insert with text() grab out with text() gives: '+attemptEsc1); 

/* 
  html(str) sets the innerHTML of the div, attempting to create complete DOM nodes
  html() gets the innerHTML property of the div which at this point is "<h1>hello</h1>"
*/ 
var attemptEsc2 = $('<div>').html(str).text(); 
$('body').append('<br> 3. insert with html() grab out with text() gives: ' +attemptEsc2); 

/* 
  html(str) sets the innerHTML of the div, attempting to create complete DOM nodes
  text() gets the textContent property of the div, which at this point is "hello"
*/ 
var attemptEsc3 = $('<div>').html(str).html();
$('body').append('<br> 4. insert with html() grab out with html() gives: '+attemptEsc3);