javascript - 基于 HTML5 DOM 方法的测试功能

标签 javascript html dom

我想知道如何测试基于 HTML5 DOM 方法的功能。例如,新的对话框 API。

考虑以下函数;

function show(dialog)
{
    if(typeof(dialog.showModal) !== "function")
        throw new Error("Update your browser");
    dialog.showModal();
}

我想确认一下

  1. 当方法不可用时会抛出错误
  2. 如果可用,则调用dialog.showModal

我目前正在使用 Firefox 和 Chrome 启动器运行 karma + jasmine,但它们似乎都不支持对话框 API。

我可以通过某种方式对此进行填充吗?我可以在所有对话框 DOM 节点上创建函数吗?

我可以执行以下操作

var modal = document.createElement("dialog");
Object.defineProperty(modal, "showModal", {
    value: function()
    {
        console.log("hello world!");
    }
});

但是,这不会转移到对话框的其他实例。

这是我想要实现的目标的一个非常简单的示例。

最佳答案

这就是polyfills:尝试将对新规范的支持填充到不支持它们的浏览器中。你所说的本质上是为<dialog>创建一个polyfill。元素。

一些旧的 ECMAScript 6 规范指定了一个函数来测试某些东西是否存在并且是一个函数,但这似乎在最近的规范中已被废弃。这是一个“polyfill”(以任何方式该术语可以应用于废弃的规范),既作为polyfill的示例,又作为我们用来进一步探索这个概念的工具:

(function () {
    "use strict";
    var ops = Object.prototype.toString;

    Function.isFunction = function(o) {
        return ops.call(o) === "[object Function]";
    };
}());

请注意,我们必须缓存原始的 Object.prototype.toString:大多数 JavaScript 运行时都会在 Function.prototype.toString 中覆盖它,并且我们确实需要调用原始的。这应该会让您了解多重填充是多么繁琐和容易出错:即使在这样的情况下,代码简短而简单,细微差别如使用 Object.prototype.toString.call(o)而不是o.toString()仍然至关重要。

无论如何,一旦你有了这个函数,测试模态支持之类的事情就变得容易多了:

(function () {
    "use strict";
    var test = document.createElement("dialog");
    if (!Function.isFunction(test.showModal)) {
        throw new Error("HTMLDialogElement.showModal() is not supported");
    };
}());

要修改所有对话框元素实例,您需要扩展与该对象最直接相关的原型(prototype)。对于 HTML 对话框规范来说,就是 HTMLDialogElement。你可以这样做:

(function () {
    "use strict";

    var HTMLDialogElement = HTMLDialogElement; //undefined if unsupported

    if (!Function.isFunction(HTMLDialogElement)) {
        // No native dialog support
        throw new Error("No support for <dialog> elements");
    }

    if (!Function.isFunction(HTMLDialogElement.prototype.showModal)) {
        // The interface exists, but showModal isn't supported
        HTMLDialogElement.prototype.showModal = function () {
            console.log("Hello world!");
        };
     }
}());

如果也不支持原型(prototype),那么事情就会变得更加棘手。未知的元素不会有独特的原型(prototype);它只是一个 HTMLElement(最终像所有其他元素一样)。因此,要使函数适用于 <dialog>如果在不受支持的环境中使用元素,则必须将其添加到所有元素中。尽管如此,你还是可以让它发挥作用:

(function () {
    "use strict";

    HTMLElement.prototype.showModal = function () {
        if (this.tagName !== "DIALOG") {
            throw new TypeError("showModal() called on non-dialog");
        }
        console.log("Hello world!");
    };
}());

大多数 Polyfill 的工作都是基于这样的妥协:它们并不完全支持规范,但足以支持常见用例。

请注意:填充扩展了 native 对象,这通常被认为是不好的做法。大多数认为这是不好做法的人都会对 Polyfill 进行异常(exception)处理,但尽管 Polyfill 非常有用,但这条规则仍然被认为是好的。这应该让您了解该任务有多复杂和容易出错。这是黑魔法:不是一项可以轻易完成的任务。

关于javascript - 基于 HTML5 DOM 方法的测试功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30529008/

相关文章:

Javascript 在循环中添加对象

javascript - appendChild while inside for loop 不能正常工作

html - 如何使 float div响应

JavaScript 元素遍历返回的结果超出预期

javascript - 动态添加文本以指向 highcharts.js 中的弹出窗口

javascript - 如何使用 jquery 在页面加载和每次刷新时随机更改内联图像?

Javascript:getHours() 返回错误数据

javascript - 从 textarea 中获取值并将其放置在带有一些添加文本的新 textarea 中

javascript - 如何获取这个 DOM 的文本部分?

javascript - 在 history.js 中强制回退 html4