javascript初学者です。
以下のように、クリックイベントを取得し関数でwebページ内の文字列をDOMで置換しています。
JAVASCRIPT
1$(function(){ 2 $('.changebutton'),on('click',function(){ 3 文字列置換処理 4 }
書き換えられたwebページをリフレッシュ以外で元に戻したいのですがどういったアプローチが可能でしょうか。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
眠い…。
HTML
1<tagname class="restorable" data-original="hogehage">hogehage</tagname>
Javascript
1$(function(){ 2 $(".changebutton").on("click", function() 3 { 4 // 文字列置換処理 5 }); 6 7 $(".restore").on("click", function() 8 { 9 $(".restorable").each(function() 10 { 11 $(this).text($(this).data("original")); 12 return true; 13 }); 14 }); 15})();
投稿2018/05/19 22:58
編集2018/05/19 23:53退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2018/05/20 04:44
退会済みユーザー
2018/05/20 12:52
退会済みユーザー
2018/05/20 12:52
退会済みユーザー
2018/05/20 12:53
2018/05/22 05:37
退会済みユーザー
2018/05/22 11:25
2018/05/23 00:18 編集
退会済みユーザー
2018/05/23 12:14
2018/05/23 12:55
退会済みユーザー
2018/05/23 22:15
0
ベストアンサー
原則として、書き換える直前に「元の文字列」をバックアップします。
data-* 属性 -> input要素
.changebutton
がbutton関係要素の値を書き換えている事を意図しているように感じたので、input要素の書き換え版。
HTML
1<p><input type="button" class="target" value="Hello, World!"><input type="button" class="change1" value="change"><input type="button" class="reset1" value="reset"></p> 2<p><input type="button" class="target" value="Hello, World!"><input type="button" class="change1" value="change"><input type="button" class="reset1" value="reset"></p> 3<p><input type="button" class="target" value="Hello, World!"><input type="button" class="change1" value="change"><input type="button" class="reset1" value="reset"></p> 4 5<script> 6'use strict'; 7jQuery('.change1').on('click', function (event) { 8 var input = event.target.parentNode.querySelector('.target'); 9 10 console.dir(input.attributes['data-defaultvalue']) 11 12 if (!input.attributes['data-defaultvalue']) { 13 input.setAttribute('data-defaultvalue', input.value); 14 } 15 16 input.value = input.value.replace(/World/g, 'JavaScript'); 17}); 18 19jQuery('.reset1').on('click', function (event) { 20 var input = event.target.parentNode.querySelector('.target'); 21 22 if (input.attributes['data-defaultvalue']) { 23 input.value = input.getAttribute('data-defaultvalue'); 24 } 25}); 26</script>
data-* 属性 -> テキストノード
親要素にテキストノード値を保存する。
HTML
1<p>Hello, World!<input type="button" class="change2" value="change"><input type="button" class="reset2" value="reset"></p> 2<p>Hello, World!<input type="button" class="change2" value="change"><input type="button" class="reset2" value="reset"></p> 3<p>Hello, World!<input type="button" class="change2" value="change"><input type="button" class="reset2" value="reset"></p> 4 5<script> 6'use strict'; 7jQuery('.change2').on('click', function (event) { 8 var p = event.target.parentNode, 9 textNode = p.firstChild; 10 11 if (!p.attributes['data-defaultvalue']) { 12 p.setAttribute('data-defaultvalue', textNode.data); 13 } 14 15 textNode.data = textNode.data.replace(/World/g, 'JavaScript'); 16}); 17 18jQuery('.reset2').on('click', function (event) { 19 var p = event.target.parentNode; 20 21 if (p.attributes['data-defaultvalue']) { 22 p.firstChild.data = p.getAttribute('data-defaultvalue'); 23 } 24}); 25</script>
祖先要素にテキストノード値を保存する。
HTML
1<p class="parent">Good morning, World! <span>Hello, World!</span> Good evening, World!<input type="button" class="change3" value="change"><input type="button" class="reset3" value="reset"></p> 2<p class="parent">Good morning, World! <span>Hello, World!</span> Good evening, World!<input type="button" class="change3" value="change"><input type="button" class="reset3" value="reset"></p> 3<p class="parent">Good morning, World! <span>Hello, World!</span> Good evening, World!<input type="button" class="change3" value="change"><input type="button" class="reset3" value="reset"></p> 4 5<script> 6'use strict'; 7jQuery('.change3').on('click', function (event) { 8 var p = event.target.parentNode, 9 textNodeSnapshot = p.ownerDocument.evaluate('descendant::text()', p, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); 10 11 if (!p.attributes['data-defaultvalue']) { 12 var textList = []; 13 14 for (var i = 0, len = textNodeSnapshot.snapshotLength; i < len; ++i) { 15 var textNode = textNodeSnapshot.snapshotItem(i); 16 17 textList.push(textNode.data); 18 textNode.data = textNode.data.replace(/World/g, 'JavaScript') 19 } 20 21 p.setAttribute('data-defaultvalue', JSON.stringify(textList)); 22 } else { 23 for (var i = 0, len = textNodeSnapshot.snapshotLength; i < len; ++i) { 24 var textNode = textNodeSnapshot.snapshotItem(i); 25 26 textNode.data = textNode.data.replace(/World/g, 'JavaScript') 27 } 28 } 29}); 30 31jQuery('.parent').on('click', function (event) { 32 var input = event.target; 33 34 if (!input.classList.contains('reset3')) { 35 return; 36 } 37 38 var p = event.currentTarget; 39 40 if (p.attributes['data-defaultvalue']) { 41 var textList = JSON.parse(p.getAttribute('data-defaultvalue')), 42 textNodeSnapshot = p.ownerDocument.evaluate('descendant::text()', p, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null), 43 len = textNodeSnapshot.snapshotLength; 44 45 if (textList.length !== len) { 46 throw new Error; 47 } 48 49 for (var i = 0; i < len; ++i) { 50 textNodeSnapshot.snapshotItem(i).data = textList[i]; 51 } 52 } 53}); 54</script>
このコードは、要素とテキストノードが1対1でない場合に有効に働かない事を意味しています。
バックアップした後に動的にテキストノードが増減したら、破綻してしまうからです。
WeakMap -> テキストノード
WeakMap
を使う事でテキストノードに「元の文字列」を保存することが出来ます。
HTML
1<p class="parent">Good morning, World!<input type="button" class="change4" value="change"><input type="button" class="reset4" value="reset"> <span>Hello, World!<input type="button" class="change4" value="change"><input type="button" class="reset4" value="reset"></span> Good evening, World!<input type="button" class="change4" value="change"><input type="button" class="reset4" value="reset"></p> 2<p class="parent">Good morning, World!<input type="button" class="change4" value="change"><input type="button" class="reset4" value="reset"> <span>Hello, World!<input type="button" class="change4" value="change"><input type="button" class="reset4" value="reset"></span> Good evening, World!<input type="button" class="change4" value="change"><input type="button" class="reset4" value="reset"></p> 3<p class="parent">Good morning, World!<input type="button" class="change4" value="change"><input type="button" class="reset4" value="reset"> <span>Hello, World!<input type="button" class="change4" value="change"><input type="button" class="reset4" value="reset"></span> Good evening, World!<input type="button" class="change4" value="change"><input type="button" class="reset4" value="reset"></p> 4 5<script> 6'use strict'; 7(function () { 8 function handleClick1 (event) { 9 var input = event.target, 10 textNode = input.previousSibling, 11 wm = event.data; 12 13 if (!wm.has(textNode)) { 14 wm.set(textNode, textNode.data); 15 } 16 17 textNode.data = textNode.data.replace(/World/g, 'JavaScript'); 18 } 19 20 function handleClick2 (event) { 21 var input = event.target, 22 textNode = input.previousSibling.previousSibling, 23 wm = event.data; 24 25 if (wm.has(textNode)) { 26 textNode.data = wm.get(textNode); 27 } 28 } 29 30 function main () { 31 var wm = new WeakMap; 32 33 jQuery('.change4').on('click', wm, handleClick1); 34 jQuery('.reset4').on('click', wm, handleClick2); 35 } 36 37 main.call(this); 38}.call(this)); 39</script>
Re: KShiramiz さん
投稿2018/05/22 14:02
総合スコア18166
0
置換をしないで表示だけ入れ替える、というのはどうでしょうか。
html
1<div id="a">置換前</div> 2<div id="b" class="hide">置換後(実は置換していない)</div> 3<div id="change">置換する</div> 4<div id="undo">戻す</div>
js
1$('#b').hide(); 2$('#change').on('click',function(){ 3 $('#b').show(); 4 $('#a').hide(); 5}); 6$('#undo').on('click',function(){ 7 $('#a').show(); 8 $('#b').hide(); 9});
投稿2018/05/19 08:52
総合スコア36134
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2018/05/20 01:19
2018/05/20 23:59
2018/05/21 00:35
0
思いつく手法とその問題点を羅列してみました。
① 置き換え前のDOMを保存しておく。
- 置き換え前のDOMを保存したDOMを特定できる一意のKeyを用意する必要がある
- DOMを保存するのでコストが高い
- 正直スマートではない(笑
② 置き換え後の文字列が一意に特定できるものであれば現在の状態を判断して逆置換をかける
処理を実装する。
- 置き換え後の文字列が元の文字列に出現する場合、逆置換すると異なるDOMになってしまう。
③ DOMの文字列置換をそもそも止め、DOM自体の表示、非表示を切り替えることで同様の機能を実装する。
- 用途や書き方によってはhtmlソースやJavascriptが汚くなる。
④ 置き換え対象のDOMや文字列が決め打ちして問題無いものであれば決め打ちで置き換え処理、逆置換処理を実装する。
- 決め打ちになるので使えるケースが限られてくる。
など、普通過ぎてあんまり中身ないですね 汗
投稿2018/05/19 08:53
総合スコア98
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。