【jQuery】 IEでhtml5要素を含む文字列をappend()するとcssが適応されない問題を解決!
どういうことかというと。
【jQuery】html5要素を含む文字列をappend(), とは以下のこと。
$("ul").append("<li><article>俺のスタイル貫くぜ</article></li>");
こうするとarticle要素のcssが適応されていない!( IE8 or lower )
ちなみに、
おんなじappendでもjQueryオブジェクトをappend、
$("ul").append( $(document.createElement("li")).append( $(document.createElement("article")).text("俺のスタイル貫くぜ") ) );
これは、うまくいく。
appendChild自体はうまくいくかどうかやってみるんだけど、
var html5Element = document.createElement("article"); html5Element.innerHTML = "俺のスタイル貫くぜ"; $("ul").get(0).appendChild( document.createElement("li").appendChild(html5Element) );
これもうまくいく。
article部分だけ文字列にしてみると、
$("ul").append( $(document.createElement("li")).append('<article>俺のスタイル貫くぜ</article>') );
うまく行かない。(cssのスタイルが適応されない!スタイル貫けや。)
ということはやっぱり、
IEでhtml5要素を含む文字列をjQueryのappendしたときにcssが適応されない
のだ。
番外編として
$("ul").get(0).innerHTML='<article>俺の(ry</article>';
とか
$("ul").get(0).innerHTML='<ARTICLE>俺の(ry</ARTICLE>';
とかはちゃんとcssスタイル適応された。
※ちなみにhtml5.jsというのをつかってます。これによってIEでもhtml5要素を描画できるようになるはずなのです。
原因
この原因をさぐろーとして、jQueryの中身を見てみた。(jQuery-1.4.2)
jQueryは、jQuery.clean() というメソッドでhtml文字列をDOMに変換している。
その方法は、おおざっぱに書いちゃうとこんな感じ。
/* 実際のjQueryのソースではない!けど、ソースの4447行目ぐらいの話 */ var div = document.createElement("div"); div.innerHTML = elementString; // elementStringてのは文字列表現のhtml. "<li>aiu</li>"とか。 var elems = div.childNodes; // このelemが変換後のDOMElementsである!
IEだと
$("ul").get(0).appendChild(elems[0]);
でうまくいかなかった。
javascriptでrgb(r, g, b)を16進数に変換するワンライナー
こんにちは。ワンライナー好きの@m1m0r1です。
jQueryのcssメソッドで色を取得したとき、rgb表示を#rrggbb形式に変換したくて困ったことはありませんか?
そんなときはこの関数を使ってみてください!
rgbTo16 = function(col){ return "#" + col.match(/\d+/g).map(function(a){return ("0" + parseInt(a).toString(16)).slice(-2)}).join(""); }
使い方は以下のような感じです。
> alert( rgbTo16("rgb(255, 0, 255)") ); "#ff00ff" > alert( rgbTo16("rgb(100, 240, 1)") ); "#64f001"
JavaScriptのStyleSheetオブジェクトのcssTextはReadOnly(読み込み専用)
前回の記事に関連して。
css:
/* hoge.css */ #hoge { width: 200px; }
これを
<head> <link rel="stylesheet" href="hoge.css" /> </head>
で読み込んで
//スタイルシートオブジェクトの取得! var css = document.styleSheets[0]; // ルールの取得 var rules = css.cssRules || css.rules; // クロスブラウザな意味で。 rules.cssText ="#hoge {width: 20px; }"; // 値を代入 console.log(rules.cssText);
こう書いておくと、
#hoge { width: 200px; }
と表示される。
セットされてない。
element.style.cssTextはセット可能なのに。
http://help.dottoro.com/ljiiimpl.php
に、
The CSSValue.cssText and rule.cssText properties are read-only, all others are read/write.
と書いてあった。
cssに規定されていないプロパティをJavaScriptから取得できるのか
cssのルールとして規定されていないプロパティをcss内に書いたら、
それはJavaScriptからとれるんだろうか、とふと思った。
cssはこんな感じ。
/* hoge.css */ #hoge { width: 200px; /* 普通に指定 */ shinout: cool; /* computedStyleにはないプロパティの指定 */ }
で、これを
<head> <link rel="stylesheet" href="hoge.css" /> </head>
で読み込んで
//スタイルシートオブジェクトの取得! var css = document.styleSheets[0]; // ルールの取得 var rules = css.cssRules || css.rules; // クロスブラウザな意味で。 alert(rules[0].cssText);
こう書いておく。
すると、
#hoge { width: 200px; }
と表示される。
そりゃそうか。
shinout: cool;
という事実は見事に葬り去られた。
悲しい。
ゴミCSSをブラウザがはじいてからDOMモデルに値を設定してるってことさ。
と、思ったがここは大人気アイドルIE先生。
IE先生でやったら、どうやら、
document.styleSheets[0].rules[0].cssTextなるものは存在しないようで、
document.styleSheets[0].rules[0].style というプロパティがあった。
これを見てみると・・・
[width] 200px [shinout] cool
となっているではないか!
shinout is cool!
IEでは、意味のないCSSプロパティをとることができたぞーーー!
これができると、
css3のプロパティ名とかもhtcファイルで取得して
擬似的に再現できちゃいそうですねー!
まさにIEに一番必要な機能だわこれ!
世界一難しい数独を解くJavaScript
数学者が作った世界一難しい数独がこちらに掲載されています。
http://headlines.yahoo.co.jp/hl?a=20100824-00000018-zdn_g-ent
世界一難しい数独があるという話を聞いて、素手で解いてみました。
・・・無理です。
すべすべの壁を登れといってるようなものです。
しかし、自分にはプログラミングがある!
やつなら、なんとか解けるに違いない!
ということで書いてみました。
http://jsdo.it/shinout/sudoku/fullscreen
何をしているか、なんですが、
結局は
各マスの候補となるものを取得する
各ルール(縦、横、箱)のなかで候補の数が一つだけの数字を検出して代入
各ルール(縦、横、箱)のなかで候補の数が2、3つだけの数字を検出してヒントに使う
膠着状態になったら、2択の部分を決めちゃって、エラーが起きたらもう片方を選択。
これをやってるだけです。
2択の部分を決めちゃうのは、はっきり言ってルール違反なんですが、
さっさと答えが知りたかったんです。
論理だけで解けるというやり方があったら、教えてほしいです!
CSS3のtransformで要素のサイズを左寄せで縮める。
CSS3のtransformというのはすごく便利。
-moz-transform: scale(0.5); -webkit-transform: scale(0.5);
これで要素が半分の大きさになります。
しかしこれだと要素が真ん中で小さくなるので、左詰めできません。
こういうときは、
-moz-transform: scale(0.5) translate(-100px, -100px); -webkit-transform: scale(0.5) translate(-100px, -100px);
のようにすればいいんです。
これは全体の大きさが200px,200pxのときです。
中央から左詰めに移動するときの距離は50px,50pxなんですが、
translateで移動する値を指定するときは、
scaleする前の値で計算してからscale倍にして移動するようです。
注意しましょう。
pythonでジェネレータを使って順列を小さい順に出力してみる
@shinoutです。
こないだ、phperのためのGAE勉強会に行ってきて、python学んできました。
そんなわけでpythonでジェネレータを使って何か書いてみようと思い、
1-nまでの数字の順列を小さい順に出力するプログラムを書いてみました。
ええと、たとえば
3 を入れると
[1,2,3]
[1,3,2]
[2,1,3]
[2,3,1]
[3,1,2]
[3,2,1]
が for文で取得できるような感じです。
#-*- coding: utf-8 -*- def order(k): # 1-kまでの数字リストを小さい順に出力する。 def orderGenerator(li): # 1-kまでのリストを引数にとり、それらを小さい順に出力してゆくジェネレータ n = len(li); def order0(li): # 再帰の初期値のための関数。 yield li raise StopIteration def order1(li): # 再帰ロジック。 defaultLi = li[:] # もともといれてくれた配列 haveToPop = 0 # popするべきインデックス位置 while haveToPop < n: li = [ defaultLi[haveToPop] ] + defaultLi[:haveToPop] + defaultLi[haveToPop+1:] # ここでliは、haveToPop == 3 で[3,1,2,4]、 haveToPop == 4 で[2,1,3,4]とかになってる。 o = orderGenerator(li[1:]) for childLi in o: li[1:] = childLi yield li haveToPop = haveToPop+1 raise StopIteration(li) return eval("order%s(li)" % min(n, 1)) # order0 か order1 を呼び出す。 return orderGenerator(range(1,k+1)) o = order(4) for li in o: print li
ジェネレータの再帰、というロジックは結構ありそうですね。