質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

2回答

2133閲覧

JQueryでtableを利用したドットエディタを作り、PC、スマートフォン両方で動作させたい。

s-plus-s

総合スコア18

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

1グッド

1クリップ

投稿2016/05/06 02:08

編集2016/05/07 11:52

###前提・実現したいこと
jqueryでwordpress上にtableで方眼を作り、マスを塗りつぶすエディタを作っています。

iOS,androidでtouchmoveを動作させ、指でなぞったマス全てを塗りつぶしたいです。
また、違うテーブルの対応したマスも同時に塗りつぶします。
(.body_x またはsleeve_x)

それぞれのtableを塗ると対応した別のテーブルも同時にぬりつぶされる、というイメージです。

###発生している問題・エラーメッセージ

指をスライドさせても最初の1マスしか塗りつぶせません。 PCではクリックで1マスのみ塗る、ドラッグでなぞったマス全てを塗る両方実現できています。

###該当のソースコード

lang

1<div class="doteditor"> 2 <div class="dottlanslate"> 3 <table id="canvas" class="canvas body"></table> 4 </div> 5 <table id="palette"></table> 6</div> 7 8<div class="doteditor"> 9 <div class="dottlanslate"> 10 <table id="canvas3" class="canvas body"></table> 11 </div> 12 <table id="palette"></table> 13</div> 14 15<div class="doteditor"> 16 <div class="dottlanslate"> 17 <table id="canvas2" class="canvas body"></table> 18 </div> 19 <table id="palette"></table> 20</div> 21 22<div class="doteditor"> 23 <div class="dottlanslate"> 24 <table id="canvas4" class="canvas body"></table> 25 </div> 26 <table id="palette"></table> 27</div>

lang

1jQuery(function($) { 2 var isTouch = ('ontouchstart' in window); 3 var pals = ['000', '088', '00d', '438', '800', '888', '8cf', 'aa2', 'b82', 'c18', 'fbb', 'e00', 'fd0', 'feb', 'ddd', 'fff']; 4 var pushed = false; 5 var color = ''; 6 var text = 0; 7 8 var row = '<tr>'; 9 for (i = 0; i < 16; i++) row += '<td>&nbsp;</td>'; 10 row += '</tr>'; 11 12 for (i = 0; i < 16; i++) $('.canvas').append(row); 13 14 $('#canvas td').each(function(i){ 15 $(this).addClass('dot body_' + (i+1)); 16 }); 17 18 $('#canvas3 td').each(function(i){ 19 $(this).addClass('body_' + (i+1)); 20 }); 21 22 $('#canvas2 td').each(function(i){ 23 $(this).addClass('sleeve_' + (i+1)); 24 }); 25 26 $('#canvas4 td').each(function(i){ 27 $(this).addClass('sleeve_' + (i+1)); 28 }); 29 30 $('#canvas5 td').each(function(i){ 31 $(this).addClass('sleeve_' + (i+1)); 32 }); 33 34 35 $('#palette , #palette2').html(row); 36 for (i = 0; i < 16; i++) $('#palette td,#palette2 td').eq(i).css({backgroundColor: '#' + pals[i]}); 37 for (i = 0; i < 16; i++) $('#palette td,#palette2 td').eq(i).text(i); 38 for (i = 0; i < 16; i++) $('#palette2 td').eq(i).css({backgroundColor: '#' + pals[i]}); 39 for (i = 0; i < 16; i++) $('#palette2 td').eq(i).text(i); 40 41 42 $('td').each(function (i) { 43 i = i+1; 44 $('.body_' + i).bind('touchstart', function() { 45 event.preventDefault(); 46 this.pageX = event.changedTouches[0].pageX; 47 this.pageY = event.changedTouches[0].pageY; 48 pushed = true; 49 $('.body_' + i).text(text); 50 $('.body_' + i).css({backgroundColor: color}); 51 return false; 52 }).bind('touchmove', function(event) { 53 event.preventDefault(); 54 this.pageX = event.changedTouches[0].pageX; 55 this.pageY = event.changedTouches[0].pageY; 56 var touch = event.originalEvent.touches[0]; 57 var target = $(document.elementFromPoint(touch.clientX, touch.clientY)); 58 if (target.hasClass('dot')) $('.body_' + i).text(text); 59 if (target.hasClass('dot')) $('.body_' + i).css({backgroundColor: color}); 60 return false; 61 }); 62 }); 63 64 $(document).bind('touchup' , function() { 65 pushed = false; 66 }); 67 68 $('td').each(function (i) { 69 i = i+1; 70 $('.body_' + i).mousedown(function() { 71 pushed = true; 72 $('.body_' + i).text(text); 73 $('.body_' + i).css({backgroundColor: color}); 74 return false; 75 }).mousemove(function() { 76 if (pushed) $('.body_' + i).text(text); 77 if (pushed) $('.body_' + i).css({backgroundColor: color}); 78 return false; 79 }); 80 }); 81 82 83 $('td').each(function (i) { 84 i = i+1; 85 $('.sleeve_' + i).mousedown(function() { 86 pushed = true; 87 $('.sleeve_' + i).text(text); 88 $('.sleeve_' + i).css({backgroundColor: color}); 89 return false; 90 }).mousemove(function() { 91 if (pushed) $('.sleeve_' + i).text(text); 92 if (pushed) $('.sleeve_' + i).css({backgroundColor: color}); 93 return false; 94 }); 95 }); 96 97 $(document).mouseup(function() { 98 pushed = false; 99 }); 100 101 102 103 $('#palette td').click(function() { 104 $(this) 105 .css({borderColor: 'yellow'}) 106 .siblings() 107 .css({borderColor: 'gray'}); 108 color = $(this).css('background-color'); 109 text = $(this).text(); 110 }).eq(0).click(); 111 $('#palette2 td').click(function() { 112 $(this) 113 .css({borderColor: 'yellow'}) 114 .siblings() 115 .css({borderColor: 'gray'}); 116 color = $(this).css('background-color'); 117 text = $(this).text(); 118 }).eq(0).click(); 119 120 121});

lang

1table { 2 border-collapse: collapse; 3 margin-bottom: 16px; 4} 5td { 6 border: 1px solid gray; 7 width: 20px; 8 line-height: 20px; 9 cursor: pointer; 10 font-size: 9px; 11} 12 13.doteditor{ 14 position: relative; 15 width: 370px; 16 height: 400px; 17 z-index: 1; 18} 19 20.dottlanslate{ 21 width: 320px; 22 height: 320px; 23} 24 25.doteditor.table-parent{ 26 overflow: visible !important; 27} 28 29#canvas{ 30 position: absolute; 31 top: 0; 32 left: 0; 33 width: 320px; 34 height: 320px; 35 z-index: 5; 36} 37 38#palette{ 39 position: absolute; 40 top: 370px; 41 left: 0; 42 z-index: 5; 43} 44 45#canvas2{ 46 position: absolute; 47 top: 0; 48 left: 0; 49 width: 320px; 50 height: 320px; 51 z-index: 5; 52} 53 54#palette2{ 55 position: absolute; 56 top: 330px; 57 left: 0; 58 z-index: 5; 59} 60
kei344👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

ちょっと必要の無い処理が色々混じっているのでそのあたりも整えながら…

$('td').each(function (i) { i = i+1; $('.body_' + i)/*.bind('touchstart', function() { event.preventDefault(); this.pageX = event.changedTouches[0].pageX; this.pageY = event.changedTouches[0].pageY; pushed = true; $('.body_' + i).text(text); $('.body_' + i).css({backgroundColor: color}); return false; }) touchmoveイベントのみでOK */ .bind('touchmove', function(event) { event.preventDefault(); /*this.pageX = event.changedTouches[0].pageX; this.pageY = event.changedTouches[0].pageY; changedTouchesが拾え無いのでここでエラーが出ます。(originalEventで取得するためいりません) */ var touch = event.originalEvent.touches[0]; var target = $(document.elementFromPoint(touch.clientX, touch.clientY)); /*if (target.hasClass('dot')) $('.body_' + i).text(text); if (target.hasClass('dot')) $('.body_' + i).css({backgroundColor: color}); せっかくtaegetを取得したのに、ここで違う要素にcssを適用してしまっています。 */ if (target.hasClass('dot')) target.text(text); if (target.hasClass('dot')) target.css({backgroundColor: color}); //return false; いりません }); }); $(document).bind('touchup' , function() { //touchendでは?使ってないからどちらでも良いのかもしれませんが pushed = false; });

んん…?コメントアウトがうまく反映されませんね…。
テキストエディタかIDEへ貼り付けてご確認いただければと思います。

まとめつつ、自分だったらこうするかな?というコードも書かせていただきます。
(※5/7修正しました)

$('.dottlanslate td').on('touchmove', function(event) { event.preventDefault(); var touch = event.originalEvent.touches[0]; var target = document.elementFromPoint(touch.clientX, touch.clientY); if(target){ var cn = target.classList; // (IE10+) var drawTrg = $(target).hasClass('dot') ? '.'+cn[1] : '.'+cn[0]; if( !drawTrg.match(/body_|sleeve_/) ) return; $(drawTrg).text(text); $(drawTrg).css({backgroundColor: color}); } });
  • $('.dottlanslate td')に対してtouchmoveイベント(両方のパターンを一つのコードで。$.each(function)も変数iも無くせます)
  • event.originalEvent.touches[0]で現在座標を取得し
  • document.elementFromPoint(touch.clientX, touch.clientY)で現在座標にある要素を取得→変数targetへ代入
  • targetの存在確認で以後の処理を分岐(tableから外へ出たり等targetが取得できないことがあるので)

以後、targetが存在すれば

  • target要素のclassを取得し、塗りを適用する要素を、変数drawTrgへ
  • document.elementFromPoint()で要素を取得しているので、塗りを適用させたくない要素も取得してしまう。→'.body_'or'.sleeve_'で始まるクラスでなければreturnで処理を行わない。
  • drawTrgに代入された要素へcssを適用

という流れです。
結構回りくどい処理になってしまいましたね…。

また、
.bind()でmousedown,touchmove等をそれぞれ分けて書いてらっしゃいますが

$(selector).on({ 'mousedown: function(){ //mousedown時の処理 }, 'mouseup': function(){ //mouseup時の処理 }, 'touchmove': funtion(){ //touchmove時の処理 }, 'touchend':function(){ //touchend時の処理 } });

.on()を使って、まとめて記述することもできます。

投稿2016/05/07 08:30

編集2016/05/07 16:05
manabufukai

総合スコア700

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

s-plus-s

2016/05/07 11:50

動作しました!ありがとうございます。 ただ .body_i にcssを適用しようとしていたのは理由がありまして、片方のtableを塗るともう片方の対応したマスも塗りつぶされる、というものを作っていました。 現在touchmoveは効くようになったのですが、対応したべつのtableはマスが塗りつぶされないという状態です。 説明が足りず申し訳ありません、 とりあえず if (target.hasClass('dot')) target.text(text); if (target.hasClass('dot')) target.css({backgroundColor: color}); に if (target.hasClass('dot')) {target.text(text); $('.body_' + i).text(text);} if (target.hasClass('dot')) {target.css({backgroundColor: color}); $('.body_' + i).css({backgroundColor: color});} と追記してみました。 しかしタッチしていない方のtableのbody_iの最初の1マスは塗りつぶされるのですが、他が塗りつぶされません。(タッチした方はなぞっただけ塗りつぶされました。) if (target.hasClass('.body_' + i)) target.text(text); if (target.hasClass('.body_' + i)) target.css({backgroundColor: color});  としてみた場合は、両方のtable共に最初の1マスのみが塗りつぶされるようになりました。 説明が足りず申し訳ありませんでした。何か良い方法はないでしょうか?
manabufukai

2016/05/07 13:03 編集

ああ、なるほど、こちらこそ失礼いたしました。 (ちゃんと読めていませんでした。。) ええと、ちょっと勘違いをしていたようです。 ちなみに、 ・tableによってのdotの有無の違い ・.sleeve_x側はクラスは共通クラス無し ・これらの仕様は変更できるのか? となっていますが、これらの違いは何でしょう? これによって、処理の単純化ができるケースと面倒になるケースが分かれるので お教えいただけると幸いです。
manabufukai

2016/05/07 13:38 編集

すいません、大丈夫でした。 回答の「自分だったらこうするかな?というコード」の箇所を修正しましたので、そちらをご確認ください。 こんな感じでしょうか?
s-plus-s

2016/05/07 16:11

バッチリ動作しました! 「自分だったらこうするかな?」のコード、本当に勉強になりました。 ありがとうございました!
manabufukai

2016/05/07 16:18 編集

Re: s-plus-s さん 恐縮です、無事解決して何よりです。 ただ、(自分で書いておきながら)あんまり綺麗な処理じゃないかもしれません…。 後から後から気になって2,3回ほど直してしまいました…通知が何度も行ってしまっていたなら申し訳ございませんでした。。
guest

0

スタイルシートのz-index(重なり順)がどうなっているかわかりませんが、touch対象の.body_xが別の要素(#paletteが怪しい)に隠れてしまっていたりしませんか?
touchイベントが発生するのは最前面の要素だけです。

投稿2016/05/06 18:32

tozjp

総合スコア790

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

s-plus-s

2016/05/06 19:42 編集

回答ありがとうございます! cssを追記しました。 ```.body-x``` にz-indexを指定すると(z-indexを効かせるためにpositionを指定すると)tableが崩れてしまうので指定していません。 ```#palette``` 自体はtableには重ならないように```top:370px```を指定しています。 touchイベントは要素の位置関係にかかわらず z-indexの値が一番高い要素にのみ発生するという認識でよろしいでしょうか?
tozjp

2016/05/08 06:45

解決済みになっていますが、ご質問いただいているので回答します。 > touchイベントは要素の位置関係にかかわらず > z-indexの値が一番高い要素にのみ発生するという認識でよろしいでしょうか? いいえ、タッチとクリックは位置関係が重なっている場合のみ z-index が高い要素に発生します。 タッチ/クリックした座標にある要素の中で一番上でなければいけないということです。
s-plus-s

2016/05/08 14:59

理解できました、回答ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問