dポイントプレゼントキャンペーン実施中!

HTML の、テーブルのセルの可変について <th>や<td>などのボーダーをドラッグすると、
そのマウスの動作分だけ可変するものを Javascript で考えているのですが、
難しく思っているのは、セルのボーダーをクリックするといったロジックが浮かびません。
何か良い方法はありませんか ?

どうぞ、よろしくおねがいいたします。

A 回答 (2件)

こんなのはどうでしょう



<!DOCTYPE html><meta charset=utf-8><title>枠を摘んで表を変形</title>
<script>(function(){var _=0;
_ ; function A(a,i) { return Array.prototype.slice.call(a, i?i:0) }
_ ; function S(e) { return document.defaultView.getComputedStyle(e, '') }
_ ; var resizingContext = null;_ ;
_ ; function calcXY(e,x,y) {
_ , _ ; var M = 5, h, v;
_ , _ ; if (e instanceof HTMLTableCellElement) {
_ , _ , _ ; var col = e.cellIndex, row = e.parentElement.rowIndex;
_ , _ , _ ; h = (x < 0+M && 0 < col)? col-1: (e.offsetWidth-M <= x)? col: -1;
_ , _ , _ ; v = (y < 0+M && 0 < row)? row-1: (e.offsetHeight-M <= y)? row: -1;
_ , _ ; }
_ , _ ; if (e instanceof HTMLTableElement) {
_ , _ , _ ; h = (x < e.offsetWidth - M)? -1: e.rows[0].cells.length-1;
_ , _ , _ ; v = (y < e.offsetHeight - M)? -1: e.rows.length-1;
_ , _ ; }
_ , _ ; return (h >=0 || v >= 0)? {horizon:h, vertical:v}: null;
_ ; }
_ ; function resizeFirst(ev){
_ , _ ; if (resizingContext) return;
_ , _ ; var elem = ev.target, tab = ev.currentTarget, ctx = calcXY(elem, ev.offsetX, ev.offsetY);
_ , _ ; if (!ctx) return;
_ , _ ; ev.preventDefault();
_ , _ ; ctx.baseX = ev.pageX, ctx.baseY = ev.pageY;
_ , _ ; if (ctx.horizon >= 0) ctx.cellX = tab.rows[0].cells[ctx.horizon], ctx.width = parseFloat(S(ctx.cellX).width.replace(/px$/,''));
_ , _ ; if (ctx.vertical >= 0) ctx.cellY = tab.rows[ctx.vertical].cells[0], ctx.height = parseFloat(S(ctx.cellY).height.replace(/px$/,''));
_ , _ ; resizingContext = ctx;
_ , _ ; window.addEventListener('mousemove', resizeMid, false);
_ , _ ; window.addEventListener('mouseup', resizeEnde, false);
_ ; }
_ ; function resizeCursor(ev){
_ , _ ; var m = calcXY(ev.target, ev.offsetX, ev.offsetY);
_ , _ ; ev.currentTarget.style.cursor = m? 'move': 'auto';
_ ; }
_ ; function resizeMid(ev){
_ , _ ; if (!resizingContext) return;
_ , _ ; var m = resizingContext;
_ , _ ; if (m.cellX) m.cellX.style.width = Math.max(1, m.width + ev.pageX - m.baseX) + 'px';
_ , _ ; if (m.cellY) m.cellY.style.height = Math.max(1, m.height + ev.pageY - m.baseY) + 'px';
_ ; }
_ ; function resizeEnde(ev) {
_ , _ ; if (!resizingContext) return;
_ , _ ; window.removeEventListener('mousemove', resizeMid, false);
_ , _ ; window.removeEventListener('mouseup', resizeEnde, false);
_ , _ ; resizingContext = null;
_ ; }
_ ; window.addEventListener('DOMContentLoaded',function(){
_ , _ ; A(document.querySelectorAll('table[border]')).forEach(function(s){
_ , _ , _ ; s.addEventListener('mousedown', resizeFirst, false);
_ , _ , _ ; s.addEventListener('mousemove', resizeCursor, false);
_ , _ ; });
_ ; },false);
})()</script>
<style>
th, td { padding:0.5ex; }
</style>
<h1>枠を摘んで表を変形</h1>
<table border><caption>table #1</caption>
<thead><tr><th>name<th>flaggschiff<th>grade
<tbody><tr><td>Grillparzer<td>Eistla<td>Admiral
<tr><td>Knappstein<td>Ulfrun<td>Admiral
</table>
<h2>表が複数あっても大丈夫</h2>
<table border><caption>table #2</caption>
<thead><tr><th>name<th>flagship<th>grade
<tbody><tr><td>Morton<td>Achilles<td>Vice Admiral
<tr><td>Karlsen<td>Diomedes<td>Vice Admiral
</table>
    • good
    • 0

判別を簡単に行いたいのであれば、ひとつのアイデアとして・・・


セルのバックグラウンドカラーをボーダーに見せる方法がありそうです。

各セルの内側にmargin:2pxなどとして、div要素を入れて、実際の内容はその中に記す。
セル内かつdivの外側であればボーダー(に見える部分)をクリックしたことになります。

まぁ、この方法だと、本来のマークアップの目的とは少々異なってしまうので、なんですが・・・


通常のマークアップの場合で判定したければ・・・
クリックした時のマウスの位置を計算して、その位置がセルの外周でボーダー幅の中であればボーダーと判断する、といった方法が考えられるのではないでしょうか。
上記に比べると、スクリプトが少々面倒にはなりますが。


考えれば他にもありそうですが、とりあえず思いついた方法を。
    • good
    • 0
この回答へのお礼

私も似たようなスクリプトが浮かんでいました、
ただ、マークアップの作法が、たしかに気になります。
でもでも、ありがとうございました。

お礼日時:2015/03/12 21:14

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!