当前位置: 首页 > news >正文

微机课做网站广告案例网站

微机课做网站,广告案例网站,怎么设置 多个首页 wordpress,国家建设工程信息网官网[utils.domManipulation.js]是 Knockout.js 框架中负责处理 HTML 片段解析和 DOM 操作的核心模块。它提供了将 HTML 字符串转换为 DOM 节点的功能,以及设置元素 HTML 内容的工具函数。 核心概念 HTML 解析的挑战 在 Web 开发中,将 HTML 字符串转换为 DOM…

[utils.domManipulation.js]是 Knockout.js 框架中负责处理 HTML 片段解析和 DOM 操作的核心模块。它提供了将 HTML 字符串转换为 DOM 节点的功能,以及设置元素 HTML 内容的工具函数。

核心概念

HTML 解析的挑战

在 Web 开发中,将 HTML 字符串转换为 DOM 节点并不是一个简单的过程,特别是对于一些特殊的 HTML 元素:

  1. 表格相关元素 - <tr>, <td>, <th> 等元素不能直接通过 innerHTML 设置
  2. 表单相关元素 - <option>, <optgroup> 等元素有特殊要求
  3. 注释节点 - 在某些浏览器中处理不当可能会丢失
  4. 跨浏览器兼容性 - 不同浏览器对 HTML 解析的行为可能不同

解决方案

Knockout.js 通过包装和扩展浏览器原生的 HTML 解析功能,提供了一套统一的 API 来处理这些复杂情况。

核心实现

HTML 包装映射

var none = [0, "", ""],table = [1, "<table>", "</table>"],tbody = [2, "<table><tbody>", "</tbody></table>"],tr = [3, "<table><tbody><tr>", "</tr></tbody></table>"],select = [1, "<select multiple='multiple'>", "</select>"],lookup = {'thead': table,'tbody': table,'tfoot': table,'tr': tbody,'td': tr,'th': tr,'option': select,'optgroup': select};

这个映射表定义了如何包装特殊 HTML 元素以确保它们能被正确解析。例如,<td> 元素需要包装在 <table><tbody><tr> 中才能正确解析。

HTML 解析函数

simpleHtmlParse
function simpleHtmlParse(html, documentContext) {documentContext || (documentContext = document);var windowContext = documentContext['parentWindow'] || documentContext['defaultView'] || window;// Trim whitespace, otherwise indexOf won't work as expectedvar tags = ko.utils.stringTrim(html).toLowerCase(), div = documentContext.createElement("div"),wrap = getWrap(tags),depth = wrap[0];// Go to html and back, then peel off extra wrappers// Note that we always prefix with some dummy text, because otherwise, IE<9 will strip out leading comment nodes in descendants. Total madness.var markup = "ignored<div>" + wrap[1] + html + wrap[2] + "</div>";if (typeof windowContext['innerShiv'] == "function") {// Note that innerShiv is deprecated in favour of html5shiv. We should consider adding// support for html5shiv (except if no explicit support is needed, e.g., if html5shiv// somehow shims the native APIs so it just works anyway)div.appendChild(windowContext['innerShiv'](markup));} else {if (mayRequireCreateElementHack) {// The document.createElement('my-element') trick to enable custom elements in IE6-8// only works if we assign innerHTML on an element associated with that document.documentContext.body.appendChild(div);}div.innerHTML = markup;if (mayRequireCreateElementHack) {div.parentNode.removeChild(div);}}// Move to the right depthwhile (depth--)div = div.lastChild;return ko.utils.makeArray(div.lastChild.childNodes);
}

该函数通过将 HTML 片段包装在适当的标签中,然后使用 innerHTML 解析,最后提取出所需的节点。

jQueryHtmlParse
function jQueryHtmlParse(html, documentContext) {// jQuery's "parseHTML" function was introduced in jQuery 1.8.0 and is a documented public API.if (jQueryInstance['parseHTML']) {return jQueryInstance['parseHTML'](html, documentContext) || []; // Ensure we always return an array and never null} else {// For jQuery < 1.8.0, we fall back on the undocumented internal "clean" function.var elems = jQueryInstance['clean']([html], documentContext);// As of jQuery 1.7.1, jQuery parses the HTML by appending it to some dummy parent nodes held in an in-memory document fragment.// Unfortunately, it never clears the dummy parent nodes from the document fragment, so it leaks memory over time.// Fix this by finding the top-most dummy parent element, and detaching it from its owner fragment.if (elems && elems[0]) {// Find the top-most parent element that's a direct child of a document fragmentvar elem = elems[0];while (elem.parentNode && elem.parentNode.nodeType !== 11 /* i.e., DocumentFragment */)elem = elem.parentNode;// ... then detach itif (elem.parentNode)elem.parentNode.removeChild(elem);}return elems;}
}

当页面中引入了 jQuery 时,Knockout.js 会优先使用 jQuery 的 HTML 解析功能,因为它更成熟和强大。

核心 API

parseHtmlFragment
ko.utils.parseHtmlFragment = function(html, documentContext) {return jQueryInstance ?jQueryHtmlParse(html, documentContext) :   // As below, benefit from jQuery's optimisations where possiblesimpleHtmlParse(html, documentContext);  // ... otherwise, this simple logic will do in most common cases.
};

解析 HTML 片段并返回 DOM 节点数组。如果页面中引入了 jQuery,则使用 jQuery 的解析功能,否则使用内置的解析逻辑。

setHtml
ko.utils.setHtml = function(node, html) {ko.utils.emptyDomNode(node);// There's no legitimate reason to display a stringified observable without unwrapping it, so we'll unwrap ithtml = ko.utils.unwrapObservable(html);if ((html !== null) && (html !== undefined)) {if (typeof html != 'string')html = html.toString();// jQuery contains a lot of sophisticated code to parse arbitrary HTML fragments,// for example <tr> elements which are not normally allowed to exist on their own.// If you've referenced jQuery we'll use that rather than duplicating its code.if (jQueryInstance) {jQueryInstance(node)['html'](html);} else {// ... otherwise, use KO's own parsing logic.var parsedNodes = ko.utils.parseHtmlFragment(html, node.ownerDocument);for (var i = 0; i < parsedNodes.length; i++)node.appendChild(parsedNodes[i]);}}
};

设置节点的 HTML 内容。如果引入了 jQuery,则使用 jQuery 的 html() 方法,否则使用 Knockout.js 自己的解析逻辑。

优化方案(针对现代浏览器)

针对现代浏览器,我们可以大幅简化 DOM 操作模块的实现:

(function () {// 现代浏览器中的 HTML 包装映射const lookup = {'thead': [1, "<table>", "</table>"],'tbody': [1, "<table>", "</table>"],'tfoot': [1, "<table>", "</table>"],'tr': [2, "<table><tbody>", "</tbody></table>"],'td': [3, "<table><tbody><tr>", "</tr></tbody></table>"],'th': [3, "<table><tbody><tr>", "</tr></tbody></table>"],'option': [1, "<select multiple='multiple'>", "</select>"],'optgroup': [1, "<select multiple='multiple'>", "</select>"]};function getWrap(tagName) {// 提取标签名const match = tagName.match(/<([a-z]+)/i);const tag = match ? match[1].toLowerCase() : '';return lookup[tag] || [0, "", ""];}function parseHtmlFragment(html, documentContext) {documentContext = documentContext || document;// 使用现代浏览器的 DOMParser APIif (typeof DOMParser !== 'undefined') {const parser = new DOMParser();const doc = parser.parseFromString(`<div>${html}</div>`, 'text/html');return Array.from(doc.body.firstChild.childNodes);}// 回退到模板元素方法const template = documentContext.createElement('template');template.innerHTML = html;return Array.from(template.content.childNodes);}ko.utils.parseHtmlFragment = function(html, documentContext) {// 如果引入了 jQuery,仍然可以使用它if (jQueryInstance && jQueryInstance.parseHTML) {return jQueryInstance.parseHTML(html, documentContext) || [];}return parseHtmlFragment(html, documentContext);};ko.utils.parseHtmlForTemplateNodes = function(html, documentContext) {const nodes = ko.utils.parseHtmlFragment(html, documentContext);return (nodes.length && nodes[0].parentElement) || ko.utils.moveCleanedNodesToContainerElement(nodes);};ko.utils.setHtml = function(node, html) {ko.utils.emptyDomNode(node);// 解包 observablehtml = ko.utils.unwrapObservable(html);if ((html !== null) && (html !== undefined)) {if (typeof html != 'string')html = html.toString();// 如果引入了 jQuery,使用 jQuery 的 html 方法if (jQueryInstance) {jQueryInstance(node).html(html);} else {// 使用现代浏览器的实现const parsedNodes = ko.utils.parseHtmlFragment(html, node.ownerDocument);parsedNodes.forEach(parsedNode => node.appendChild(parsedNode));}}};
})();ko.exportSymbol('utils.parseHtmlFragment', ko.utils.parseHtmlFragment);
ko.exportSymbol('utils.setHtml', ko.utils.setHtml);

优化要点

  1. 使用现代 API - 利用 DOMParser<template> 元素
  2. 简化包装逻辑 - 移除 IE 兼容性代码
  3. 使用现代 JavaScript 语法 - 使用 const/let、箭头函数、Array.from
  4. 移除过时的兼容代码 - 删除针对 IE6-8 的特殊处理

使用示例

基本用法

// 解析 HTML 片段
const nodes = ko.utils.parseHtmlFragment('<p>Hello, world!</p><div>Content</div>');
console.log(nodes.length); // 输出节点数量// 设置元素的 HTML 内容
const element = document.getElementById('content');
ko.utils.setHtml(element, '<h1>Title</h1><p>Paragraph</p>');

在绑定处理器中使用

ko.bindingHandlers.html = {init: function() {// 阻止默认的后代绑定return { controlsDescendantBindings: true };},update: function(element, valueAccessor) {// 使用 Knockout.js 的 HTML 设置功能ko.utils.setHtml(element, valueAccessor());}
};

处理特殊元素

// 解析表格相关元素
const tableCells = ko.utils.parseHtmlFragment('<td>Cell 1</td><td>Cell 2</td>');
// 这些单元格会被正确包装在表格结构中// 解析表单选项
const options = ko.utils.parseHtmlFragment('<option value="1">Option 1</option><option value="2">Option 2</option>');
// 这些选项会被正确包装在 select 元素中

总结

[utils.domManipulation.js]是 Knockout.js 中一个重要的 DOM 操作模块,它解决了 HTML 解析和 DOM 操作中的复杂问题。通过提供统一的 API,它隐藏了浏览器差异,使得开发者可以安全地处理各种 HTML 片段。

对于现代浏览器,我们可以利用新的 Web API(如 DOMParser<template> 元素)来简化实现,同时保持与 jQuery 等库的兼容性。这种渐进式增强的设计模式使得 Knockout.js 既能在旧环境中正常工作,又能在现代浏览器中发挥最佳性能。

http://www.dtcms.com/a/559395.html

相关文章:

  • 还有哪些行业可以做垂直网站wordpress 仿百度百家
  • php7跨设备网站开发pdf网页首页设计图片
  • 网站设计人员就业要求青岛网站制作价格
  • 网站建设公司客户分析成都专业网站推广公司
  • 建设人力资源网站目标企业站seo哪家好
  • 网站设计大概多少钱如何申请网站空间
  • 兼职网站开发需求网上做造价网站
  • 手机网站建设怎么样建完网站怎样维护
  • 个人网站可以做地方女装网站建设规划书
  • 免费域名如何建站搜索引擎优化自然排名的缺点
  • 高端的网站建设wordpress调用菜单
  • wordpress登录地址修改密码搜狗整站优化
  • 做微商哪个网站有客源黄埔做网站
  • 域名解析网站登录seo技术软件
  • 深圳市深圳市住房和建设局网站首页seo网络推广公司
  • xunsearch做搜索网站江西省网站建设公司
  • 原识:快述Transformer架构
  • 不是搜索网站的是北京清控人居建设集团网站
  • 质量品质好的装修公司济南官网seo厂家
  • iis7.5 网站打不开推广方式英语
  • 做游戏网站教程上海百度地图
  • app设计网站模板wordpress适配手机端
  • 北京网站建设哪便宜个人代运营一般怎么收费
  • 网站免费认证联盟网站内容设计遵循的原则有
  • 政法队伍建设网站主要内容营销型网站设计建设
  • 开通建立企业网站cmseasy去版权
  • 中裕隆建设有限公司网站做数据结构基础的网站
  • 自动下单网站开发盐城网站建设费用
  • 视频营销网站1m宽带做网站
  • 毕业设计做网站起个名字wordpress 审批