-2

我想要一个 javascript 函数来获取元素的数据属性。我想在原生 JS 元素上使用它。

我四处寻找原型吸气剂,但我无法理解它是如何工作的(javascript还不是我的一杯茶)。

我想要的是:

this.myCustomFunction('fooBar'); // the `this` element
document.getElementById('ExampleId').myCustomFunction('fooBar'); // another way of selecting

我找到的所有示例都是关于我自己创建的对象,我想要一个像上面的示例一样。

要提供基准,您可以在此处找到基准

如果有人能给我一个小例子,以及一些关于代码如何流动的解释,那就太好了(或者关于如何调用它,以供将来参考)。


第一条评论建议我不要这样做。如果有其他解决方案,我会多解释一下我的目标。这就是我现在的位置:

Object.prototype.cms_getDataAttr = function(dataname){
    // IE upto 10 doenst work with dataset, so use the slower 'getAttribute'
    if( typeof this.dataset == 'undefined'){
         return this.getAttribute('data-'+dataname);
    }
    else{
        // I want to use this one instead, benchmarked this is ALOT faster
        return this.dataset.bigsrc;
    }
}
4

3 回答 3

1

我不确定这是您想要的,但您可以使用 setAttribute 和 getAttribute 在元素上读取和写入 html 属性(包括数据属性):

element.getAttribute("data-foo"); // ==> Returns the value of the data-attribute
element.setAttribute("data-foo", "newValue"); // ==> Changes the value of the data-attribute to "newValue"
于 2013-10-15T12:10:08.210 回答
1

一般来说,您应该避免扩展原生 Javascript 对象的原型。这个建议的最大原因之一是,如果不同的程序员对其原生原型扩展使用相同的函数名,这可能会导致冲突,这意味着第一个程序员的函数现在会做一些完全不同的事情。如果你想在某个时候将你的一些代码变成一个可重用的库以与其他程序员或项目共享怎么办?如果其中一个程序员有他/她自己的getDataAttr函数做的事情与你的不同,那么你的代码或其他程序员的代码都需要重写。因此,如果每个人都避免扩展本机对象会更好,除了编写 shim 以添加对旧浏览器的支持,以支持后来成为标准的功能。

正如@Bergi 指出的那样,在这种情况下,您实际上可以使用dataset较新浏览器上可用的本机属性。使用 shim,例如这个,您现在可以简单地访问dataset任何元素的属性,而不管您使用的是哪个浏览器,这意味着您不再需要自定义函数。这就是我在这种情况下所推荐的,因为当那些旧浏览器变得过时时,您甚至不再需要 shim,而且显然本机方法性能更好,并且其他程序员也更容易使用。

一般来说,扩展原生原型的一个很好的替代方法是做一些类似于 jQuery 所做的事情 - 编写一个包装原生对象并使用其他方法“扩展”它的函数,但实际上并不修改对象本身。正如我所说,我认为dataset在这种特殊情况下,垫片是一个更好的解决方案,但总的来说,这是一种有用的方法。这是一个例子:

function ExtendedDomElement(element) {
    this.element = element;
}

ExtendedDomElement.prototype = {
    constructor: ExtendedDomElement,
    getDataAttr: function(dataname) {
        var element = this.element;

        // IE upto 10 doenst work with dataset, so use the slower 'getAttribute'
        if( typeof element.dataset == 'undefined'){
             return element.getAttribute('data-'+dataname);
        }
        else {
            return element.dataset[dataname];
        }
    }
}

function extendDomElement(element) {
    return new ExtendedDomElement(element);
}

function byId(id) {
    return extendDomElement(document.getElementById(id));
}


var fooElementExtended = byId('foo');
var bar = fooElementExtended.getDataAttr('bar');
于 2013-10-15T12:51:41.443 回答
0

这就是我现在的位置:

Object.prototype.cms_getDataAttr = function(dataname){
    if (typeof this.dataset == 'undefined')
        return this.getAttribute('data-'+dataname);
    else
        return this.dataset.bigsrc;
};

您应该只扩展DOMElement接口,而不是全部Object

此外,您可能不会编写自己的数据集方法,而只需使用现有dataset属性 shim

于 2013-10-15T12:23:09.760 回答