У меня есть следующий элемент HTML, содержащий объект javascript:
<div ui-jq = "easyPieChart"
ui-options = "{
percent: 75,
lineWidth: 5,
trackColor: '#e8eff0',
barColor: '#23b7e5',
scaleColor: false,
color: '#3a3f51',
size: 134,
lineCap: 'butt',
rotate: -90,
animate: 1000
}"
class = "easyPieChart">
</div>
Как я могу преобразовать эту строку в массив, как показано ниже, без изменения HTML:
[{
animate: 1000,
barColor: "#23b7e5",
color: "#3a3f51",
lineCap: "butt",
lineWidth: 5,
percent: 75,
rotate: -90,
scaleColor: false,
size: 134,
trackColor: "#e8eff0"
}]
Я уже пробовал эти версии:
$("[ui-jq]").each(function () {
var self = $(this);
// var options = eval('[' + self.attr('ui-options') + ']');
var options = (new Function("return [" + self.attr('ui-options') + "];")());
console.info(options);
});
Но я получаю сообщение об ошибке относительно CSP:
Content Security Policy of your site blocks the use of 'eval' in JavaScript
The Content Security Policy (CSP) prevents the evaluation of arbitrary strings as JavaScript to make it more difficult for an attacker to inject unauthorized code on your site.
To solve this issue, avoid using eval(), new Function(), setTimeout([string], ...) and setInterval([string], ...) for evaluating strings.
Я создал этот JSFiddle, чтобы помочь вам быстрее показать мне пример: https://jsfiddle.net/oqwc1j58/4/
Спасибо



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Если вы сделаете атрибут атрибутом data- и сделаете значение правильным JSON, то jQuery сделает это за вас:
$("[ui-jq]").each(function () {
var self = $(this);
var options = self.data("uiOptions");
console.info(options);
});<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div ui-jq = "easyPieChart"
data-ui-options='{
"percent": 75,
"lineWidth": 5,
"trackColor": "#e8eff0",
"barColor": "#23b7e5",
"scaleColor": false,
"color": "#3a3f51",
"size": 134,
"lineCap": "butt",
"rotate": -90,
"animate": 1000
}'
class = "easyPieChart">
</div>Когда jQuery видит, что значение атрибута data- может быть проанализировано как действительный JSON, он делает это неявно и возвращает результирующее значение, когда вы загружаете его через .data(). Обратите внимание, что следует использовать версию имени в верблюжьем регистре (я думаю), но jQuery может работать с любой версией. Обратите также внимание, что вы опускаете префикс «data-».
Спасибо за ваш ответ, но я не могу изменить HTML.
Это немного странно, но вы можете самостоятельно проанализировать HTML и создать массив, который вы ищете:
// From https://stackoverflow.com/a/72773057/378779
const sortObjectByKeys = (object, asc = true) => Object.fromEntries(
Object.entries(object).sort(([k1], [k2]) => k1 < k2 ^ !asc ? -1 : 1),
)
$("[ui-jq]").each(function () {
let options = $(this).attr('ui-options').replace('{', '').replace('}', '').split('\n')
let o = {}
options.filter(function(option) { return ! option.match(/^\s*$/) }).forEach(function(option){
option = option.trim().replace(/,$/, '')
let a = option.split(/: /)
o[a[0]] = a[1].replace("'", '')
})
console.info(sortObjectByKeys(o))
});
</script><script src = "https://code.jquery.com/jquery-3.6.3.js" integrity = "sha256-nQLuAZGRRcILA+6dMBOvcRh5Pe310sBpanc6+QBmyVM = " crossorigin = "anonymous"></script>
<div ui-jq = "easyPieChart"
ui-options = "{
percent: 75,
lineWidth: 5,
trackColor: '#e8eff0',
barColor: '#23b7e5',
scaleColor: false,
color: '#3a3f51',
size: 134,
lineCap: 'butt',
rotate: -90,
animate: 1000
}"
class = "easyPieChart">
</div>Вы можете использовать JSON.parse():
const opts=$("[ui-jq]").get().map(el=>Object.fromEntries(Object.entries(JSON.parse(el.getAttribute('ui-options').replaceAll("'",'"').replace(/(\w+)(?=\s*:)/g,'"$1"'))).sort(([a],[b])=>a.localeCompare(b))));
console.info(opts);<script src = "https://code.jquery.com/jquery-3.6.3.js" integrity = "sha256-nQLuAZGRRcILA+6dMBOvcRh5Pe310sBpanc6+QBmyVM = " crossorigin = "anonymous"></script>
<div ui-jq = "easyPieChart"
ui-options = "{
percent: 75,
lineWidth: 5,
trackColor: '#e8eff0',
barColor: '#23b7e5',
scaleColor: false,
color: '#3a3f51',
size: 134,
lineCap: 'butt',
rotate: -90,
animate: 1000
}"
class = "easyPieChart">
</div>Это более элегантное решение, чем мое, но все же не упорядочивает результаты по ключу. С небольшим количеством кода вы также можете выполнить необходимую сортировку.
Хорошо, я добавил сортировку. Не понимал, что это важно здесь.
@kmoser Вы не должны полагаться на порядок ключей в объекте
@Bergi Это сложный вопрос, и на него есть несколько ответов в зависимости от того, как вы собираетесь использовать объект.
@kmoser Это сложно только тогда, когда вам нужно это сделать. Общий совет, что вам не следует этого делать, остается в силе.
Ну, не меняйте HTML, если не хотите, но вы просто усложняете себе жизнь/