みかづきブログ その3

3ヶ月つづけてみました。

Androidで動的にdata属性を変更した際に、属性セレクタで指定したスタイルが適用されない時がある

DEMOをごらんください。


DEMO


JavaScript

var index = 0;
    
setInterval(function() {
    index = (index + 1) % 3;
        
    $("#box").attr("data-index", index);
}, 200);

HTML

<div id="box" data-index="0">
    <div class="face">٩( 'ω' )و</div>
</div>

SCSS

$length: 3;

#box {
    position: relative;
    width: 100px; height: 100px;
    
    @for $i from 0 through ($length - 1) {
        &[data-index="#{$i}"] {
            .face { // 【TODO】Androidで動かない機種あり
                left: $i * -10px;
            }
        }
    }
}

.face {
    position: absolute;
    padding-left: 20px;
    white-space: nowrap;
}


こちら、PCやiPhoneで見た時は動くのですが、一部Androidで見たときは動きません。
もろもろ探ってみたところ、data属性を動的に変更した要素の子要素がリペイントされていないことが原因のようです。


対策その1 変更する属性をクラスにする

JavaScript

var index = 0;
    
setInterval(function() {
    index = (index + 1) % 3;
        
    $("#box").attr("class", "c" + index); // classに変更
}, 200);

SCSS

$length: 3;

#box {
    position: relative;
    width: 100px; height: 100px;
    
    @for $i from 0 through ($length - 1) {
        &.c#{$i} { // classに変更
            .face {
                left: $i * -10px;
            }
        }
    }
}

.face {
    position: absolute;
    padding-left: 20px;
    white-space: nowrap;
}

DEMO



クラス属性を変更した際は子要素もしっかりリペイントされるようです。
というかしっかりリペイントして欲しいところです。


対策 その2 リペイントしてほしいDOMのstyle属性も変更する

JavaScript

var index = 0;
    
setInterval(function() {
    index = (index + 1) % 3;
        
    $("#box").attr("data-index", index);
    $(".face").css("opacity", 1); // リペイントしたいDOMのスタイル属性を変更
}, 200);

DEMO



動的にdata属性を変更したことで更新されてほしいDOMのstyleを変更することでも更新されるようになります。