sikaku

上記記事からjQueryを抜いて、ちょっと機能を足した版です。

所謂夢界隈に足を踏み入れたことがないエアプ人間なので(本当にごめんなさい)使用感はわかりませんが、多分そこそこ便利……?なのではないでしょうか。

また、当ページは上記記事と差し替え予定の為、URLでの共有を推奨しません。

source code

demo

demo

設定中:見本 例子

私の名前はだ。 名前については設定でどうとでも変わる為、ここでは省略する。
現在、見本テキストとしての役目を全うしているところだ。

HTML

HTML
  1. <div>
  2. <input type="text" data-text="" />
  3. <input type="text" data-text="" />
  4. <input type="submit" id="changeSet" value="SET" />
  5. <input type="submit" id="changeClr" value="CLEAR" />
  6. </div>
  7. <p>設定中:見本 例子</p>
  8. <p class="sample-txt">私の名前は<span data-text=""></span><span data-text=""></span>だ。 名前については設定でどうとでも変わる為、ここでは省略する。<br />現在、<span class="no-change">見本</span>テキストとしての役目を全うしているところだ。</p>
  • 灰色の文字色部分は無視して構いません。
  • 処理に使用している要素もHTMLのルールに則っていれば他にどんな属性を足しても問題ありません。
設定フォーム
入力欄

例:

input要素にdata-text="key"属性を付与してください。

  • keyに対応した入力欄として扱われます。
  • 同一のkeyに対応したinput要素が複数ある状態で設定ボタンを押した場合、一番最後の入力欄の内容が採用されます。
  • type属性値は何でも構いませんが、上記の理由とチェック有無を確認する処理は挟んでいない為、radio,checkbox等複数設置する前提のものは推奨しません。(需要があれば対応策を出します)
決定ボタン

例:

お好きな要素にid="changeSet"属性を付与してください。

初期化ボタン

例:

お好きな要素にid="changeClr"属性を付与してください。

テキスト部分
置き換え対象テキスト

例:見本例子部分

特にHTMLによるマークアップは不要で、default部分を閲覧者が設定したテキストと置き換えます。

置き換え拒否

例:

お好きな要素にno-changeクラスを持たせてください。

  • 要素内に置き換え対象テキストがあっても無視します。
  • HTMLでマークアップ

    例:

    input以外の要素にdata-text="key"属性を付与してください。

    • 内部テキストをkeyに対応したテキストと入れ替えます。
    • 置き換え対象テキストの探索範囲外にあってもHTMLでマークアップされている場合、置き換え対象になります。

JavaScript

JavaScript
  1. <script src="//cdn.jsdelivr.net/gh/nn-3/text-changer/main.min.js"></script>
  2. <script>
  3. textChanger({
  4. '': '見本',
  5. '': '例子'
  6. });
  7. </script>
関数について

で読み込めるようにしています。

変換設定

例:

textChanger({});{}間に'key':'default',区切りで必要数記述してください。

その他設定

後述、関数 textChanger について を参照してください。

関数 textChanger について

関数

JavaScript
  1. function textChanger(dflt,opt) {
  2. let on = 'addEventListener';
  3. let $d = document;
  4. let $id = id => (id instanceof HTMLElement)?id:$d.getElementById(id);
  5. let tc = textChanger;
  6. let set = Object.assign({
  7. setBtnId: 'changeSet',
  8. clrBtnId: 'changeClr',
  9. areaId: null,
  10. btnEvent: null,
  11. storage: 'session',
  12. path: 'textChanger',
  13. attr: 'data-text',
  14. word: 'default'
  15. },opt||{});
  16. let keys = Object.keys(dflt);
  17. let data = Object.create(dflt);
  18. let storage, sF = set.storage!==null;
  19. if(sF) {
  20. storage = window[set.storage+'Storage']||window.sessionStorage;
  21. data = Object.assign(data,JSON.parse(storage.getItem(set.path))||{});
  22. }
  23. function setting(){
  24. let $area = $id(set.areaId)||$d.body;
  25. let $set = $id(set.setBtnId);
  26. let $clr = $id(set.clrBtnId);
  27. let $list = {};
  28. let bET = typeof set.btnEvent;
  29. let bF = !!$set||!!$clr;
  30. let iF = false;
  31. let lF = bF && (bET=='function'||!sF);
  32. let nF = Array.isArray(tc.nodes);
  33. for(let k of keys){
  34. $list[k] = {};
  35. if(lF) $list[k].node = [];
  36. }
  37. $d.querySelectorAll('['+set.attr+']').forEach($e=>{
  38. let k = $e.getAttribute(set.attr);
  39. if(keys.indexOf(k)<0) return;
  40. if($e.tagName=='INPUT'){
  41. if(!bF) return;
  42. $e.value = data[k];
  43. $list[k].input = $e;
  44. iF = true;
  45. } else {
  46. $e.textContent = data[k];
  47. if(lF) $list[k].node.push($e.childNodes[0]);
  48. if(nF) tc.nodes.push($e.childNodes[0]);
  49. }
  50. });
  51. if(!!set.word) {
  52. let t = set.word.match(/key|default/);
  53. if(t){
  54. let regEsc = str => str.replace(/[\-\/\|^$*+?.(){}\[\]]/g,'\x5c$&');
  55. let wP = (e,k) => {w[e]=k;reg+=(reg.length?'|':'')+regEsc(e)};
  56. let w={},reg='';
  57. let rTN, rTNs = $elm =>{
  58. let ns = Array.from($elm.childNodes);
  59. for(let n of ns){
  60. if(n.nodeType==1&&!n.matches('script,['+set.attr+'],.no-change')) rTNs(n);
  61. else if(n.nodeType==3) rTN(n);
  62. }
  63. }
  64. if(t[0]=='key') for(let k of keys) wP(k,k);
  65. else for(let k of keys) wP(dflt[k],k);
  66. reg = regEsc(set.word).replace(t[0],'('+reg+')');
  67. if(lF||nF) {
  68. reg = RegExp(reg);
  69. rTN = n =>{
  70. if(nF&&tc.nodes.includes(n)) return;
  71. let m = n.nodeValue.match(reg);
  72. if(!!m){
  73. let l = m.index+m[0].length;
  74. if(m.input.length!=l) rTN(n.splitText(l));
  75. let nn = !m.index?n:n.splitText(m.index);
  76. if(lF) $list[w[m[1]]].node.push(nn);
  77. if(nF) tc.nodes.push(nn);
  78. nn.nodeValue = data[w[m[1]]];
  79. }
  80. }
  81. } else {
  82. reg = RegExp(reg,'g');
  83. let rep = (s,k) => data[w[k]]||s;
  84. rTN = n => n.nodeValue = n.nodeValue.replace(reg,rep);
  85. }
  86. rTNs($area);
  87. }
  88. }
  89. if(iF&&bF){
  90. let iEach = fnc =>{
  91. for(let k of keys) if(!!$list[k].input) fnc(k,$list[k].input);
  92. }
  93. let sSet = sF?()=>{
  94. if(Object.keys(data).length) storage.setItem(set.path,JSON.stringify(data));
  95. else storage.removeItem(set.path);
  96. }:()=>{};
  97. let bEv = lF?(type,obj)=>{
  98. iEach((k,$i)=>{
  99. $i.value = obj[k];
  100. $list[k].node.forEach(n=>n.nodeValue=obj[k]);
  101. });
  102. if(bET=='function') set.btnEvent(type,data,dflt);
  103. }:bET=='string'?()=>{location.href=set.btnEvent}:()=>{location.reload()};
  104. if(!!$set) {
  105. $set[on]('click',()=>{
  106. iEach((k,$i)=>data[k]=$i.value);
  107. sSet();
  108. bEv('set',data);
  109. });
  110. };
  111. if(!!$clr) {
  112. $clr[on]('click',()=>{
  113. iEach(k=>delete data[k]);
  114. sSet();
  115. bEv('clr',dflt);
  116. });
  117. }
  118. }
  119. }
  120. if($d.readyState=='loading') $d[on]('DOMContentLoaded',setting);
  121. else setting();
  122. }

下記URLでCDNサーバーから読み込めるようにしてもらっています。 サービス可動状況について当サイトは関与できないので、自前で全て管理したい方は上記でJavaScriptファイルを作成し、読み込ませてください。

呼び出し

textChanger(変換設定,その他設定)

  • 引数の変換設定その他設定は双方連想配列を持たせてください。

その他設定

JavaScript
  1. textChanger({
  2. '': '見本',
  3. '': '例子'
  4. },{
  5. setBtnId: 'changeSet', // フォームの決定ボタンid
  6. clrBtnId: 'changeClr', // フォームの初期化ボタンid
  7. btnEvent: null, // 上記ボタンを押した際に呼び出すイベント
  8. areaId: null, // 置き換え対象テキストの探索範囲のid
  9. storage: 'session', // ストレージの選択
  10. path: 'textChanger', // ストレージ保存に使うパス
  11. attr: 'data-text', // HTML側で使う属性名
  12. word: 'default' // 置き換え対象テキスト
  13. });
  • 第二引数に持たせた連想配列で、変換に関する設定を指定できます。
  • 初期値から変更したい項目のみを指定してください。
  • 全項目初期値のままでいい場合、第二引数自体を省略できます。
  • 上記は初期設定の再指定なので言ってしまえば完全に無駄です。
setBtnId フォームの決定ボタンid
初期値
'changeSet'
文字列

HTML側のidを他に変更したい場合に指定してください。

clrBtnId フォームの初期化ボタンid
初期値
'changeClr'
文字列

HTML側のidを他に変更したい場合に指定してください。

btnEvent 上記ボタンを押した際に呼び出すイベント
初期値
null
下記いずれか
null
ページ再読込
文字列
文字列をパスとするページへ遷移
関数
関数呼び出し、ページの再読込,遷移は無し
areaId 置き換え対象テキストの探索範囲
初期値
null
下記いずれか
null
body要素内を探索
文字列
文字列をidとする要素内を探索

HTML要素でマークアップしていなくても置き換えられるテキストの探索範囲を指定できます。

指定しておいた方が探索範囲が限定されるので処理の高速化が見込めます

storage ストレージの選択
初期値
'session'
下記いずれか
'session'
セッションストレージを選択
'local'
ローカルストレージを選択
null
ストレージ使用無し(入力内容の反映はそのページのみ、再読込含むページ移動後は保持無し/btnEventの値に関係なくそのページに留まる)
path ストレージ保存に使うパス
初期値
'textChanger'
文字列
attr HTML側で使う属性名
初期値
'data-text'
文字列(HTML属性名として問題のないもの)

入力欄や文字の置き換えを行うHTML要素に付与する属性名を設定できます。

ここで指定した属性を持つ要素内も置き換え対象テキストの探索範囲外になるので、その辺りも踏まえて変更してください。

基本的に本スクリプト専用の属性であると想定して処理させています。

word 置き換え対象テキスト
初期値
'default'
下記いずれか
null
マークアップ外のテキストを置き換えしない
文字列
keydefaultどちらかを含む

設定テキストと自動で置き換える文字列を設定できます。

文字列中のkeydefault部分はそれぞれ変換設定側で指定したkeydefaultの文字列と置き換えた上で探索します。

JavaScript
  1. textChanger({
  2. '': '見本',
  3. '': '例子'
  4. },{
  5. word: '#key#'
  6. });

HTML上での置き換え対象テキスト:#姓##名#

上記から'#key#'部分を置き換えた場合の例
HTML上での置き換え対象テキスト
見本例子
'default'見本例子
'#key#'#姓##名#
'「default」'「見本」「例子」
'[write:key]'[write:姓][write:名]
'keydefault'姓default名default
'defaultkey'見本key例子key

jQuery版と設定を同一にする

JavaScript
  1. textChanger({
  2. '名称1': 'デフォ1',
  3. '名称2': 'デフォ2'
  4. },{
  5. word: '#key#',
  6. path: 'textchanger',
  7. btnEvent: ()=>{}
  8. });

関数呼び出し部分を上記にすることで、jQuery版との互換性を持たせられます。