草庐IT

javascript - 通过 jQuery 附加的 HTML 字符串

coder 2023-08-08 原文

我想使用 jQuery append 生成以下 HTML 字符串。手动编写代码对我来说太麻烦了。

 <div>

    <label>Name (Optional)</label>
    <input type='text' class='form-control' id='job-name'/><br />

    <label>Quick Schedule</label><br />

    <a class="btn btn-primary" onclick="schedule = '@hourly'; job_string();">Hourly</a>
    <a class="btn btn-primary" onclick="schedule = '@daily'; job_string();">Daily</a>
    <a class="btn btn-primary" onclick="schedule = '@weekly'; job_string();">Weekly</a>
    <a class="btn btn-primary" onclick="schedule = '@monthly'; job_string();">Monthly</a>
    <a class="btn btn-primary" onclick="schedule = '@yearly'; job_string();">Yearly</a><br /><br />

    <div class="row">
        <div class="col-md-2">Minute</div>
        <div class="col-md-2">Hour</div>
        <div class="col-md-2">Day</div>
        <div class="col-md-2">Month</div>
        <div class="col-md-2">Week</div>
    </div>

    <div class="row">
        <div class="col-md-2"><input type="text" class="form-control" id="job-minute" value="*" onclick="this.select();"/></div>
        <div class="col-md-2"><input type="text" class="form-control" id="job-hour" value="*" onclick="this.select();"/></div>
        <div class="col-md-2"><input type="text" class="form-control" id="job-day" value="*" onclick="this.select();"/></div>
        <div class="col-md-2"><input type="text" class="form-control" id="job-month" value="*" onclick="this.select();"/></div>
        <div class="col-md-2"><input type="text" class="form-control" id="job-week" value="*" onclick="this.select();"/></div>
        <div class="col-md-2"><a class="btn btn-primary" onclick="set_schedule();">Set</a></div>
    </div>
  </div>

例如,应该写成如下格式。

$('<div/>').append(

        ).append(

        ) ....

使用 jQuery append 创建上述 HTML 的最佳方法是什么?非常感谢这里的领导。

最佳答案

您可以用树状数据结构表示 HTML。完成后,您可以遍历树,并为每个节点创建相应的元素并将其附加到目标元素。

函数式编程似乎非常适合用最少的代码创建上述对象。您可以通过函数组合来抽象创建复杂的结构。此外,您可以使用数组和高阶函数(如 map)来批量创建元素。

为了让您了解它是如何完成的,请考虑以下用于表示节点(元素)的模型(接口(interface)):

interface Node {
  tag: string;
  classNames: string[];
  attrs: {
    [key: string]: string;
  };
  eventHandlers: {
    [key: string]: (...params: any[]) => any;
  };
  children: Node[];
  textChildren: string[];
}

注意:上面的类型定义是用 Typescript 编写的。显然,您可以忽略类型并实现我在纯 JavaScript 中描述的内容。

现在考虑以下标记:

<div class="row">
    <div class="col-md-2"><input type="text" class="form-control" id="job-minute" value="*" onclick="this.select();"/></div>
    <div class="col-md-2"><input type="text" class="form-control" id="job-hour" value="*" onclick="this.select();"/></div>
    <div class="col-md-2"><input type="text" class="form-control" id="job-day" value="*" onclick="this.select();"/></div>
    <div class="col-md-2"><input type="text" class="form-control" id="job-month" value="*" onclick="this.select();"/></div>
    <div class="col-md-2"><input type="text" class="form-control" id="job-week" value="*" onclick="this.select();"/></div>
    <div class="col-md-2"><a class="btn btn-primary" onclick="set_schedule();">Set</a></div>
</div>

让我们定义一些辅助函数,这样我们就可以更容易地创建等价树:

const createRow = (children) => ({
  tag: "div",
  classNames: ["row"],
  attrs: {},
  eventHandlers: {},
  children,
  textChildren: []
});

const createCol = (cls, children) => ({
  tag: "div",
  classNames: [cls],
  attrs: {},
  eventHandlers: {},
  children,
  textChildren: []
});

const createFormInput = (attrs, eventHandlers) => ({
  tag: "input",
  attrs,
  classNames: ["form-control"],
  eventHandlers,
  children: [],
  textChildren: []
});

const createFormInputTextInCol = id =>
  createCol("col-md-2", [
    createFormInput(
      {
        type: "text",
        id,
        value: "*"
      },
      {
        click() {
          this.select();
        }
      }
    )
  ]);

const createAnchorButton = (text, eventHandlers) => ({
  tag: "a",
  attrs: {},
  classNames: ["btn", "btn-primary"],
  eventHandlers,
  children: [],
  textChildren: [text]
});

使用上面定义的函数,创建等效树非常简单:

const row = createRow([
  ...["job-minute", "job-hour", "job-day", "job-month", "job-week"].map(
    createFormInputTextInCol
  ),
  createCol("col-md-2", [
    createAnchorButton("Set", {
      click() {
        // TODO: define set_schedule
        // set_schedule();
      }
    })
  ])
]);

要将此对象转换为(JQuery 包装的)元素,您可以执行以下操作:

const toElement = node => {
  const element = $(`<${node.tag}>`);
  Object.keys(node.attrs).forEach(key => {
    element.attr(key, node.attrs[key]);
  });
  element.addClass(node.classNames.join(" "));
  Object.keys(node.eventHandlers).forEach(key => {
    element.on(key, function(...args) {
      node.eventHandlers[key].call(this, ...args);
    });
  });
  node.textChildren.map(text => document.createTextNode(text)).forEach(e => element.append(e));
  node.children.map(toElement).forEach(e => element.append(e));
  return element;
};
$('<div />').append(toElement(row));

演示

const createRow = (children) => ({
  tag: "div",
  classNames: ["row"],
  attrs: {},
  eventHandlers: {},
  children,
  textChildren: []
});

const createCol = (cls, children) => ({
  tag: "div",
  classNames: [cls],
  attrs: {},
  eventHandlers: {},
  children,
  textChildren: []
});

const createFormInput = (attrs, eventHandlers) => ({
  tag: "input",
  attrs,
  classNames: ["form-control"],
  eventHandlers,
  children: [],
  textChildren: []
});

const createFormInputTextInCol = id =>
  createCol("col-md-2", [
    createFormInput({
      type: "text",
      id,
      value: "*"
    }, {
      click() {
        this.select();
      }
    })
  ]);

const createAnchorButton = (text, eventHandlers) => ({
  tag: "a",
  attrs: {},
  classNames: ["btn", "btn-primary"],
  eventHandlers,
  children: [],
  textChildren: [text]
});

const row = createRow([
  ...["job-minute", "job-hour", "job-day", "job-month", "job-week"].map(
    createFormInputTextInCol
  ),
  createCol("col-md-2", [
    createAnchorButton("Set", {
      click() {
        // TODO: define set_schedule
        // set_schedule();
      }
    })
  ])
]);

const toElement = node => {
  const element = $(`<${node.tag}>`);
  Object.keys(node.attrs).forEach(key => {
    element.attr(key, node.attrs[key]);
  });
  element.addClass(node.classNames.join(" "));
  Object.keys(node.eventHandlers).forEach(key => {
    element.on(key, function(...args) {
      node.eventHandlers[key].call(this, ...args);
    });
  });
  node.textChildren.map(text => document.createTextNode(text)).forEach(e => element.append(e));
  node.children.map(toElement).forEach(e => element.append(e));
  return element;
};

$(document).ready(() => {
  const rowElement = toElement(row);
  $("#wrapper").html(rowElement);
  $("#outerHtml").text($("#wrapper").html());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">

<h2>Generated HTML</h2>
<pre id="outerHtml"></pre>

<h2>Appended Element</h2>
<div id="wrapper"></div>

关于javascript - 通过 jQuery 附加的 HTML 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52312451/

有关javascript - 通过 jQuery 附加的 HTML 字符串的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. Ruby 解析字符串 - 2

    我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

  3. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  4. ruby-on-rails - unicode 字符串的长度 - 2

    在我的Rails(2.3,Ruby1.8.7)应用程序中,我需要将字符串截断到一定长度。该字符串是unicode,在控制台中运行测试时,例如'א'.length,我意识到返回了双倍长度。我想要一个与编码无关的长度,以便对unicode字符串或latin1编码字符串进行相同的截断。我已经了解了Ruby的大部分unicode资料,但仍然有些一头雾水。应该如何解决这个问题? 最佳答案 Rails有一个返回多字节字符的mb_chars方法。试试unicode_string.mb_chars.slice(0,50)

  5. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  6. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  7. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  8. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  9. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  10. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

随机推荐