1
0

なでしこで自身のDOM要素を削除したい

Posted at

はじめに

最近、こんなものを、日本語プログラミング言語「なでしこ」で作りたいと思った。
2024-08-31 12-15-55 (online-video-cutter.com).gif

追加ボタンは非常に簡単で、ラベル作成という命令を用いることで、比較的簡単に実現できる。

例えば、以下のようなプログラムを作成すると追加することができる。

index.html
<html>
    <body>
        <div id="result" style="text-align: center"></div>
        <div id="result2" style="text-align: center"></div>

        <script type="なでしこ">
        
            //ここになでしこのプログラムを書く
        
        </script>
        <script type="text/javascript" src="https://nadesi.com/v3/cdn.php?v=3.6.16&f=release/wnako3.js&run"></script>
    </body>
</html>
なでしこのプログラム
《カウント》に1を代入。
《要素リスト》は空配列。
「result」のDOM要素ID取得して、DOM親要素設定。
「追加」のボタン作成して、《追加ボタン》に代入。
「削除」のボタン作成して、《削除ボタン》に代入。
改行作成。

《追加ボタン》をクリックした時には
	「{《カウント》}番のラベルです」のラベル作成。
	それを《要素リスト》に配列追加。
	《カウント》=《カウント》+1
	改行作成。
ここまで

では、削除ボタンはどうすれば良いだろうか。

なでしこでDOM要素削除処理

調べてみるとDOM子要素削除という命令があると分かった。この命令は、親要素と子要素を指定し、子要素を削除するというものである。

これを使えば、出来るんじゃないかと考え、以下のようなプログラムを追加してみた。

なでしこのプログラム(追加1)
《削除ボタン》をクリックした時には
	もし、(《要素リスト》の要素数)が1以上なら
		《要素リスト》の0から1を配列取り出す。
		それ[0]をDOM要素削除処理。
	ここまで
ここまで


●(《要素》を)DOM要素削除処理とは、
	DOM親要素から《要素》をDOM子要素削除
ここまで

このプログラムは一見、正常に動くが、場合によっては正常に動作しない。つまり、関数DOM要素削除処理内で参照しているDOM親要素が途中で書き換わった場合には正常に動作しないのだ。このことは、これまでのなでしこのプログラムの最後に以下のようなプログラムを付け加えることで確認できる。

なでしこのプログラム(追加2)
15秒後には
	「result2」のDOM要素ID取得して、DOM親要素設定。
	「ーーーここからresult2ーーー」のラベル作成。
	改行作成。
ここまで

image.png

DOM親要素DOM子要素削除を使っていると、DOM親要素の書き換わる可能性があるプログラム内ではDOM要素を削除することが出来ない。

もちろん、自前でどのDOMがどのDOM親要素の子要素に当たるか、管理することで、適切に削除するプログラムを作成することも出来る。(面倒だけど)

JS実行を使って実現できないか

JavaScriptには自分自身の要素を削除するメソッドがある。こいつを呼び出すことが出来れば万事解決できそう。

ということで、なでしこのJS実行の出番である。

このJS実行の命令を用いて、以下のようなプログラムを試してみた。

なでしこのプログラム
●(《要素》を)DOM要素削除処理とは、
-	DOM親要素から《要素》をDOM子要素削除
+	「sys.__findVar("《要素》").remove()」をJS実行
ここまで

ただ、このプログラムは上手く動作しない。下記のページに書かれているように関数の引数として渡された削除対象の変数《要素》は、あくまでも関数内からのみ参照できる変数であり、グローバルスコープからは参照できないからである。

【2024年9月16日追記】
初稿作成時点(8月31日)では記事の通りでしたが、仕様変更があった(検討中?)ようです。Github上の動向に今後も注意してください。

とりあえず解決策

大人しく、プラグインを作る。DOM要素を削除するためだけに、プラグインをつくるのはどうかしてるかもしれないが、致し方無い。
以下のプログラム全文をコピーして、適当なhtmlファイルに貼り付けてやると最初のGIF画像のように上手く動く。また、後半部分に書かれているプラグイン本体を読み込むと、他のなでしこプログラム上でもDOM要素削除命令が実行できるようになる。配列に対しても操作可能なので、例えばDOM要素全取得タグ一覧取得と組み合わせても使用することが出来る。

index.html
<html><body>
<script type="text/javascript" src="https://nadesi.com/v3/cdn.php?v=3.6.16&f=release/wnako3.js"></script>
<div id="result" style="text-align: center"></div>
<div id="result2" style="text-align: center"></div>


<script type="なでしこ">

カウントに1を代入
要素リストは空配列
resultのDOM要素ID取得してDOM親要素設定
追加のボタン作成して、《追加ボタンに代入
削除のボタン作成して、《削除ボタンに代入
改行作成

追加ボタンをクリックした時には
	{カウント}番のラベルですのラベル作成
	それを要素リストに配列追加
	カウント=カウント+1
	改行作成
ここまで

削除ボタンをクリックした時には
	もし(要素リストの要素数)が1以上なら
		要素リストの0から1を配列取り出す
		それ[0]をDOM要素削除
	ここまで
ここまで

15秒後には
	result2のDOM要素ID取得してDOM親要素設定
	ーーーここからresult2ーーーのラベル作成
	改行作成
ここまで


</script>
<script type="text/javascript">
    //↓ここからプラグイン本体
	const plugin_delete_dom={
		"meta": {
			type: "const",
			value: {
				pluginName: "delete_dom",
				description: "DOMを削除するためのプラグイン",
				pluginVersion: "3.6.0",
				nakoRuntime: ["wnako"],
				nakoVersion: "3.6.0"
			}
		},
		"DOM要素削除": { // @DOMを削除する // @DOMようそさくじょ
			type: "func",
			josi: [["",""]],
			fn: function (el, sys) {
                //elとして、要素配列か要素が与えられると期待している
				if(Array.isArray(el)){
					el.forEach(e=>e.remove());
				}else{
					el.remove();
				}
			}
		},
	}
	if(typeof(navigator)==="object"){
		navigator.nako3.addPluginObject("plugin_delete_dom", plugin_delete_dom)
	}else{
		module.exports=pluginObj
	}
    //↑ここまでプラグイン本体&プラグイン登録処理
 
	navigator.nako3.runNakoScript();

</script>
</body></html>

参考ページ↓

おわりに

element.remove()を呼び出すだけのDOM要素削除は、公式でサポートしても良いんじゃないかと思う。

 

以上。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0