21

有没有一种方便的方法来引用 JavaScript 中同时包含单引号和双引号的大块 HTML?

有没有类似 HERE-doc <<EOF、多引号字符"""或自定义分隔符的东西q{}

对这个问题有任何创造性或创造性的解决方案吗?

4

11 回答 11

20

有些人不喜欢这样,所以要为轻蔑和嘲笑做好准备,但一个技巧是将你的“大块东西”倾倒在一个<script language="text">块中:

<script id='blockOfStuff' language="text">
  Hi this is random stuff
  <h1>Including HTML markup</h1>
  And quotes too, or as one man said, "These are quotes, but
  'these' are quotes too."
</script>

John Resig 使用了这种技术(或者如果你愿意的话,也可以使用这种技术)作为他的模板机制的例子。

您可以酌情使用“innerText”或“innerHTML”或通过​​您喜欢的框架的服务来获取内容。

编辑——请注意,通过 jQuery(与我在下面的评论中所说的相反).text()不起作用,尽管认为它应该。改为使用.html()

于 2010-06-01T22:11:07.187 回答
9

本机不支持。

但是,由于我们正在讨论使其发挥作用的方法,因此(根据我的经验)可以这样做:

<script type="text/javascript">  

    var name = "Mud";

    var str = "\
        My name is " + name + "\
        not to be confused with Bill\
        or Jack or Pete or Dennis\
        my name is " + name + " and it's always been\
    ";

    alert("Les'n one: " + str);

</script>

那些反斜杠可以解决问题。只需确保对字符串中的任何双引号进行反斜杠转义,因为整个块都被它们引用。

请注意,这不会保留换行符,您必须在每行的尾随斜杠之前手动将它们插入为“\n”。另一方面,每行开头的任何空白缩进都将包含在输出中。

当您必须在脚本(例如 XML)中声明一个长的多行字符串时,这确实最有效,当您需要保持该字符串的格式与您定义它的方式完全相同时效果不佳。

干杯

于 2011-03-30T20:50:58.177 回答
4

JavaScript 做不到,但CoffeeScript是 JavaScript 之上的一个薄层,可以。

点击链接并向下滚动到“多行字符串和 Heredocs”。

于 2010-06-01T22:04:23.967 回答
3

我记得不久前看到过一个聪明的解决方案,它在函数中使用了多行注释:

(function () {
   /*
      "This is an example of a multi-line string.  It's really just a mult-line
      comment, and it's wrapped in quote marks.  You might also notice the 
      apostrophe's ;-)"; 
   */
});

注意:最后一个撇号是故意不正确的;-P

诀窍是调用函数的toString()方法并使用正则表达式解析出多行注释。聪明,但很像 Pointy 的建议,有点可恶。

我实际上并不认为这个问题是在寻找一种用于生产用途的真正可行的方法——我自己的错误是草率地得出结论——我不确定你为什么不只是逃避相关的字符串文字分隔符。正如 Tim Down 在下面的评论中指出的那样,ECMAScript 第 3 版将函数的 toString() 定义为依赖于实现。

有趣的是,我决定检查浏览器的兼容性,这种方法在 IE、Opera、Safari 和 Chrome 中是可行的,但在 Firefox 中是可行的,它在返回的字符串中不包含注释。 http://jsfiddle.net/2yvXG/

于 2010-06-01T22:17:09.163 回答
1

用于 JavaScript 的 HereDoc

FuncToHereDoc(“demiter”,未调用的函数,带有注释的 HEREDOC)

function FuncToHereDoc(here,str) {
    var reobj = new RegExp("/\\*"+here+"\\n[\\s\\S]*?\\n"+here+"\\*/", "m");
    str = reobj.exec(str).toString();
    str = str.replace(new RegExp("/\\*"+here+"\\n",'m'),'').toString();
    return str.replace(new RegExp("\\n"+here+"\\*/",'m'),'').toString();
}

用法:

FuncToHereDoc("HERE", MyHereDoc);

function MyHereDoc(){
/*HERE
<p>
This is written ing the HEREDOC, notice the multilines :D.
</p>
<p>
HERE
</p>
<p>
And Here
</p>
HERE*/
}
于 2012-10-10T23:16:01.657 回答
1

ECMAscript 6,现在是标准,允许使用反引号(重音符号)来引用多行文字字符串。不幸的是,IE 11 不支持此功能,因此不应在大多数网站上使用它。(图片来源:Adam Katz,上图)

例子:

var str=
`Line 1
Line 2`;
于 2016-02-03T19:02:51.097 回答
0

我实际上制定了一个类似于 user742675 的 kludgy 变体,您将文本放在一个 div 中,然后将其可见性设置为无,然后提取内容。但是仅仅引用大量的 HTML 是不够的,所以我添加了一个功能,该功能可以获取您在脚本中声明的所有变量,因此如果您有var a = 'Steve',则 heredoc 文本中的任何 $a 实例都将呈现为 '史蒂夫'。

<script type="text/javascript">
// set variables named andy and handy, which we can use as $andy and $handy in our text

var andy = "Fred Flintstone";
var handy = "Steve Austin";

function hereDoc(divid){
var obj = window; // gets an object containing all the variables
var str = document.getElementById(divid).innerHTML; // gets the HTML block
for(var i in obj){

/* the for loop recurses through all the objects in the page - remember strings are objects in Javascript */

if((typeof(obj[i])=="string")||(typeof(obj[i])=="number")){

/* Type of makes sure it only executes replacement for strings and numbers. The function worked without this test in Firefox and Safari, but threw errors on Opera until it was added. */

myregex = new RegExp('\\$'+i,"g");

/* To replace globally, you need to use a regular expression and use the "g" option, but within the string.replace() method, the regular expression is unquoted, so you can't use a variable in it directly. So we create it and assign it to a RegExp object that works in the string.replace() method. */

str = str.replace(myregex, obj[i]);

/* we replace instances of the variable name with a dollar sign before it with the variable's value */
}
}
return str;

/* and when the loop is done, we return the processed text to be used however needed */

}

function gotoit(){

/* fill the "steve" div with the processed contents of the "randy" div. */

document.getElementById("steve").innerHTML = hereDoc("randy");
}

</script>

<a href="javascript:gotoit();">Run the script</a>
<div id="randy" style="display:none;">
The interesting thing about $andy is that he's not nearly as popular with young kids as $handy.<br><br>

What I really find 'interesting' is that this "multiline" thing works as well as $handy's bionic arm. <br><br>
</div>
<div id="steve"></div>
于 2012-02-10T17:03:55.677 回答
0

根据之前的答案和不同的用例,这里有一个小例子:

https://gist.github.com/lavoiesl/5880516

/*!
 * Extract a function's comment, useful to have multiline string
 * @link https://gist.github.com/lavoiesl/5880516
 *
 * Don't forget to use /*! to avoid the comment being removed in minification 
 */

function extractFuncCommentString(func) {
  var matches = func.toString().match(/function\s*\(\)\s*\{\s*\/\*\!?\s*([\s\S]+?)\s*\*\/\s*\}/);
  if (!matches) return false;

  return matches[1];
}

var myString = extractFuncCommentString(function(){/*!
  <p>
    foo bar
  </p>
*/});
于 2013-06-27T21:26:02.183 回答
0

我对这个问题很感兴趣,因为我想使用 javascript 将新行添加到编辑屏幕(例如,用于多个电话号码)。(我可以为此使用 ajax,但希望避免额外的服务器请求。)

我喜欢 Pointy 关于使用标签来包含您要使用的 html 块的回答:

<script id='blockOfStuff'>
  Hi this is random stuff
  <h1>Including HTML markup</h1>
</script>

但是当我尝试这个时,Firefox 和 Chrome 抱怨语法错误。我的解决方案是将“脚本”标签更改为“div”,通过 css 向用户隐藏其显示,并将其移动到正文中。例如:

<div style="display: none;" id="new_row_innerhtml">
  <td><a href="#" onclick="removeCurrentRow(this); return false;">Remove</a></td>
  <input type="hidden" name="id[]" value="new" />
  <td><input name="name[]" type="text" /></td>
</div>

That removed the syntax errors.

Here's how I used that block:

I had an "Add" link that called the appendRow function:
<a href="#" onclick="appendRow(this); return false;">Add</a>

here's the appendRow function:

function appendRow() {
  var tbl = document.getElementById('my_table');
  var row = tbl.insertRow(-1); // add to end of table
}
于 2014-08-21T03:59:00.253 回答
0
// js heredoc - http://stackoverflow.com/a/32915549/466363
// a function with comment with eval-able string, use it just like regular string

function extractFuncCommentString(func,comments) {
  var matches = func.toString().match(/function\s*\(\)\s*\{\s*\/\*\!?\s*([\s\S]+?)\s*\*\/\s*\}/);
  if (!matches) return undefined;
  var str=matches[1];

   // i have made few flavors of comment removal add yours if you need something special, copy replacement lines from examples below, mix them
  if(comments===1 )
  {
   // keep comments, in order to keep comments  you need to convert /**/ to / * * / to be able to put them inside /**/ like /*    / * * /    */
   return (
    str
   .replace(/\/\s\*([\s\S]*?)\*\s\//g,"/*$1*/") //       change   / * text * /  to   /* text */ 
   )
  }
  else if(comments===2)
  {
   // keep comments and replace singleline comment to multiline comment
   return (
    str
   .replace(/\/\s\*([\s\S]*?)\*\s\//g,"/*$1*/") //       change   / * text * /  to   /* text */ 
   .replace(/\/\/(.*)/g,"/*$1*/")          //           change   //abc to  /*abc*/
   )
  }
  else if(comments===3)
  {
   // remove comments
   return (
      str
      .replace(/\/\s\*([\s\S]*?)\*\s\//g,"") //       match / * abc * /
      .replace(/\/\/(.*)/g,"")             // match //abc
     )
  }
  else if(comments===4)
  {
   // remove comments and trim and replace new lines with escape codes
   return (
      str
      .replace(/\/\s\*([\s\S]*?)\*\s\//g,"") //       match / * abc * /
      .replace(/\/\/(.*)/g,"")             // match //abc
      .trim() // after removing comments trim and:
      .replace(/\n/g,'\\n').replace(/\r/g,'\\r') // replace new lines with escape codes. allows further eval() of the string, you put in the comment function: a quoted text but with new lines
     )
  }
  else if(comments===5)
  {
   // keep comments comments and replace strings, might not suit when there are spaces or comments before and after quotes 
   // no comments allowed before quotes of the string
   // url html links
   return (
      str
      .replace(/\/\s\*([\s\S]*?)\*\s\//g,"/*$1*/") //       change   / * text * /  to   /* text */
      .replace(/\/\/(.*)/g,"/*$1*/")          //           change   //abc to  /*abc*/
      .trim() // trim space around quotes to not escape it and:
      .replace(/\n/g,'\\n').replace(/\r/g,'\\r') // replace new lines with escape codes. allows further eval() of the string, you put in the comment function: a quoted text but with new lines
     )
  }
  else if(comments===6)
  { // good for html with links
   // remove comments and trim and replace new lines with escape codes
   return (
      str
      .replace(/\/\s\*([\s\S]*?)\*\s\//g,"") //       match / * abc * /
      .trim() // after removing comments trim and:
      .replace(/\n/g,'\\n').replace(/\r/g,'\\r') // replace new lines with escape codes. allows further eval() of the string, you put in the comment function: a quoted text but with new lines
     )
  }
  else 
  return str
}

例子

var week=true,b=123;
var q = eval(extractFuncCommentString(function(){/*!

// this is a comment     


'select 

/ * this
is a multiline 
comment * /

 a
,b  // this is a comment  
,c
from `table`
where b='+b+' and monthweek="'+(week?'w':'m')+'" 
//+' where  a=124
order by a asc
'
*/},4));

带缓存: - 制作一个简单的模板函数,并保存函数:

var cache={};
function myfunction(week,a){


    if(!cache.myfunction_sql1) eval('cache.myfunction_sql1=function(week,a){return ('+extractFuncCommentString(function(){/*!
'select 

/ * this
is a multiline 
comment * /

 a
,b  // this is a comment  
,c
from `table`
where b='+b+' and monthweek="'+(week?'w':'m')+'" 
//+' where  a=124
order by a asc

'*/},4)+')}');
    q=cache.myfunction_sql1(week,a);
    console.log(q)
}
myfunction(true,1234)

简单文本(未评估):

//var cache={};
function myfunction2(week,a){


    if(!cahce.myfunction_sql2) cahce.myfunction_sql2=extractFuncCommentString(function(){/*!

some multiline text
with <html>
and a link://to.url
and a / * comment * / 
*/},6);
    q=cahce.myfunction_sql2;
    console.log(q)
}
于 2015-10-02T20:42:13.437 回答
-1

这是你的答案。在您的页面正文中创建一个跨度或 div,使用唯一的 id 并在其中放置您想要的所有文本以及您想要的所有引号都没有关系。将 span 或 div 的样式设为“display:none; visibility:hidden;”。然后,当您希望它从 id 获取 DOM 对象并检索 innerHTML 以执行您的操作时。

于 2011-09-20T23:48:47.847 回答