jQuery каждая буква в элементе div, случайный цвет из массива при наведении

Я пытаюсь заставить каждую букву в элементе div измениться на случайный цвет из массива цветов. Затем сбрасывайте, когда мышь уходит от div.

Вот что у меня есть до сих пор. Я думаю, что я довольно близок, за исключением того факта, что это на самом деле не работает. Это было построено из нескольких разных фрагментов на этом сайте.

$(document).ready(function() {

    // COLOURS ARRAY
    var colours = Array("#ddd", "#333", "#999", "#bbb"), idx;

    $("DIV#header").hover(function(){

        $( $(this).text().split('')).each(function(index, character) {
            idx = Math.floor(Math.random() * colours.length);
            $(this).css("color", colours[idx]);
        });

    }, function() {
        $(this).css("color","#ddd");
    });

});

Он не выдает никаких ошибок JS. 2-я функция наведения вроде работает, а не первая. Любая помощь будет принята с благодарностью!


person batfastad    schedule 23.09.2012    source источник
comment
Спасибо за указание на то, что каждый символ должен быть обернут в элемент, чтобы применить дискретные стили. Я думал, что каждая буква будет считаться отдельным узлом DOM и с ним можно будет манипулировать как таковым. Отличные ответы здесь!   -  person batfastad    schedule 24.09.2012


Ответы (4)


Строка не является элементом, и вы не можете добавить к ней свойство CSS. Вы можете поместить свои буквы в элементы span, а затем стилизовать их, попробуйте следующее:

$(document).ready(function() {

    // COLOURS ARRAY
    var colours = Array("#ddd", "#333", "#999", "#bbb"), idx;

    $('DIV#header').hover(function(){

        $('span', this).each(function(index, character) {
            idx = Math.floor(Math.random() * colours.length);
            $(this).css("color", colours[idx]);
        });

    }, function() {
        $('span',this).css("color","#ddd");
    });

}); 

http://jsfiddle.net/BC5jt/

person undefined    schedule 23.09.2012
comment
Вау, здесь есть действительно замечательные вещи. Все эти ответы когда-нибудь пригодятся. Спасибо за все предложения! На данный момент я думаю, что выберу это более простое решение и вручную оберну буквы в элементы span, так как это понадобится только для статического текста. Я бы хотел, чтобы количество JS было низким и пока оно было максимально простым. Спасибо всем за блестящие ответы, все проголосовали! - person batfastad; 24.09.2012

Вы можете только добавлять стили к элементам, оборачивать каждый символ в <span> и стилизовать диапазон.

#header {color: #ddd}​
<div id="header">Some text here</div>​
$(document).ready(function() {

    // COLOURS ARRAY
    var colours = Array("#ddd", "#333", "#999", "#bbb"), idx;

    $("#header").hover(function(){
        var header = $(this); 
        var characters = header.text().split('');
        header.empty();  
        var content = '';
        for(var i = 0; i < characters.length; i++) {
            idx = Math.floor(Math.random() * colours.length);
            content += '<span style="color:'+colours[idx]+'">' + characters[i] + '</span>'; 
        }
        header.append(content);
    }, function() {
        $(this).find('span').contents().unwrap();
    });

});

http://jsfiddle.net/vVNRF/

person Musa    schedule 23.09.2012

Как указывали другие, вы можете стилизовать только то, что является элементом, поэтому вам нужно обернуть каждую букву в свой собственный элемент. Вот пример того, как это сделать. Он также работает рекурсивно, поэтому он будет работать с текстом, который содержит другие элементы, такие как <b>, <a> и т. д. В других приведенных ниже примерах предполагается, что внутри div будет только текст и никаких других HTML-тегов.

var colours = Array("#ddd", "#333", "#999", "#bbb");

$('#header').hover(function(){
    wrapLetters(this);
    $('.random-color', this).css('color', function(){
        var idx = Math.floor(Math.random() * colours.length);
        return colours[idx];
    });
}, function(){
    $('.random-color', this).css('color', '#ddd');
});

// Wrap every letter in a <span> with .random-color class.
function wrapLetters(el){
    if ($(el).hasClass('random-color')) return;

    // Go through children, need to make it an array because we modify
    // childNodes inside the loop and things get confused by that.
    $.each($.makeArray(el.childNodes), function(i, node){
        // Recursively wrap things that aren't text.
        if (node.nodeType !== Node.TEXT_NODE) return wrapLetters(node);

        // Create new spans for every letter.
        $.each(node.data, function(j, letter){
            var span = $('<span class="random-color">').text(letter);
            node.parentElement.insertBefore(span[0], node);
        });

        // Remove old non-wrapped text.
        node.parentElement.removeChild(node);
    });
}

Скрипт: http://jsfiddle.net/aWE9U/2/

person loganfsmyth    schedule 23.09.2012
comment
Не возражаешь, если я сделаю из этого плагин, Логан? - person Matthew Johnson; 23.05.2014
comment
@MatthewJohnson Конечно, дерзайте, код полностью общедоступен. - person loganfsmyth; 23.05.2014
comment
Сладкий ... решил, что было бы лучше сначала проверить :), это будет на github, я обязательно упомяну вас. Спасибо! - person Matthew Johnson; 23.05.2014

Ну, это именно то, что сказал Муса, вы не можете применять стили к текстовым узлам, вам нужен элемент <span> вокруг каждого символа. Вот пример кода, который динамически добавляет интервалы:

$(document).ready(function() {

    // COLOURS ARRAY
    var colours = ["#ddd", "#333", "#999", "#bbb"], 
        idx;

    $("DIV#header").hover(function(){
        var div = $(this); 
        var chars = div.text().split('');
        div.html('');     
        for(var i=0; i<chars.length; i++) {
            idx = Math.floor(Math.random() * colours.length);
            var span = $('<span>' + chars[i] + '</span>').css("color", colours[idx])
            div.append(span);
        }

    }, function() {
        $(this).find('span').css("color","#ddd");
    });

});​

http://jsfiddle.net/Mv4pw/

person bfavaretto    schedule 23.09.2012