#javascript
#javascript
Вопрос:
Я перебираю все имена классов в моем html-теле. Я бы хотел сохранить classname со значением textSize. Каждый раз, когда для данного classname появляется повторяющееся значение, я хочу увеличить его textSize .
$("*").each(function() {
classname = $(this).get(0).className;
myarray.push({"className" : classname, "textSize" : 5});
Здесь я пытаюсь отсортировать имена классов, а затем получить количество для каждого дубликата:
myarray.sort();
var current = null;
var dupCount = 0;
for (var i = 0; i < myarray.length-1; i ) {
if (myarray[i]["className"] !== "") {
if (myarray.indexOf(myarray[i]["className"]) == -1) {
log(myarray[i]["className"]);
}
else {
log("DUP");
myarray[i]["textSize"] = myarray[i]["textSize"] = 5;
dupCount ;
}
}
}
log(myarray[i]["className"]);
, показанный на изображении ниже, четко показывает дубликаты:
Тем не менее, log("DUP");
никогда не вызывается один раз. Почему это так?
Более того, почему они не myarray.sort();
сортируются по алфавиту? Если бы это было сделано, я мог бы просто if (myarray[i]["className"] === myarray[i ]["className"]) {
проверить, равно ли значение следующему значению в массиве. Но сортировка не работает.
Редактировать:
Итак, при выполнении цикла я должен иметь возможность изменять css для каждого имени класса, верно?
for(var classname in classes) {
console.log(classes[classname].textSize);
var $val = $(classes[classname]);
$val.css({
"color" : "blue",
"fontSize": $val.textSize "px"
});
}
Это не работает, хотя console.log(classes[classname].textSize);
дает размеры текста для каждого элемента
Ответ №1:
Попробуйте использовать объект вместо массива, используя имена классов в качестве ключей:
var classes = {};
$("*").each(function() {
var classname = $(this).get(0).className;
var c = classes[classname] ||
(classes[classname] = { className: classname, textSize: 0 });
c.textSize = 5;
});
for(var classname in classes) {
console.log(classes[classname]);
}
Помните, что любой элемент может иметь несколько классов. Если вы хотите учесть это, вам придется разделить имена классов:
$("*").each(function() {
var classnames = $(this).get(0).className.split(' ');
for(var i=0; i<classnames.length; i ) {
var classname = classnames[i];
var c = classes[classname] ||
(classes[classname] = { className: classname, textSize: 0 });
c.textSize = 5;
}
});
Посмотрите эту демонстрацию: http://jsfiddle.net/FSBhv /
ОБНОВЛЕНИЕ: ОП пояснил, что он хочет установить размер текста для элементов на основе количества элементов, имеющих этот класс. Для этого потребуется несколько иной подход (на самом деле нам придется хранить элементы):
var eltsByClass = {};
$("*").each(function() {
var $this = $(this);
$this.get(0).className.split(' ').forEach(function(cname) {
var c = eltsByClass[cname] ||
(eltsByClass[cname] = []);
c.push($this.get(0));
});
});
for(var cname in eltsByClass) {
var elts = eltsByClass[cname];
$(elts).css('font-size', (elts.length 1) * 5 'px');
}
Комментарии:
1. Итан, ты можешь помочь мне понять, что здесь происходит?
var c = classes[classname] || (classes[classname] = { className: classname, textSize: 0 });
2. Конечно.
classes
это объект, который содержит запись (другой объект) для каждого найденного имени класса. Либо запись уже существует (classes[classname]
является правдивой иc
устанавливается на нее), либо она еще не создана, и в этом случае мы создаем и назначаем ее на том же шаге :classes[classname] = { className: classname, textSize: 0 }
.3. Хорошо, спасибо! Я обновил выше. Я пытаюсь установить css для имен классов. Чем чаще они встречаются, тем больше увеличивается размер текста для этого имени класса. По какой-то причине css не устанавливается
4. О, извините, эта часть была мне непонятна. Это немного более сложная проблема: сначала вы должны посчитать их все, а ЗАТЕМ установить их размер. Я обновлю свой ответ.
Ответ №2:
Храните свои данные в объекте, а не в массиве. И это можно упростить как:
var classes = {};
$("*").each(function() {
var classname = $(this).get(0).className;
classes[classname] = (classes[classname] || 0) 5;
});
for(var classname in classes) {
console.log(classname " textSize:" classes[classname]);
}
Комментарии:
1.
$(this).get(0).className
противthis.className
?
Ответ №3:
myarray.indexOf(myarray[i]["className"])
это проблема.
Вы знаете, что myarray
он содержит только объекты, но вы запрашиваете позицию строки в этом списке. Это никогда не вернет ничего, кроме -1
.
Рассмотрите возможность использования второго массива для хранения количества частот, вместо того, чтобы пытаться использовать оба myarray
.
var frequency = {};
myarray.forEach(function (i) {
frequency[i.className] = frequency[i.className] || 0
frequency[i.className] ;
}
Комментарии:
1. И что происходит, когда у меня есть
<div class="constructor">...</div>
? 🙂
Ответ №4:
Это поможет вам отсортировать массив в алфавитном порядке на основе classname
var myarray=[];
$("*").each(function()
{
classname = $(this).get(0).className;
myarray.push({"className" : classname, "textSize" : 5});
});
function compare(a,b)
{
if (a.className < b.className)
return -1;
if (a.className > b.className)
return 1;
return 0;
}
myarray.sort(compare);