iT邦幫忙

0

IE、Firefox 可移動Div,但無法多選 Div 文字一起移動、及指定文字大小

makey 5 年前4299 瀏覽

請教先進們,下面有兩段 JavaScript 的程式碼。

第一段的 JavaScript 的程式碼,可以移動 Div 裡面的文字,經測試可在
IE、Firefox 兩種瀏覽器執行,但只能單獨移動 Div。

第二段的 JavaScript 程式碼,不但可以移動 Div 裡的文字,而且按Alt鍵可多選
Div 後一起移動、也可以將多選的 Div 同時指定文字大小。可是只能在 IE 瀏覽器
執行,無法在 Firefox 運作

想請問,如何修改第一段的程式碼,讓第一段能像第二段一樣:按Alt鍵可多選
Div 文字一起移動,以及將多選的文字指定文字大小(選取時出現邊框)等功能呢?

<html >

<title>移動 Div 裡面的文字(IE、Firefox) --> 可多選Div文字一起移動、指定大小(出現邊框)</title>

<style type="text/css">
.draggable{
font-size:10pt;
width:120px; height:25px;
position:absolute; cursor:pointer;
}
</style>

<script type="text/javascript">

var currLabels = [];

var rDrag = {
o:null,

init:function(o){
o.onmousedown = this.start;
},

start:function(e){
var o;
e = rDrag.fixEvent(e);
e.preventDefault && e.preventDefault();
rDrag.o = o = this;
o.x = e.clientX - rDrag.o.offsetLeft;
o.y = e.clientY - rDrag.o.offsetTop;
document.onmousemove = rDrag.move;
document.onmouseup = rDrag.end;
},

move:function(e){
e = rDrag.fixEvent(e);
var oLeft,oTop;
oLeft = e.clientX - rDrag.o.x;
oTop = e.clientY - rDrag.o.y;
rDrag.o.style.left = oLeft + 'px';
rDrag.o.style.top = oTop + 'px';
},

end:function(e){
e = rDrag.fixEvent(e);
rDrag.o = document.onmousemove = document.onmouseup = null;
},

fixEvent: function(e){
if (!e) {
e = window.event;
e.target = e.srcElement;
e.layerX = e.offsetX;
e.layerY = e.offsetY;
}
return e;
}
}

window.onload = function(){
var obj1 = document.getElementById('draggable1');
rDrag.init(obj1);

var obj2 = document.getElementById('draggable2');
rDrag.init(obj2);

var obj3 = document.getElementById('draggable3');
rDrag.init(obj3);

}
</script>

<div id="draggable1" class="draggable" style="position:absolute; z-index:5; left:300px; top:115px;">DIV_001</div>
<div id="draggable2" class="draggable" style="position:absolute; z-index:5; left:370px; top:175px;">DIV_002</div>
<div id="draggable3" class="draggable" style="position:absolute; z-index:5; left:210px; top:205px;">DIV_003</div>

第二段程式碼:

<meta http-equiv="Content-Type" content="text/html; charset=big5">

<title>按 Alt 鍵,對 Div 裡的 Label 文字進行多選,一起移動、改變字型大小(IE only)</title>

<style type="text/css">
.drag{
position:relative;
cursor:hand;
}
</style>

<script type="text/javascript">

/*** 文字移動(滑鼠)***/

var dragapproved = false;

var z, x, y, temp1, temp2;

/*** 當前選中的所有 labels ***/

var currLabels = [];

function move(){
if (event.button==1 && dragapproved){
for(var i=0; i<z.length; i++){
z[i].style.pixelLeft = temp1[i] + event.clientX - x[i];
z[i].style.pixelTop = temp2[i] + event.clientY - y[i];
}
return false;
}
}

function drags(){
if (!document.all)
return;

z=[]; x=[]; y=[]; temp1=[]; temp2=[];

for(var i=0; i<currLabels.length; i++) {
if (currLabels[i] && currLabels[i].className=="drag"){
dragapproved = true;
z.push(currLabels[i]);

temp1.push(currLabels[i].style.pixelLeft);
temp2.push(currLabels[i].style.pixelTop);

x.push(event.clientX);
y.push(event.clientY);

document.onmousemove = move;
}
}
}

document.onmousedown = function(){

var el = event.srcElement;

if(el.tagName.toUpperCase() == "BODY") { // 點到空白處,重置
while(currLabels.length > 0) {
chgBorder(currLabels.shift(), false);
}
}

else{
if(el.className && el.className=="drag") { // 點到可以托拽的label上
var isInSelected = false; // 此label是否已經被包含

for(var i=0; i<currLabels.length; i++) {
if(el == currLabels[i]) {
isInSelected = true;
break;
}
}

if(window.event.altKey){ // 如果按下 Alt 鍵,添加進去
currLabels.push(el);
}
else{
if(!isInSelected) { // 沒按下 Alt 鍵且不是之前選中的,則重選
while(currLabels.length > 0) {
chgBorder(currLabels.shift(), false);
}
currLabels = [el];
}
}

chgBorder(el, true);
event.cancelBubble = true;
drags();
}
}
}

document.onmouseup = function(){
dragapproved=false;
}

/*** 顯示邊框 ***/

function chgBorder(obj, b){
if(obj && obj.style){
if(b){
obj.style.border = "1px solid Lime";
}
else{
obj.style.border = "";
}
}
}

/*** 改變文字大小(單位:pt)***/

function chgSize(obj){
for(var i=0; i<currLabels.length; i++) {
if (currLabels[i]) {
currLabels[i].style.fontSize = obj.value +'pt';
}
}
}

</script>

<body onload="chgFonts();">

<div id="inner01" class="Text1" style="position:absolute; z-index:5; left:300px; top:115px;" >
<label id="id1" name="mycorp" class="drag" >Div_001</label>
</div>

<div id="inner02" class="Text1" style="position:absolute; z-index:5; left:370px; top:175px;">
<label id="id2" name="myname" class="drag" >Div_002</label>
</div>

<div id="inner03" class="Text1" style="position:absolute; z-index:5; left:210px; top:205px;" >
<label id="id3" name="mycorp" class="drag" >Div_003</label>
</div>

<form name="R1">

<select class="size" onChange="chgSize(this)" onclick="event.cancelBubble=true">
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
</select>

</form>

1 個回答

2
fillano
iT邦超人 1 級 ‧ 5 年前
最佳解答
&lt;pre class="c" name="code">


&lt;meta http-equiv="Content-Type" content="text/html; charset=utf8">
&lt;title>按 Alt 鍵,對 Div 裡的 Label 文字進行多選,一起移動、改變字型大小(IE only)&lt;/title>
&lt;style type="text/css">
.drag{
    position:relative;
    cursor:hand;
}
&lt;/style>
&lt;script type="text/javascript">
/*** 文字移動(滑鼠)***/
var dragapproved = false;

var z, x, y, temp1, temp2;

/*** 當前選中的所有 labels ***/
var currLabels = [];

function move(event){
    if(event) {
        var button = 0,event = event;
    } else {
        var button = 1,event = window.event;
    }
    var event = event||window.event;
    if (event.button==button && dragapproved){
        for(var i=0; i&lt;z.length; i++){
            z[i].style.pixelLeft = temp1[i] + event.clientX - x[i];
            z[i].style.pixelTop = temp2[i] + event.clientY - y[i];
        }
        return false;
    }
}

function drags(){
/*    if (!document.all) {
        return;
    }*/
    z=[]; x=[]; y=[]; temp1=[]; temp2=[];

    for(var i=0; i&lt;currLabels.length; i++) {
        if (currLabels[i] && currLabels[i].className=="drag"){
            dragapproved = true;
            z.push(currLabels[i]);

            temp1.push(currLabels[i].style.pixelLeft);
            temp2.push(currLabels[i].style.pixelTop);

            x.push(event.clientX);
            y.push(event.clientY);

            document.onmousemove = move;
        }
    }
}

document.onmousedown = function(event){

    var event = event||window.event;
    var el = event.srcElement;

    if(el.tagName.toUpperCase() == "BODY") {	 // 點到空白處,重置
        while(currLabels.length > 0) {
            chgBorder(currLabels.shift(), false);
        }
    } 
    else{
        if(el.className && el.className=="drag") {	 // 點到可以托拽的label上
            var isInSelected = false;	 // 此label是否已經被包含

            for(var i=0; i&lt;currLabels.length; i++) {
                if(el == currLabels[i]) {
                    isInSelected = true;
                    break;
                }
            }
            if(event.altKey){	 // 如果按下 Alt 鍵,添加進去
                currLabels.push(el);
            } 
            else{
                if(!isInSelected) {	 // 沒按下 Alt 鍵且不是之前選中的,則重選
                    while(currLabels.length > 0) {
                        chgBorder(currLabels.shift(), false);
                    }
                    currLabels = [el];
                }
            }
            chgBorder(el, true);
            event.cancelBubble = true;
            drags();
        }
    }
}

document.onmouseup = function(){
    dragapproved=false;
}

/*** 顯示邊框 ***/
function chgBorder(obj, b){
    if(obj && obj.style){
        if(b){
            obj.style.border = "1px solid Lime";
        } 
        else{
            obj.style.border = "";
        }
    }
}

/*** 改變文字大小(單位:pt)***/
function chgSize(obj){
    for(var i=0; i&lt;currLabels.length; i++) {
        if (currLabels[i]) {
            currLabels[i].style.fontSize = obj.value +'pt';
        }
    }
}
&lt;/script>


&lt;div id="inner01" class="Text1" style="position:absolute; z-index:5; left:300px; top:115px;" >
&lt;label id="id1" name="mycorp" class="drag" >Div_001&lt;/label>
&lt;/div>
&lt;div id="inner02" class="Text1" style="position:absolute; z-index:5; left:370px; top:175px;">
&lt;label id="id2" name="myname" class="drag" >Div_002&lt;/label>
&lt;/div>
&lt;div id="inner03" class="Text1" style="position:absolute; z-index:5; left:210px; top:205px;" >
&lt;label id="id3" name="mycorp" class="drag" >Div_003&lt;/label>
&lt;/div>
&lt;form name="R1">
&lt;select class="size" onChange="chgSize(this)" onclick="event.cancelBubble=true">
&lt;option value="8">8&lt;/option>
&lt;option value="9">9&lt;/option>
&lt;option value="10">10&lt;/option>
&lt;option value="11">11&lt;/option>
&lt;option value="12">12&lt;/option>
&lt;option value="13">13&lt;/option>
&lt;option value="14">14&lt;/option>
&lt;option value="15">15&lt;/option>
&lt;option value="16">16&lt;/option>
&lt;option value="17">17&lt;/option>
&lt;option value="18">18&lt;/option>
&lt;/select>
&lt;/form>

事件機制稍有不同,調整一下就可以動了,另外看起來event.button的定義也不一樣。

看更多先前的回應...收起先前的回應...
fillano iT邦超人 1 級 ‧ 5 年前 檢舉
&lt;pre class="c" name="code">&lt;select class="size" onChange="chgSize(this)" onclick="event.cancelBubble=true">

這一段我沒改,不過沒影響操作。

makey iT邦新手 4 級 ‧ 5 年前 檢舉

哇! fillano 前輩的回應,真是榮幸 & 開心阿。
謝謝 fillano 前輩的指導。經測試,IE正常,
但 Firefox 還是不能移動,正努力找原因。
應該不是版本的問題吧(FF版本_3.6.27)。

fillano iT邦超人 1 級 ‧ 5 年前 檢舉

看起來是因為Firefox不認識pixelLeft跟pixelTop,把它改成left跟top來做吧(要把字串中的單位去掉,例如px)

fillano iT邦超人 1 級 ‧ 5 年前 檢舉

再補充一下好了:

event.cancelBubble在新版的Firefox上應該沒作用了,可以先偵測event是否有stopPopagation方法,然後呼叫他。

return false在新版的Firefox上可能沒辦法取消預設動作觸發,可以先偵測event是否有preventDefault方法,然後呼叫他。(這樣拖曳時,才不會選取文字)

makey iT邦新手 4 級 ‧ 5 年前 檢舉

謝謝 fillano 前輩的教導。
修正程式碼,改為 left、top,也參考幾個網站,
但可能我程度還不夠,Firefox 仍沒反應,文字能無法移動。
實在不暸問題出在哪?不過我會不斷努力測試看看的。

fillano iT邦超人 1 級 ‧ 5 年前 檢舉

在FF8/10,ie7/9,chrome17測試過可以動的版本:
https://gist.github.com/1990693

可以比較一下差在哪裡。我懶得去處理style.left, style.top,所以交給parseInt處理。手邊沒有夠「舊」的IE可以測試,所以最多到IE7(而且其實是用IE9的模擬功能),IE6以下我就不知道可不可以執行了。

makey iT邦新手 4 級 ‧ 5 年前 檢舉

這版本可以執行耶! IE6 我測試也可以呢!真是厲害!!
感謝 fillano 前輩,您真的很棒。
JavaScript 我學一年多了,基礎的還可以,但要靈活運用還要努力,
希望能像您看齊,不斷地學習、發問才能成為達人。
最後想請教 fillano 前輩,學習 JS 的好書或您的方法?
再次地謝謝您。

fillano iT邦超人 1 級 ‧ 5 年前 檢舉

其實有問題大概都是在瀏覽器實作差異,而且主要是在DOM上...Javascript本身在各個瀏覽器上的相容性問題不大。

學習喔...我都是看書或文章以後有想法,就直接寫code,測試API的功能或做概念驗證等等。測試你的例子是test772b.html...所以目前大概做了這麼多(大多數是垃圾就是了)

書的話,我想應該要看作者。Crockford、Zakas、Resig、CCK等大神都有好書,涵蓋範圍廣的話,犀牛書(Javascript: The Definite Guide)也不錯。

另外,http://www.facebook.com/groups/javascript.tw/ <-這裡有很多高手出沒,我只是小咖...

makey iT邦新手 4 級 ‧ 5 年前 檢舉

高手都有空杯的心,因此才裝的下新的東西。
謝謝 fillano 的指導與學習心得,真的收穫好多。
希望台灣科技資訊界因有大家的努力,能更上層樓!!

我要發表回答

立即登入回答