Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

[ExtendScript] How to move layer children while preserving their order

Community Expert ,
Sep 07, 2025 Sep 07, 2025

I'm writing code to move the contents of a layer to another layer. Moving pageItems alone works fine, but when sublayers and pageItems are at the same level, I don't know how to move them while preserving their order.

 

As far as I know, the only way is to retrieve pageItems and layers separately, which results in two clusters after moving—like beer liquid and foam. How to solve this problem?

(function() {
  if(app.documents.length <= 0) {return ;}
  var doc = app.documents[0] ;
  var srcLayer = doc.layers[1] ;
  var dstLayer = doc.layers[0] ;

  var pageItems = srcLayer.pageItems ;
  for(var i = pageItems.length - 1 ; i >= 0 ; i--) {
    pageItems[i].move(dstLayer, ElementPlacement.PLACEATEND) ;
  }
  var sublayers = srcLayer.layers ;
  for(var i = sublayers.length - 1 ; i >= 0 ; i--) {
    sublayers[i].move(dstLayer, ElementPlacement.PLACEATEND) ;
  }
})() ;

 

Update:
Added the test data (.ai) and before/after image.

 

before_after.png

 

TOPICS
Scripting
125
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Sep 07, 2025 Sep 07, 2025

yes, as far as I know, we have to move pageItems and sublayers separately. I was going to mess with absoluteZorderPosition but I thought it would be easier to add an "anchor" right before (or after) each sublayer.

 

(function() {
  if(app.documents.length <= 0) {return ;}
  var doc = app.documents[0] ;
  var srcLayer = doc.layers[1] ;
  var dstLayer = doc.layers[0] ;

  // add dummy placeholders above each sublayer
  var dummyPlacehodlers = [];

  var sublayers = srcLayer.layers ;
  for(var i = 
...
Translate
Adobe
Community Expert ,
Sep 07, 2025 Sep 07, 2025

Hi @sttk3 can you please post a test case document showing how you'd like to control the layering? Before and after?

 

I know you are an expert, so I know this is going to be a challenge. I hope @CarlosCanto sees this!

- Mark

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 08, 2025 Sep 08, 2025

Yes, I'll add the test data to the source question.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 07, 2025 Sep 07, 2025

yes, as far as I know, we have to move pageItems and sublayers separately. I was going to mess with absoluteZorderPosition but I thought it would be easier to add an "anchor" right before (or after) each sublayer.

 

(function() {
  if(app.documents.length <= 0) {return ;}
  var doc = app.documents[0] ;
  var srcLayer = doc.layers[1] ;
  var dstLayer = doc.layers[0] ;

  // add dummy placeholders above each sublayer
  var dummyPlacehodlers = [];

  var sublayers = srcLayer.layers ;
  for(var i = sublayers.length - 1 ; i >= 0 ; i--) {
    dummyPlacehodlers[i] = srcLayer.pathItems.rectangle(0,0,1,1) ;
    dummyPlacehodlers[i].move(sublayers[i], ElementPlacement.PLACEBEFORE) ;
  }

  var pageItems = srcLayer.pageItems ;
  for(var i = pageItems.length - 1 ; i >= 0 ; i--) {
    pageItems[i].move(dstLayer, ElementPlacement.PLACEATEND) ;
  }

  var sublayers = srcLayer.layers ;
  for(var i = sublayers.length - 1 ; i >= 0 ; i--) {
    sublayers[i].move(dummyPlacehodlers[i], ElementPlacement.PLACEAFTER);
    dummyPlacehodlers[i].remove() ;
  }
})() ;
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 07, 2025 Sep 07, 2025

the layering order is upside down for now, but that the way your original function is.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 08, 2025 Sep 08, 2025
LATEST

Thanks, your method made it possible. Here's the code that changed the reverse order to the intended order.

(function() {
  if(app.documents.length <= 0) {return ;}
  var doc = app.documents[0] ;
  var srcLayer = doc.layers[1] ;
  var dstLayer = doc.layers[0] ;

  // add dummy placeholders above each sublayer
  var dummyPlacehodlers = [] ;

  var sublayers = srcLayer.layers ;
  var lastSublayerIndex = sublayers.length - 1 ;
  for(var i = lastSublayerIndex ; i >= 0 ; i--) {
    var dummyPlacehodler = srcLayer.groupItems.add() ;
    dummyPlacehodlers.unshift(dummyPlacehodler) ;
    dummyPlacehodler.move(sublayers[i], ElementPlacement.PLACEBEFORE) ;
  }

  var pageItems = srcLayer.pageItems ;
  for(var i = pageItems.length - 1 ; i >= 0 ; i--) {
    pageItems[i].move(dstLayer, ElementPlacement.PLACEATBEGINNING) ;
  }

  for(var i = lastSublayerIndex ; i >= 0 ; i--) {
    sublayers[i].move(dummyPlacehodlers[i], ElementPlacement.PLACEAFTER) ;
    dummyPlacehodlers[i].remove() ;
  }
})() ;

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines