จะใช้ z-index ในองค์ประกอบ svg ได้อย่างไร?


154

ฉันใช้แวดวง svg ในโครงการของฉันเช่นนี้

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 160 120">
    <g>
        <g id="one">
            <circle fill="green" cx="100" cy="105" r="20" />
        </g>
        <g id="two">
            <circle fill="orange" cx="100" cy="95" r="20" />
        </g>
    </g>
</svg>

และฉันใช้ดัชนี z ในgแท็กเพื่อแสดงองค์ประกอบแรก ในโครงการของฉันฉันต้องใช้เฉพาะค่าดัชนี z แต่ฉันไม่สามารถใช้ดัชนี z กับองค์ประกอบ svg ของฉันได้ ฉันเที่ยวมาก แต่ก็ไม่ค่อยเจออะไรเลย ดังนั้นโปรดช่วยฉันใช้ z-index ใน svg ของฉัน

นี่คือDEMO


คำตอบ:


163

สเปค

ในข้อกำหนดคุณสมบัติ SVG เวอร์ชัน 1.1 ใบสั่งการแสดงผลจะยึดตามลำดับเอกสาร:

first element -> "painted" first

อ้างอิงถึงSVG 1.1 สเปค

3.3 คำสั่งการแสดงผล

องค์ประกอบในส่วนเอกสาร SVG มีคำสั่งการวาดภาพโดยปริยายด้วยองค์ประกอบแรกในส่วนเอกสาร SVG ได้รับ"ทาสี" ครั้งแรก องค์ประกอบที่ตามมาจะถูกทาสีทับองค์ประกอบที่ทาสีไว้ก่อนหน้านี้


โซลูชัน (ทำความสะอาดเร็วกว่า)

คุณควรวางวงกลมสีเขียวเป็นวัตถุล่าสุดที่จะวาด ดังนั้นสลับสององค์ประกอบ

<svg xmlns="http://www.w3.org/2000/svg" viewBox="30 70 160 120"> 
   <!-- First draw the orange circle -->
   <circle fill="orange" cx="100" cy="95" r="20"/> 

   <!-- Then draw the green circle over the current canvas -->
   <circle fill="green" cx="100" cy="105" r="20"/> 
</svg>

นี่ส้อมของคุณjsFiddle

โซลูชัน (ทางเลือก)

แท็กที่useมีแอตทริบิวต์xlink:hrefและเป็นค่ารหัสขององค์ประกอบ โปรดทราบว่าอาจไม่ใช่วิธีที่ดีที่สุดแม้ว่าผลลัพธ์จะออกมาดี มีบิตของเวลาที่นี่การเชื่อมโยงของสเปคที่SVG 1.1 "การใช้" ธาตุ

วัตถุประสงค์:

เพื่อหลีกเลี่ยงการกำหนดให้ผู้เขียนแก้ไขเอกสารอ้างอิงเพื่อเพิ่ม ID ให้กับองค์ประกอบราก

<svg xmlns="http://www.w3.org/2000/svg" viewBox="30 70 160 120">
    <!-- First draw the green circle -->
    <circle id="one" fill="green" cx="100" cy="105" r="20" />
    
    <!-- Then draw the orange circle over the current canvas -->
    <circle id="two" fill="orange" cx="100" cy="95" r="20" />
    
    <!-- Finally draw again the green circle over the current canvas -->
    <use xlink:href="#one"/>
</svg>


หมายเหตุเกี่ยวกับ SVG 2

ข้อมูลจำเพาะ SVG 2เป็นรุ่นใหญ่ครั้งต่อไปและยังคงรองรับคุณสมบัติข้างต้น

3.4 คำสั่งการแสดงผล

องค์ประกอบใน SVG อยู่ในตำแหน่งสามมิติ นอกจากตำแหน่งของพวกเขาบนแกน x และ y ของวิวพอร์ต SVG แล้วองค์ประกอบ SVG ยังถูกจัดตำแหน่งบนแกน z อีกด้วย ตำแหน่งบนแกน z กำหนดเพื่อที่พวกเขาจะทาสี

ตามแกน z องค์ประกอบจะถูกจัดกลุ่มเป็นบริบทการสแต็ก

3.4.1 สร้างบริบทการซ้อนใน SVG

...

บริบทการเรียงซ้อนเป็นเครื่องมือทางแนวคิดที่ใช้เพื่ออธิบายลำดับที่องค์ประกอบจะต้องทาสีหนึ่งบนอื่น ๆเมื่อมีการแสดงเอกสาร ...


นอกจากนี้ยังมีร่างเก่าเกี่ยวกับการแทนที่ลำดับการแสดงผล แต่เป็นคุณลักษณะที่ไม่พร้อมใช้งาน เอกสารอ้างอิง
Maicolpt

12
อ๊ะ! มันไม่ง่ายเสมอไปที่จะวาดองค์ประกอบตามลำดับที่คุณต้องการให้ทาสีโดยเฉพาะอย่างยิ่งถ้าวัตถุนั้นถูกสร้างขึ้นโดยทางโปรแกรมและอาจปรากฏซ้อนกัน (เช่นปรากฏว่าgไม่สามารถมี a, b, เช่น a อยู่ด้านล่าง g พี่น้อง c แต่ b อยู่เหนือ)
Michael

@Michael: ในสถานการณ์ของคุณก่อนอื่นฉันจะพยายามที่จะเข้าใจว่าจริงๆองค์ประกอบจะต้องมีการจัดกลุ่ม
Maicolpt

1
'ใช้ xlink: href' นั้นยอดเยี่ยมและแปลกและสมบูรณ์แบบสำหรับสิ่งที่ฉันต้องการ !!
เอียน

32

ดังที่คนอื่น ๆ ที่นี่ได้กล่าวไว้ดัชนี z ถูกกำหนดโดยลำดับที่องค์ประกอบปรากฏใน DOM หากการจัดเรียง html ของคุณใหม่ด้วยตนเองไม่ใช่ตัวเลือกหรืออาจเป็นเรื่องยากคุณสามารถใช้ D3 เพื่อจัดลำดับกลุ่ม / วัตถุ SVG ใหม่

ใช้ D3 เพื่ออัปเดตการสั่งซื้อ DOM และฟังก์ชั่นการลอกเลียนแบบ Z-Index

การอัพเดทองค์ประกอบ Z ของดัชนี SVG ด้วย D3

ในระดับพื้นฐานที่สุด (และหากคุณไม่ได้ใช้ ID เพื่อสิ่งอื่นใด) คุณสามารถใช้ ID องค์ประกอบเป็นสแตนอินสำหรับดัชนี z และเรียงลำดับใหม่ได้ เกินกว่าที่คุณจะปล่อยให้จินตนาการของคุณก้าวไปข้างหน้า

ตัวอย่างในโค้ดขนาดสั้น

var circles = d3.selectAll('circle')
var label = d3.select('svg').append('text')
    .attr('transform', 'translate(' + [5,100] + ')')

var zOrders = {
    IDs: circles[0].map(function(cv){ return cv.id; }),
    xPos: circles[0].map(function(cv){ return cv.cx.baseVal.value; }),
    yPos: circles[0].map(function(cv){ return cv.cy.baseVal.value; }),
    radii: circles[0].map(function(cv){ return cv.r.baseVal.value; }),
    customOrder: [3, 4, 1, 2, 5]
}

var setOrderBy = 'IDs';
var setOrder = d3.descending;

label.text(setOrderBy);
circles.data(zOrders[setOrderBy])
circles.sort(setOrder);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 100"> 
  <circle id="1" fill="green" cx="50" cy="40" r="20"/> 
  <circle id="2" fill="orange" cx="60" cy="50" r="18"/>
  <circle id="3" fill="red" cx="40" cy="55" r="10"/> 
  <circle id="4" fill="blue" cx="70" cy="20" r="30"/> 
  <circle id="5" fill="pink" cx="35" cy="20" r="15"/> 
</svg>

แนวคิดพื้นฐานคือ:

  1. ใช้ D3 เพื่อเลือกองค์ประกอบ SVG DOM

    var circles = d3.selectAll('circle')
  2. สร้างดัชนี z จำนวนหนึ่งโดยมีความสัมพันธ์ 1: 1 กับองค์ประกอบ SVG ของคุณ (ที่คุณต้องการจัดลำดับใหม่) อาร์เรย์ดัชนี Z ที่ใช้ในตัวอย่างด้านล่างนี้คือ ID, ตำแหน่ง x & y, รัศมี, ฯลฯ ....

    var zOrders = {
        IDs: circles[0].map(function(cv){ return cv.id; }),
        xPos: circles[0].map(function(cv){ return cv.cx.baseVal.value; }),
        yPos: circles[0].map(function(cv){ return cv.cy.baseVal.value; }),
        radii: circles[0].map(function(cv){ return cv.r.baseVal.value; }),
        customOrder: [3, 4, 1, 2, 5]
    }
  3. จากนั้นใช้ D3 เพื่อผูกดัชนี z ของคุณกับการเลือกนั้น

    circles.data(zOrders[setOrderBy]);
  4. สุดท้ายโทร D3.sort เพื่อจัดเรียงองค์ประกอบใน DOM ใหม่ตามข้อมูล

    circles.sort(setOrder);

ตัวอย่าง

ป้อนคำอธิบายรูปภาพที่นี่

  • คุณสามารถสแต็คตาม ID

ป้อนคำอธิบายรูปภาพที่นี่

  • ด้วย SVG ซ้ายสุดอยู่ด้านบน

ป้อนคำอธิบายรูปภาพที่นี่

  • รัศมีที่เล็กที่สุดอยู่ด้านบน

ป้อนคำอธิบายรูปภาพที่นี่

  • หรือระบุอาเรย์ที่จะใช้ z-index สำหรับการสั่งซื้อเฉพาะ - ในโค้ดตัวอย่างของฉันอาเรย์[3,4,1,2,5]จะย้าย / เรียงลำดับวงกลมที่ 3 (ตามลำดับ HTML ดั้งเดิม) ให้อยู่ในอันดับที่ 1 ใน DOM, อันดับที่ 4 เป็นอันดับที่ 1 และอื่น ๆ ...


คำตอบที่ดีที่สุดแน่นอนที่นี่ ... 10/10 ทำไมตอนนี้ได้รับการยอมรับ
Tigerrrrr

1
@Tigerrrrrr การนำเข้าไลบรารีภายนอกเพื่อทำสิ่งที่ง่ายเหมือนการควบคุมลำดับการซ้อนคือความบ้า เพื่อทำให้แย่ลง D3 เป็นห้องสมุดขนาดใหญ่โดยเฉพาะ
iMe

2
@ ฉันพูดได้ดี ขณะนี้เป็นวิธีการแก้ปัญหาจึงทำให้คุณค่าของการเป็นนี่; มันไม่ได้และไม่ควรจะเป็นคำตอบ สิ่งเดียวที่ควรแทนที่คำตอบปัจจุบันคือถ้าข้อมูลจำเพาะใหม่ออกมาและเบราว์เซอร์เปลี่ยน ใครก็ตามที่ต้องการใช้คำตอบนี้อย่านำเข้า D3 ทั้งหมดเพียงนำเข้าโมดูลที่คุณต้องการ อย่านำเข้า D3 ทั้งหมดเพียงแค่นี้
Steve Ladavich

31

พยายามที่จะกลับและ#one #twoดูซอนี้: http://jsfiddle.net/hu2pk/3/

Update

ใน SVG, ดัชนี z จะถูกกำหนดโดยการสั่งซื้อองค์ประกอบที่ปรากฏในเอกสาร คุณสามารถดูที่หน้านี้ได้เช่นกันหากคุณต้องการ: https://stackoverflow.com/a/482147/1932751


1
ขอบคุณ แต่ฉันต้องการองค์ประกอบตามค่าดัชนี z
Karthi Keyan

ตกลง. และคุณต้องการให้ #one อยู่บน #two หรือตรงกันข้าม
Lucas Willems

ใช่ถ้าฉันบอกว่าค่าดัชนี z เป็น -1 สำหรับ #one หมายความว่ามันจะแสดงที่ระดับบนสุด
Karthi Keyan

10
ไม่มีคุณสมบัติ z-index ในข้อกำหนดคุณสมบัติ SVG ใด ๆ วิธีเดียวในการกำหนดองค์ประกอบที่ปรากฏอยู่ด้านบนและสิ่งที่ปรากฏอยู่ด้านล่างคือการใช้การสั่งซื้อ DOM
nicholaswmin

9
d3.selection.prototype.moveToFront = function() { return this.each(function() { this.parentNode.appendChild(this); }); };และจากนั้นคุณสามารถพูดselection.moveToFront()ผ่านstackoverflow.com/questions/14167863/…
mb21

21

คุณสามารถใช้การใช้งาน

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 160 120">
    <g>
        <g id="one">
            <circle fill="green" cx="100" cy="105" r="20" />
        </g>
        <g id="two">
            <circle fill="orange" cx="100" cy="95" r="20" />
        </g>
    </g>
    <use xlink:href="#one" />
</svg>

วงกลมสีเขียวปรากฏขึ้นที่ด้านบน
jsFiddle


4
สิ่งนี้จะวาด #one สองครั้งหรือไม่
mareoraft

@ mareoraft ใช่#oneถูกวาดสองครั้ง แต่ถ้าคุณต้องการคุณสามารถซ่อนตัวอย่างแรกผ่าน CSS useมีผลเช่นเดียวกับการโคลนองค์ประกอบ DOM ที่อ้างถึง
Jose Rui Santos

+1 เพราะมันไม่ต้องการจาวาสคริปต์ แต่ -1 เพราะคุณสามารถเปลี่ยนลำดับของ<g>ตัวเองเมื่อเปลี่ยน DOM ก่อนที่จะโหลดต่อไป
Hafenkranich

14

ตามที่กล่าวไว้ svgs จะแสดงผลตามลำดับและอย่านำ z-index เข้าบัญชี (ตอนนี้) อาจแค่ส่งองค์ประกอบเฉพาะไปที่ด้านล่างของพาเรนต์ของมันเพื่อให้มันแสดงผลครั้งสุดท้าย

function bringToTop(targetElement){
  // put the element at the bottom of its parent
  let parent = targetElement.parentNode;
  parent.appendChild(targetElement);
}

// then just pass through the element you wish to bring to the top
bringToTop(document.getElementById("one"));

ทำงานให้ฉัน

ปรับปรุง

หากคุณมี SVG ที่ซ้อนกันซึ่งมีกลุ่มคุณจะต้องนำรายการออกจาก parentNode

function bringToTopofSVG(targetElement){
  let parent = targetElement.ownerSVGElement;
  parent.appendChild(targetElement);
}

คุณลักษณะที่ดีของ SVG คือองค์ประกอบแต่ละรายการมีตำแหน่งโดยไม่คำนึงถึงกลุ่มที่ซ้อนใน: +1:


สวัสดีนี่ใช้งานได้สำหรับฉัน แต่สิ่งที่เทียบเท่า 'นำไปสู่ด้านล่าง' จะเป็นอย่างไร ขอบคุณ
กาวิน

@gavin องค์ประกอบ SVG ถูกวาดตามลำดับจากบนลงล่าง ในการใส่องค์ประกอบไว้ด้านบนเราผนวก () เพื่อให้เป็นองค์ประกอบสุดท้าย ในทางกลับกันถ้าเราต้องการให้องค์ประกอบถูกส่งไปที่ด้านล่างเราจะวางองค์ประกอบนั้นเป็นองค์ประกอบแรกโดยเติม () ฟังก์ชั่น bringToBottomofSVG (targetElement) {ให้ผู้ปกครอง = targetElement.ownerSVGElement; parent.prepend (targetElement); }
bumsoverboard

13

ใช้ D3:

หากคุณต้องการแทรกองค์ประกอบที่เลือกอีกครั้งตามลำดับในฐานะลูกย่อยของพาเรนต์

selection.raise()

5
selection.raise()ใหม่ใน D3 ตั้งแต่ v4
tephyr

9

ไม่มีดัชนี z สำหรับ svgs แต่ svg กำหนดว่าองค์ประกอบใดของคุณคือตำแหน่งบนสุดของพวกเขาใน DOM ดังนั้นคุณสามารถลบวัตถุและวางไว้ที่ส่วนท้ายของ svg ทำให้เป็นองค์ประกอบ "การแสดงผลครั้งสุดท้าย" สิ่งนั้นจะถูกแสดงผล "บนสุด" ด้วยสายตา


ใช้ jQuery:

function moveUp(thisObject){
    thisObject.appendTo(thisObject.parents('svg>g'));
}

การใช้งาน:

moveUp($('#myTopElement'));

ใช้ D3.js:

d3.selection.prototype.moveUp = function() {
    return this.each(function() {
        this.parentNode.appendChild(this);
    });
};

การใช้งาน:

myTopElement.moveUp();


ในปี 2019 ตอนนี้มันยังคงเป็นจริงหรือไม่? ในฐานะที่เป็น SVG 2.0 ได้รับการยอมรับในเบราว์เซอร์ที่ทันสมัย?
Andrew S



4

วิธีแก้ปัญหาที่สะอาดเร็วและง่ายที่โพสต์ ณ วันที่คำตอบนี้ไม่น่าพอใจ พวกเขาถูกสร้างขึ้นด้วยคำสั่งที่มีข้อบกพร่องว่าเอกสาร SVG ขาดคำสั่ง z ห้องสมุดก็ไม่จำเป็นเช่นกัน บรรทัดหนึ่งของรหัสสามารถดำเนินการส่วนใหญ่เพื่อจัดการกับลำดับ z ของวัตถุหรือกลุ่มของวัตถุที่อาจจำเป็นในการพัฒนาแอพที่เคลื่อนย้ายวัตถุ 2 มิติในพื้นที่ xyz

ใบสั่ง Z มีอยู่จริงในชิ้นส่วนเอกสาร SVG

สิ่งที่เรียกว่าชิ้นส่วนเอกสาร SVG เป็นต้นไม้ขององค์ประกอบที่ได้มาจากประเภทโหนดฐาน SVGElement โหนดรูทของส่วนของเอกสาร SVG คือ SVGSVGElement ซึ่งสอดคล้องกับแท็กHTML5 <svg> SVGGElement สอดคล้องกับแท็ก<g>และอนุญาตให้รวมเด็ก ๆ

การมีแอ็ตทริบิวต์ z-index บน SVGElement เหมือนกับใน CSS จะเอาชนะรูปแบบการแสดงผล SVG ส่วนที่ 3.3 และ 3.4 ของ W3C SVG คำแนะนำ v1.1 รัฐฉบับที่ 2 ว่า SVG เศษเอกสาร (ต้นไม้ของลูกหลานจาก SVGSVGElement) จะแสดงผลโดยใช้สิ่งที่เรียกว่าความลึกแรกค้นหาของต้นไม้ แบบแผนนั้นเป็นระเบียบในทุกความหมายของคำ

คำสั่ง Z เป็นทางลัดในการมองเห็นคอมพิวเตอร์เพื่อหลีกเลี่ยงความจำเป็นในการเรนเดอร์ 3D ที่มีความซับซ้อนและความต้องการใช้คอมพิวเตอร์ในการติดตามเรย์ สมการเชิงเส้นสำหรับดัชนีซีโดยนัยขององค์ประกอบในส่วนของเอกสาร SVG

z-index = z-index_of_svg_tag + depth_first_tree_index / tree_node_qty

นี่เป็นสิ่งสำคัญเพราะถ้าคุณต้องการย้ายวงกลมที่อยู่ด้านล่างของสี่เหลี่ยมจัตุรัสไปด้านบนคุณเพียงแค่แทรกสี่เหลี่ยมที่อยู่ตรงหน้าวงกลม สิ่งนี้สามารถทำได้อย่างง่ายดายใน JavaScript

วิธีการสนับสนุน

อินสแตนซ์ SVGElement มีสองวิธีที่สนับสนุนการจัดการคำสั่ง z ที่ง่ายและสะดวก

  • parent.removeChild (เด็ก)
  • parent.insertBefore (child, childRef)

คำตอบที่ถูกต้องที่ไม่ได้สร้างความยุ่งเหยิง

เนื่องจาก SVGGElement ( แท็ก<g> ) สามารถลบและแทรกได้ง่ายเหมือนกับ SVGCircleElement หรือรูปร่างอื่น ๆ เลเยอร์ภาพทั่วไปของผลิตภัณฑ์ Adobe และเครื่องมือกราฟิกอื่น ๆ สามารถนำไปใช้งานได้อย่างง่ายดายโดยใช้ SVGGElement JavaScript นี้เป็นหลักคำสั่งย้ายด้านล่าง

parent.insertBefore(parent.removeChild(gRobot), gDoorway)

ถ้าเลเยอร์ของหุ่นยนต์ที่ดึงมาเป็นลูกของ SVGGElement gRobot อยู่ก่อนทางเข้าประตูในฐานะที่เป็นเด็กของ SVGGElement gDoorway ตอนนี้หุ่นยนต์จะอยู่ด้านหลังทางเข้าประตูเนื่องจากคำสั่ง z ของทางเข้านั้นเป็นหนึ่งในคำสั่ง z ของหุ่นยนต์

ย้ายเหนือคำสั่งเกือบจะเป็นเรื่องง่าย

parent.insertBefore(parent.removeChild(gRobot), gDoorway.nextSibling())

แค่คิดว่า = a และ b = b เพื่อจดจำสิ่งนี้

insert after = move above
insert before = move below

ออกจาก DOM ในสถานะที่สอดคล้องกับมุมมอง

เหตุผลที่คำตอบนี้ถูกต้องเพราะมีน้อยและสมบูรณ์และเช่นเดียวกับผลิตภัณฑ์ของ Adobe หรือบรรณาธิการกราฟิกที่ได้รับการออกแบบมาเป็นอย่างดีทำให้การเป็นตัวแทนภายในอยู่ในสถานะที่สอดคล้องกับมุมมองที่สร้างขึ้นโดยการแสดงผล

วิธีทางเลือก แต่ จำกัด

อีกวิธีที่ใช้กันโดยทั่วไปคือการใช้ CSS z-index ร่วมกับชิ้นส่วนเอกสาร SVG หลายรายการ (แท็ก SVG) ที่มีพื้นหลังโปร่งใสส่วนใหญ่ในทั้งหมดยกเว้นด้านล่าง อีกครั้งนี่เป็นการกำจัดความสง่างามของรูปแบบการเรนเดอร์ SVG ทำให้ยากที่จะย้ายวัตถุขึ้นหรือลงตามลำดับ z


หมายเหตุ:

  1. ( https://www.w3.org/TR/SVG/render.html v 1.1, รุ่นที่ 2, 16 สิงหาคม 2554)

    3.3 องค์ประกอบการสั่งซื้อการแสดงผลในส่วนของเอกสาร SVG มีลำดับการวาดโดยนัยโดยองค์ประกอบแรกในส่วนของเอกสาร SVG จะได้รับ "ทาสี" ก่อน องค์ประกอบที่ตามมาจะถูกทาสีทับองค์ประกอบที่ทาสีไว้ก่อนหน้านี้

    3.4 วิธีการแสดงผลของกลุ่มการจัดกลุ่มองค์ประกอบเช่นองค์ประกอบ 'g' (ดูองค์ประกอบของภาชนะบรรจุ) มีผลต่อการสร้างผืนผ้าใบแยกชั่วคราวซึ่งเริ่มต้นเป็นสีดำโปร่งใสบนองค์ประกอบของเด็กที่ถูกทาสี เมื่อเสร็จสิ้นของกลุ่มเอฟเฟกต์ตัวกรองใด ๆ ที่ระบุสำหรับกลุ่มจะถูกนำไปใช้เพื่อสร้างผืนผ้าใบชั่วคราวที่ถูกดัดแปลง ผืนผ้าใบชั่วคราวที่ผ่านการดัดแปลงจะถูกนำมาประกอบเป็นพื้นหลังโดยคำนึงถึงการตั้งค่าการปิดบังระดับกลุ่มและความทึบของกลุ่ม


4

เรามีอยู่แล้วในปี 2019และz-indexยังไม่รองรับใน SVG

คุณสามารถดูบนเว็บไซต์การสนับสนุน SVG2 ใน Mozillaว่ารัฐสำหรับz-index- ไม่ได้ใช้งาน

คุณสามารถดูบนเว็บไซต์Bug 360148 "สนับสนุนคุณสมบัติ 'ดัชนี z' ในองค์ประกอบ SVG" (รายงาน: 12 ปีที่แล้ว)

แต่คุณมี 3 ความเป็นไปได้ใน SVG เพื่อตั้งค่า:

  1. กับ element.appendChild(aChild);
  2. กับ parentNode.insertBefore(newNode, referenceNode);
  3. ด้วยtargetElement.insertAdjacentElement(positionStr, newElement);(ไม่มีการสนับสนุนใน IE สำหรับ SVG)

ตัวอย่างการสาธิตเชิงโต้ตอบ

ด้วยฟังก์ชั่นทั้ง 3 นี้

var state = 0,
    index = 100;

document.onclick = function(e)
{
    if(e.target.getAttribute('class') == 'clickable')
    {
        var parent = e.target.parentNode;

        if(state == 0)
            parent.appendChild(e.target);
        else if(state == 1)
            parent.insertBefore(e.target, null); //null - adds it on the end
        else if(state == 2)
            parent.insertAdjacentElement('beforeend', e.target);
        else
            e.target.style.zIndex = index++;
    }
};

if(!document.querySelector('svg').insertAdjacentElement)
{
    var label = document.querySelectorAll('label')[2];
    label.setAttribute('disabled','disabled');
    label.style.color = '#aaa';
    label.style.background = '#eee';
    label.style.cursor = 'not-allowed';
    label.title = 'This function is not supported in SVG for your browser.';
}
label{background:#cef;padding:5px;cursor:pointer}
.clickable{cursor:pointer}
With: 
<label><input type="radio" name="check" onclick="state=0" checked/>appendChild()</label>
<label><input type="radio" name="check" onclick="state=1"/>insertBefore()</label><br><br>
<label><input type="radio" name="check" onclick="state=2"/>insertAdjacentElement()</label>
<label><input type="radio" name="check" onclick="state=3"/>Try it with z-index</label>
<br>
<svg width="150" height="150" viewBox="0 0 150 150">
    <g stroke="none">
        <rect id="i1" class="clickable" x="10" y="10" width="50" height="50" fill="#80f"/>
        <rect id="i2" class="clickable" x="40" y="40" width="50" height="50" fill="#8f0"/>
        <rect id="i3" class="clickable" x="70" y="70" width="50" height="50" fill="#08f"/>
    </g>
</svg>


2

ผลักองค์ประกอบ SVG ไปที่ล่าสุดเพื่อให้ดัชนี z ของมันจะอยู่ด้านบน ใน SVG ไม่มีคุณสมบัติที่เรียกว่า z-index ลองด้านล่าง javascript เพื่อนำองค์ประกอบขึ้นด้านบน

var Target = document.getElementById(event.currentTarget.id);
var svg = document.getElementById("SVGEditor");
svg.insertBefore(Target, svg.lastChild.nextSibling);

เป้าหมาย: เป็นองค์ประกอบที่เราจำเป็นต้องนำมาไว้ด้านบน svg: เป็นคอนเทนเนอร์ขององค์ประกอบ


0

มันง่ายที่จะทำ:

  1. คัดลอกรายการของคุณ
  2. เรียงรายการโคลน
  3. แทนที่รายการโดยโคลน

function rebuildElementsOrder( selector, orderAttr, sortFnCallback ) {
	let $items = $(selector);
	let $cloned = $items.clone();
	
	$cloned.sort(sortFnCallback != null ? sortFnCallback : function(a,b) {
  		let i0 = a.getAttribute(orderAttr)?parseInt(a.getAttribute(orderAttr)):0,
  		    i1 = b.getAttribute(orderAttr)?parseInt(b.getAttribute(orderAttr)):0;
  		return i0 > i1?1:-1;
	});

        $items.each(function(i, e){
            e.replaceWith($cloned[i]);
	})
}

$('use[order]').click(function() {
    rebuildElementsOrder('use[order]', 'order');

    /* you can use z-index property for inline css declaration
    ** getComputedStyle always return "auto" in both Internal and External CSS decl [tested in chrome]
    
    rebuildElementsOrder( 'use[order]', null, function(a, b) {
        let i0 = a.style.zIndex?parseInt(a.style.zIndex):0,
  		    i1 = b.style.zIndex?parseInt(b.style.zIndex):0;
  		return i0 > i1?1:-1;
    });
    */
});
use[order] {
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="keybContainer" viewBox="0 0 150 150" xml:space="preserve">
<defs>
    <symbol id="sym-cr" preserveAspectRatio="xMidYMid meet" viewBox="0 0 60 60">
        <circle cx="30" cy="30" r="30" />
        <text x="30" y="30" text-anchor="middle" font-size="0.45em" fill="white">
            <tspan dy="0.2em">Click to reorder</tspan>
        </text>
    </symbol>
</defs>
    <use order="1" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#sym-cr" x="0" y="0" width="60" height="60" style="fill: #ff9700; z-index: 1;"></use>
    <use order="4" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#sym-cr" x="50" y="20" width="50" height="50" style="fill: #0D47A1; z-index: 4;"></use>
    <use order="5" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#sym-cr" x="15" y="30" width="50" height="40" style="fill: #9E9E9E; z-index: 5;"></use>
    <use order="3" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#sym-cr" x="25" y="30" width="80" height="80" style="fill: #D1E163; z-index: 3;"></use>
    <use order="2" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#sym-cr" x="30" y="0" width="50" height="70" style="fill: #00BCD4; z-index: 2;"></use>
    <use order="0" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#sym-cr" x="5" y="5" width="100" height="100" style="fill: #E91E63; z-index: 0;"></use>
</svg>

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.