79545656

Date: 2025-03-31 07:05:32
Score: 1
Natty:
Report link

Following leech's answer & some inspiration from David V McKay's impressive 1-liner ... along w/ all the answers utilizing while-loops ...

I used the following for my "drop" events. Since my draggable "tabs" & "item lists" all have different structures w/ different HTML elements, I need to find the parent of my "drop" {target} to make sure that it matches the parent my "dragstart" {target} (for drag & drop, these are 2 different events & 2 different {targets}).

The idea here is to climb back up the HTML DOM until you find the desired node. Enjoy ...

Javascript

document.addEventListener("drop", ({target}) => {
  // gotta find the parent to drop orig_itm into
    var i = 0;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* this is the part that answers the OP                                                    */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    var target_itm = target;
    if(!target_itm.getAttribute('draggable')){
      while(!target_itm.parentNode.getAttribute('draggable')){
        // since we haven't found the correct node, we move up the tree
          target_itm = target_itm.parentNode;

        // increment the counter so things don't blow-up on us
          i++;

        // check the counter & the element's tagName to prevent the while-loop from going WOT
        // adjust threshold for your application ... mine gets the job done at 20
          if(i > 20){
            console.log('i = ' + i);
            break;
          } else if(target_itm.parentNode.tagName == 'body'){
            console.log(i + ' - draggable parent not found. looped back to <body>')
            break;
          }
      }
      target_itm = target_itm.parentNode;
    }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    [criteria to make sure selected & target items are on the same parentNode]
    [move items around]
});

If you remove the unnecessary remarks (shown to help clarify the code) & consolidate the counter/body check w/ an '&&' operator & only the break;, this code can be compacted down to about 8-ish lines w/out requiring nested function calls & takes the most direct path w/out having to load all the matching selector elements.

I usually just .getElementById() & rarely search for parents above the previous tier. I only need this feature for my "draggable" items, but if I want to make it available throughout my code, I can (like others have already answered) simply embed the code in a

function getParentByAttribute(itm,attr){
  [relevent code from above]
  return target_itm;
}

... then just call reqd_node = getParentByAttribute([desired_elem],[desired_attr]); from wherever needed.

Reasons:
  • Blacklisted phrase (0.5): I need
  • RegEx Blacklisted phrase (1): I want
  • Long answer (-1):
  • Has code block (-0.5):
  • Low reputation (1):
Posted by: DarkMain94