Soy nuevo en la programación de JavaScript y estoy atascado con la recuperación de atributos de datos.

El siguiente enlace es un poco útil para las personas que usan jQuery

almacenar y recuperar matrices de JavaScript en y desde atributos de datos HTML5

Me gustaría hacer lo mismo con vanilla js. Con la ayuda de atributos de datos personalizados, me gustaría crear objetos y matrices.

<div id="getAnimation"
data-r="564"
data-c="96" 
data-custom="x:0;y:0;z:0;rotationX:0;rotationY:0;rotationZ:0;scaleX:0.75;scaleY:0.75; skewX:0;skewY:0;opacity:0;transformPerspective:600;transformOrigin:50% 50%;"
data-s="700"
data-st="1400"
</div>

¿Los atributos de datos personalizados HTML5 "funcionan" en IE 6?

El enlace anterior ayuda a obtener atributos de datos muy bien, pero ¿cómo se puede filtrar la cadena en datos personalizados o crear directamente un objeto de datos personalizados?

Si alguien conoce una biblioteca para hacer esto, hágamelo saber

0
Fahim Akhtar 5 sep. 2014 a las 16:51

2 respuestas

La mejor respuesta

Ese ejemplo en particular es bastante directo: es una serie de nombres: pares de valores separados por punto y coma. Entonces puede obtener una matriz de los pares usando split, y luego obtener el nombre y la validez por separado usando split nuevamente. Si desea crear propiedades en un objeto utilizando esos nombres y valores, puede hacerlo con notación entre corchetes:

// Get the value
var val = theElement.getAttribute("data-custom");

// Split it into fields on `;` (with optional whitespace on either side)
var fields = val.split(/\s*;\s*/);

// Create a blank object
var obj = {};

// Loop through the fields, creating object properties:
fields.forEach(function(field) {
    // Split the field on :, again with optional whitespace either side
    var parts = field.split(/\s*:\s*/);

    // Create a property on the object using the name, and assigning the value
    obj[parts[0]] = parts[1];
});

Estoy usando String#split allí, dándole una expresión regular para decirle dónde se divide la cadena.

En el objeto resultante, con solo el código anterior, los valores de las propiedades serán cadenas. Por ejemplo, obj.scaleX será la cadena "0.75". Si los necesita como números, puede convertirlos en números de varias maneras:

  • parseFloat, que convertirá tantos caracteres como sea posible pero ignorará los caracteres finales. entonces parseFloat("0.75foo") es 0.75, no es un error.

  • Number, que no será tolerante como parseFloat, Number("0.75foo") es NaN, no 0.75.

  • Aplicando cualquier operador matemático, el + unario es común: +"0.75" es 0.75.

Entonces, en lugar de simplemente tomar los valores como cadenas, podríamos verificar si parecen ser números y convertirlos si es así:

// Loop through the fields, creating object properties:
fields.forEach(function(field) {
    // Split the field on :, again with optional whitespace either side
    var parts = field.split(/\s*:\s*/);

    // Does the value look like a number?
    if (/(?:^\d+$)|(?:^\d+\.\d+$)/.test(parts[1])) {
        // Yes
        obj[parts[0]] = +parts[1];
    }
    else {
        // No
        obj[parts[0]] = parts[1];
    }
});

Eso supone . como separador decimal, y supone que no habrá un separador de miles.


Nota al margen: arriba he usado Array#forEach, que es una función ES5 que no está presente en los navegadores más antiguos. Sin embargo, forEach se puede "calzar" en navegadores antiguos. Puede ver todo tipo de formas de recorrer las matrices en esta respuesta aquí en SO.

0
Community 23 may. 2017 a las 12:29

Aquí hay un par de funciones rápidas que le permitirán almacenar, recuperar y eliminar cualquier dato compatible con JSON en un atributo de datos

function setData(node, data_name, data_value) {
    node.dataset[data_name] = JSON.stringify(data_value);
}

function getData(node, data_name) {
    return JSON.parse(node.dataset[data_name]);
}

function delData(node, data_name) {
    return delete node.dataset[data_name];
}

Luego, para escribir un Array en #getAnimation en data-fizz

// variables to use
var elm = document.getElementById('getAnimation'),
    foo = [1, 2, 3, 'a', 'b', 'c'];
// store it
setData(elm, 'fizz', foo);
// retrieve it
var bar = getData(elm, 'fizz');
// look what we have
console.log(bar); // [1, 2, 3, "a", "b", "c"] 

Requiere IE 11+ porque uso { {X0}}, si cambia esto a los métodos node.setAttribute, node.getAttribute y node.removeAttribute como se usan, el requisito cae a IE 8+ por JSON.stringify y JSON.parse

1
Paul S. 5 sep. 2014 a las 13:05