選択不可能文字列は、textarea要素の子要素にTextNodeを生成した時に発生したが、setAttribute()メソッドで、value属性値として生成してやると大丈夫だった。でもHTMLでは、textarea要素にvalue属性など無い筈なのでどうも腑に落ちない。
DOM(HTML)(邦訳)を見ると、JavaScriptを踏襲してか、HTMLTextAreaElementにはvalue Attributeが設定されていた。だから正しくは、Textarea.value = '文字列';でプロパティを書き換える形になるはず。それでもできたのだけれど、ともかくsetAttribute()はHTML要素の属性値を設定するメソッドなのだから、エラーとは言わないまでも何も起らないのが正しいのでは。同じくHTMLTextAreaElementには、form Attributeなんてのもあるが、Textarea.setAttribute('form', 'foo')とかは当然ながら無視されるわけだし。
Mozilla、Netscape6.1は、実装は整っているのにどうも表示が不安定。この件以外では、table rowを追加生成すると妙な隙間が出来たり、子要素を追加すると、親要素のborderがきちんと再描画されなかったり、pre要素が枠線をはみだしたり。そういえば、fieldset要素にposition:fixedで強制終了なんてのもあったっけ。
そう考えると、どんなにとんでもない事をしてもそれなりに表示してしまうIE5.5はすごいと思う(5.0はバグが目立った)。少なくとも今まで、CSSで強制終了などした記憶はない。CSSの配置関係が標準規格と異なっていたりすることは良くあるが、そういうのを差し引けば非常にレンダリング能力の優れたブラウザなのではないかと思う。
嫌なストレスが溜まってきたので、HTML Editorの方はしばらく凍結。
発見なのか、私が非常識だったのか。
<?xml version="1.0" encoding="ISO-2022-JP"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja"> <?xml version="1.0" encoding="ISO-2022-JP"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
例えば上のソースのある範囲を選択状態にしたいとき、ドラッグするのではなく、範囲の先頭をクリックし、Shiftキーを押しながら範囲の末尾をクリックすることでも可能なんです。これくらいの文字数ならどうでもいい話ですが、スクロールさせなきゃならない程たくさん文字がある場合には必要になります。
ブラウザでもこれが出来るとは思いませんでした。ちなみにテキストエディタなどと違うのは、単語の途中までを選択することが出来ないことです。
今まで私は、トリプルクリックがどういう挙動をするのか知りませんでしたが、どうやらHTMLの要素、それもブロック要素単位で選択状態にするようです。上のPRE要素の場合は少し特殊で、トリプルクリックした行、それ以下すべてを選択状態にするようです。
正しいマークアップの利点を、また一つ発見です。
少し実験してみます。「authorの意図する段落」の区切りを、p要素としてマークアップしたものと、単にbr要素で整形したものを書いてみます。
段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落
段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段
段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落
段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落段落
後者の例では、トリプルクリックでは「authorの意図した段落」が選択されません。(Windows + IE5.5)
まあ、トリプルクリックの概念がないNetscape系などには関係ないのですが、brで整形してふんぞり返っている誰かに
「トリプルクリックが役に立たなくなるじゃあないか!」
と文句を言うことができます。嫌われるかも知れませんが。
ブラウザの表示領域に選択不可能な文字列を作る方法をご紹介します。選択できそうで、どうしても出来ないという意地悪な裏技です。Mozilla0.9.3で確認。
-------HTML Source--------
<p>
<textarea cols="50" rows="7" id="myTextarea"></textarea>
</p>
-------Java Script--------
function nST(){
var oTextarea = document.getElementById('myTextarea');
var nText = document.createTextNode('選択不可能文字列');
oTextarea.appendChild(nText);
}
困った。編集も可能なtextareaだからこそイイんじゃあないか。取り敢えずpre要素で代用。\n(\r)を整形してくれるのはこれくらいしかないし。
以下のような構造のHTMLから、Document Object Modelでdivタグを取り除こうと思った。
<div class="section"> <h1>見出し</h1> <p>段落1</p> <p>段落2</p> </div>
ある要素を消去するには、その要素の親要素にアクセスして、メソッドremoveChild()を使う。しかしdivを消してしまったら、中身も消えてしまうので、div要素を消す前に中身(h1、p要素)を外に出さなければならない。
そこで、そのdivの子要素群(childNodes)をコピーしておこうと考えたが、childNodesは、NodeList型なので、コピーするためのメソッド、cloneNode()メソッドが使えない。どうしようか。まさか子要素一つ一つコピーしたり移植したりするわけにも行かない。
cloneNode()メソッドのパラメータはtrueかfalse。trueならなdivの中身のh1やらpやらも丸ごとコピーし、falseなら中身の子要素群は除外される。ダメだこれは。
仕方がないので、良い方法が見つかるまではその「まさか」で代用してみることにした。
見出し
段落1
段落2
function dappi(){
var d = document;
var elmLI = d.getElementById('dappiSample');
var nlChildren = elmLI.childNodes;
var elmUL = elmLI.parentNode;
while(nlChildren.length !== 0)
{
var child = nlChildren.item(nlChildren.length-1);
if(child.nodeName !== 'P') continue;
var clone = elmLI.removeChild(child);
elmUL.parentNode.insertBefore(clone, elmUL.nextSibling);
}
}dappi();
このIEの挙動は、DOMユーザを裏切るものだ。Mozillaは期待通り。まあそれはともかくとして、このスクリプトを、このページの全セクションに実行したら多分如何なるブラウザでもタダでは済むまい。
この逆、つまりセクションをさらにdivで内包(それも四重に)するスクリプトをこのページで実行してみたら、IEはフリーズした。それを遥かに凌ぐ処理量だもの。この脱皮スクリプトは。
<p>●見出し、リストなど、適切なHTML構造を用いて記述する。</p> <p>●「引用」タグを見栄えのために用いない。</p>
この方にとっては、これらの箇条がLI要素に見えないのだ。しかしそうだとすると行頭の●はなんなのだろうか。適切なHTML構造
とは、何か。簡単なことだと思っていたが、意識的であろうと思われる人ですらこうである。私は人を買いかぶっているのだろうか。
現在(2002-12-18)は修正されています。
Mozillaにてフォーカスされていた要素を非表示にしてしまうと、キーボード操作ではどうやってもフォーカスを操作できなくなる。ものすごく歯痒い。
でもこれってマウスが操作できない環境だったら、アプリケーションが操作不能になるような。F5も、Ctrl+Fも、ctrl+Wも、なにも出来ないんだから。Alt+Tabで切り替え直しても駄目。もしそういう環境だったら、自分だったらCtrl+Alt+Deleteで強制終了させるしか。単に画面をクリックすれば回復するのに、歯痒いったらありゃしない。
fieldset要素に、position:fixedを指定すると、Netscrpe6.1 Mozilla0.9.3が強制終了。
仕方ないからdivをかぶせた。DOM実験室にて。
しかし、始めにIEのDOMに慣れている(これが、結構VBテイストなのです)からか、これだけのスクリプトなのにかなり苦労しました。特に、イベントモデルがかなり違っていたので、そこの点は理解するまでに相当かかりました。これは、言うなればJavaのイベントモデルに近いクロージャを登録するものだったのですが、それに引数を渡せないのが一番苦労しました。実際に、どんな逃げに走ったかは、スクリプトをご覧下さい。
逃げ走ったどころか正攻法そのもの。トップページのスクリプトは非常に参考になるものだった。
要素ごとに属性や子要素に制限があるので、各要素それぞれの文法チェック用関数を作ることに。リファレンスを書く以上に大変だということが分かったものの、それ以上に面白いのでどうでもいい。
要素名の連想配列から関数を呼び出す方法を考えてみた。オブジェクト指向プログラム言語としてのJavaScriptが参考になった。とはいっても、オブジェクト指向(クラスや継承)というもののメリットはさっぱり分からないのだけど。何か、余程複雑なことをする時に必要なのだろうか。それはともかくとして。
var Check = new Object();
Check.P = function(){ …… }
Check.H1 = function(){ …… }
Check.BLOCKQUOTE = function(){ …… }
………………………
for(var i in Check){
if(tag_name == i){
Check[i]();
break;
}
}
tag_name(タグ名)が、Checkオブジェクトのメンバ名とかぶったら、その関数を実行(というか、メソッド名とかぶったらそのメソッドを実行)。Check.i()としてしまうとiを引数として扱ってくれないので、Check[i]()とする必要があった。でもこんな書き方して良いのだろうか。まあいいや。出来てるんだし。こういうのは書いておかないと絶対に後で意味不明になる。
TR要素を階層丸ごとコピーして
兄弟に追加すると、なんか得体の知れないモノがくっついてくる。normalizeメソッドというのが鍵を握っているのかも。隣接するテキストノードを無くすってことは、ソースレベルのタブ文字とか改行コードとかを消すってことになるのかな。そう読めるんだけど。
……違うみたいだ。getElementsByNodeName()って無いのか。nodeNameが#textのノードを全部消したい。改行とかタブ文字をノードに数えるのやめてくれよう。
……テキストノード全然関係なかったし。なんだよ、もう。分けわかんないよ。IEではうまくいってるのに。無駄っぽいけど一応、ソースレベルの改行、タブ文字などのテキストノードを取り除くヤツを書いてしまったのでしるす。
//obj : 親のーど
for(var i=0; i<obj.childNodes.length; i++){
if(obj.childNodes.item(i).nodeName == '#text')
obj.removeChild(obj.childNodes.item(i));
}
removeChild()っていうくらいだから、パラメータはitem(i)だけでも良いかと思ったら駄目だった。
結論。ただのバグだった。どうしようもない。TR要素を追加生成すると表示バグ。innerHTML見てみるときちんと生成されてるもの。
シャア専用fub入手。fub-liteの後継とのこと。ノーマルのIEはもう用無しか。
DOMで要素を消去したり置き換えたりする方法も見つかった。idか何かで参照して、直接消去するような方法は、確かに無い(見つからない)のだけど。ULの子要素(LI)の参照に関してIEとMozillaで判別せずに済む方法も分かった。childNodesではなく、getElementsByTagName('LI')でNodeListを参照。後者は、documentオブジェクトだけのメソッドだと勘違いしていた。これでやれそうなことの幅がかなり広がった気がする。
function replaceElement(text){
var parent = d.getElementById('testUL');
var refchild = parent.getElementsByTagName('LI').item(0);
var newchild = d.createElement('LI');
parent.replaceChild(newchild, refchild);
var nText = d.createTextNode(text);
newchild.insertBefore(nText, null); //または appendChild(nText);
}replaceElement('c');
あとはイベント関係。例えばonclick属性を持たない要素に、DOMでonclick属性をつけてやってもIEでイベントが発生しないという件。要素ごと生成するなら、innerHTMLメソッドで何とかなるものの、既に存在する要素の場合面倒なことになるし、innerHTMLは独自拡張ということで早く忘れてしまいたいというのもある。
取り敢えずHTML EditorはMozilla専用にしてみる。(見通しが立ったので)セクションだけではなく、DOCTYPE宣言から何から、全部生成するHTML Editorを作ることにした。User-Javascriptを併用すれば、テキストエディタを起動せずにHTMLの編集ができそう。テキストエディタは保存する時だけ使用。DOM Level2をサポートしてるというのは、かなり強力(Mozilla)。
document.implementation.hasFeature('HTML','2.0')
なんというか、掲示板に投稿するような気軽な感覚でHTMLを書きたいというのがあって、そりゃあCGIでやった方が良いに決まっているのだけれど、そのためだけに勉強するというのは素人には無意味だから。リロードを必要としないというのもかなりの魅力だし。
CSS EditorもIE対策でソースが自分でも見たくなくなるくらい酷いものになってしまった。手を加える気にならない。こちらはN6専用に変更。そもそもIEで表示確認を取るCSSエディタなんて、害悪そのものだった。
Windows起動直後に例外OEだの、保護違反だのの嵐。赤〜い、おどろおどろしいフォントでWindowsを終了する準備ができました
とかいうメッセージも。Nielsenが見たら発狂するだろう。基本的にユーザを小馬鹿にしている
セーフモードで起動して、レジストリの何とかというキーを虱潰しに調べたり、Step by step なんたらとかいう起動方法を何度も試したりしたものの、原因は特定できずに状況はますます悪化。Windowsを再インストールしてください
とかいうメッセージが出たときはちょっと観念した。
ハードウェアアクセラレータのつまみを低くしたら取り敢えず起動できるようになった。その後何もしてないのに完全に復旧。意味がさっぱりわからない。
前に作ってみた簡単な日記編集用のCGIをみたら、さっぱり理解不能になっていた。でもこれでPerlに手を出したら、またJavaScriptを忘れるのは目に見えている。
というわけで、DHTML版のHTML編集スクリプトの作成に取りかかります(取り敢えず自分専用)。
ともかく、一つ作ってみればCSS Editorに応用できるはず。idやクラスに対応するには、ユーザが要素を生成するしかないのだから。
取り急ぎ、擬似クラスの出力が間違っていたのを修正。ついでに子孫セレクタにも対応開始。そのうちidやclassにも対応できそう。
-(ハイフン)は使わないほうが良い。というより、半角英数字と_(アンダースコア)以外は使わない方が良い。id属性値は(少なくともJScriptでは)オブジェクト名になるから。「JavaScript%20カラーチャート」で検索をかけてみたものの、これといったものが見つからなかった。私が探してるのは、「暗くする」「明るくする」「濃くする」「薄くする」という、直感的な操作で数値が算出されるタイプ。もう一度しつこく調べて見つからなかったら自作。RGB値のままならいけるはず。16進数に変換するメソッドとかあったっけかな。って何故こだわる。ねむ。
IE5用のオンラインCSSエディタです。動作確認はWin+IE5.5sp1ですので、もしかするとIE5.01とか、IE6bとかは駄目かも知れません。もし要望があればNetscape6.1用も作りますが、Mozilla(0.9.3)はinsertRule()メソッドで強制終了するので不可能です。
リンク集 - Document Object Model -
もう少し追加する予定です。
Microsoft Accessibilityが、全12種類色とりどりのユーザースタイルシート配布を始めた模様。
*.exe だったのでどれ程のものなのかと思いきや、保存場所を指定するためのプログラムだった。
中身は恐らく全部これの設定値違い。時間損した。
BODY, TABLE, TR, TH, TD
{
font-size:100%;
color:white;
background-color:black;
}
B, I, U
{
font-weight:normal;
font-style:normal;
}
A:link
{
color:white;
}
A:visited
{
color:white;
}
H1, H2, H3, H4, H5, H6, FONT, DIV, SPAN
{
font-size:100%;
}
このスタイルシートでMicrosoft Accessibilityを見ると、どこがリンクだかサッパリ分からなくなる。MS-DOS風スタイルシート。
ZDNetエンタープライズ:受動的攻撃再び〜Webページを見るだけでレジストリを書き換え
今回の攻撃の問題は,「単にWebページにアクセスしていた」だけにもかかわらず,ユーザーが気づかないうちにJavaスクリプトが実行され,Windowsマシンのレジストリファイルが改変されてしまう点だ。そのページに悪意あるスクリプトが埋め込まれていても,見た目からは判断できない。
ZDNetエンタープライズ:受動的攻撃再び〜Webページを見るだけでレジストリを書き換え より
JavaScriptというより、JAVAでは。VMのセキュリティホールだという話だし。なんでもかんでもJavaScriptのせいにしないでもらいたいよ。document.applets[0].***()とかでHTML内のJAVAアプレットのメソッドを呼び出しているだけなんじゃないのかなぁ。JAVA自体は知らないけど。
「JavaScriptでレジストリが書き換えられる」と思われたらたまらない。
仮にJavaScriptをオフにしたとして、このケースは回避できても根本的な解決にはならないはず。というか、オフにする必要さえない。以下IEのセキュリティ設定。
1.は、JavaScriptとJAVAの関連性を断つらしい。
ジュピターテレコム、CATVインターネットの接続料を5800円に値下げ――ブランド名も“J-COM Broadband”に
どうかサービスの質が低下しませんように。