简体   繁体   中英

Selector to click on div loaded with AJAX - jQuery

I am trying to create an event that, on click of the div-wrapper, gets a data-value from the tag. To bind events on elements that on document.ready do not exist, I have to use the "on-selector" right?

On document ready my HTML is:

<div class="dashboard_container">
  <div class="ab-builder-el el-empty ui-droppable" ordering="-0.5">
    <p>Plaats hier je element</p>
  </div>
</div>

On drag/drop I add a part of HTML below the div mentioned above (with class el-empty) using jQuery:

 $(document).ready(function(){
 //Initialize variables
    var generatedID = 1;
    var elementName = null;
    //Initialize droppable elements
    dropInit();
    //Draggable 
    $('.ab-nav-element').draggable({
            appendTo: '.scroll-container',
            revert: 'invalid',
            cursor: "move", 
            distance: 50,
            revertDuration: 250,
            helper: 'clone',
            start: function(){
                $('.el-empty').addClass('el-receptive');
                elementName = $(this).data('original-title');
                // console.log("draggable start, elementName: "+elementName);
            },
            stop: function(){
                $('.el-receptive').removeClass('el-receptive');
                elementName = null;
            }
        });



    //Function droppable
    function dropInit () {
        // console.log("droppable start, elementName: "+elementName);
        $('.ab-builder-el').droppable({
        hoverClass : 'ui-hover',
        drop: function() {
            var dropContent = '<div id="'+elementName+'-'+generatedID+'" ordering="0" class="ab-builder-el panel" data-element="'+elementName+'"></div><div class="ab-builder-el el-empty" ordering="0.5"><p>Plaats hier je element</p></div>';
            $(this).after(dropContent);
            var divID = '#'+ $(this).next('.panel').attr('id');
            generatedID++;
            $(divID).load("builder-loader.php",{
                elementName: elementName,
                divID:divID 
            });
            dropInit();
        }
    })};
});

The AJAX call changes the HTML to this:

<div class="dashboard_container">
  <div class="ab-builder-el el-empty ui-droppable" ordering="-0.5">
    <p>Plaats hier je element</p>
  </div>
  <div id="element_text_columns-1" ordering="0" class="ab-builder-el panel ui-droppable" data-element="element_text_columns"><div class="row" background-color:default_background_color;"="">
  <div class="ab-builder-el el-empty ui-droppable" ordering="0.5">
    <p>Plaats hier je element</p>
  </div>
</div>

What I then like to do is to select my div with ID: "element_text_columns-1"" and read out the data-element value.

I tried using LOTS of selectors, but none of them seem to work? I have the following:

$('.dashboard_container').children('.panel').on("click", function(){
    console.log('children');
    var clickedElement = $(this).data('element');
    if(typeof clickedElement != 'undefined'){console.log(clickedElement);}
});

But this does not seem to work at all. Any way to target the div ?

Allthough using on() you have to rebind events on dynamically created DOM elements. Lets say you have a container <div id="foo"></div> .

$(element).on('click', fn) does not affect dynamically created elements

This will alert 'bar', because it is bind after the element is added. ( JSFiddle )

var panel = $('<div class="panel">foo</div>');
$('#foo').append(panel);

$('.panel').on('click', function(){
    alert('bar');
});

This will not alert anything, because you bind the event and afterwards the element is added. ( JSFiddle )

$('.panel').on('click', function(){
    alert('bar');
});

var panel = $('<div class="panel">foo</div>');
$('#foo').append(panel);

$(document).on('click', element, fn) affects dynamically created elements

So you have to rebind your events every single time you add a new element. If performance does not matter that much, you could use another syntax so you do not need to rebind them. ( JSFiddle )

$(document).on('click', '.panel', function(){
    alert('bar');
});

var panel = $('<div class="panel">foo</div>');
$('#foo').append(panel);

Easiest Fix for your Problem

$(document).on('click', '.dashboard_container .panel', function(){
    var clickedElement = $(this).data('element');
    if(typeof clickedElement != 'undefined'){console.log(clickedElement);}
});

Note : document can be replaced with just a parent div. This works because the click event is bind on a existing parent div and the selector given is checked every time you click the element. that's also why it is worse performance wise.

You have to use click event on() because the tag you want to select is generated dynamicly with js (like Satpal mentioned in comment) and then simple selector like $(this).data( "element") .

 $('.dashboard_container').on("click", '.panel', function(){ alert($(this).data( "element")); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="dashboard_container"> <div class="ab-builder-el el-empty ui-droppable" ordering="-0.5"> <p>Plaats hier je element</p> </div> <div id="element_text_columns-1" ordering="0" class="ab-builder-el panel ui-droppable" data-element="element_text_columns"><div class="row" background-color:default_background_color;"=""> <div class="ab-builder-el el-empty ui-droppable" ordering="0.5"> <p>Plaats hier je element</p> </div> </div> 

NOTE : You have a malformed tag in the HTML generated by ajax :

<div class="row" background-color:default_background_color;"="">

You have to fix it.

Hope this helps.

You said that:

on click of the div-wrapper , gets a data-value from the tag

So, I think what you want is to assign the click event to the wrapper, then, get value of its descendants. To do that, we use this:

        $('.dashboard_container').click(function(){
            var data = $(this).find('.panel').data('element');
            alert(data);
        });

To prove that the code above works with dynamic HTML, I'm posting my tested code here.

HTML

<div id="foo"></div>

Javascript

    $(function(){
        $('#foo').click(function(){
            var className = $(this).find('.panel').data('element');
            alert(className);
        });

        var panel = $('<div class="panel" data-element="test">foo</div>');
        $('#foo').append(panel);
    });

Result : I get the data-element alerted (test) when I click the div.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM