Force My jquery to run on any newly added dom elements - javascript

I have the following scripts, which contains two selectors:-
$(document).ready(function () {
if ($("#ChoiceName2").prop("checked")) {
&
$("#ChoiceTag2, #ChoiceName2").each(function () {
$(this).change(function () {
The selectors will not fire on any newly added Dom elements, usually i use the .on to force my jquery to run on any newly added elements as follow:-
$("body").on('click', '#DCSort', function () {
but not sure how i can add the .on to mt first script ?

Since you are using #ChoiceTag2, #ChoiceName2 as selector, $.each is not required. As it's going to return you only one element always as it's an ID.
$('body').on("change", "#ChoiceTag2, #ChoiceName2", function () {
This will do the trick for the newly added elements

The best way to accomplish what you are trying to do is by using a CSS class that has no style definition, but will allow you to bind a delegate to events involving that class.
That way the delegate acts on the class, regardless of when it is added to the DOM.
Like this:
<button class='DCSort'>Some Button</button>
$('body').on('click', '.DCSort', function () {
}

Related

Firing a function with a newly added class

I've tried to simplify it, simple enough to make my question clearer.
The alert 'I am a boy' didn't popup with even after the addClass has been executed.
Here is my code:
$(".first").click(function () {
var a = $(this).html();
if (a=='On') {
$(this).removeClass('first').unbind().addClass('second');
$(this).html('Off');
}
});
$(".second").click(function () {
alert('I am a boy');
});
<button class="first">On</button>
This behavior is because you are apply a class to an element after the DOM has loaded, in other words dynamically. Because of this, your event listener attached to the control for '.second' isn't aware of the newly added class and doesn't fire when you click on that control.
To fix this, you simply need to apply your event listener to a parent DOM object, typically $(document) or $('body'), this will ensure it is aware of any children with dynamically added classes.
As George Bailey said, you can refer here for a in depth explanation.
In regards to your specific code, the fix is to simply adjust it as so:
$(".first").click(function () {
var a = $(this).html();
if (a=='On') {
$(this).removeClass('first').unbind().addClass('second');
$(this).html('Off');
}
});
/* Changed this:
$(".second").click(function () {
alert('I am a boy');
});
*/
// To this:
$(document).on('click', '.second', function () {
console.log('I am a boy');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="first">On</button>
The function you pass to $.post doesn’t run until later (a callback). So the class is added after you try to select it. Do it inside the callback, the same way you added the class (and you don’t need to select that class, just use $this)

javascript events not working with dynamic content added with json

I'm stuck with a situation where my DOM elements are generated dynamically based on $.getJSON and Javascript functions for this elements are not working. I'll post some general idea on my code because I'm looking just an direction of what should I do in this situation.
site.js contains general features like
$(document).ready(function() {
$('.element').on('click', function() {
$(this).toggleClass('active');
});
$(".slider").slider({
// some slider UI code...
});
});
After that:
$.getJSON('json/questions.json', function (data) {
// generating some DOM elements...
});
I have also tried to wrap all site.js content into function refresh_scripts() and call it after $.getJSON() but nothing seems to be working.
Firstly you need to use a delegated event handler to catch events on dynamically appended elements. Then you can call the .slider() method again within the success handler function to instantiate the plugin on the newly appended content. Try this:
$(document).ready(function(){
$('#parentElement').on('click', '.element', function() {
$(this).toggleClass('active');
});
var sliderOptions = { /* slider options here */ };
$(".slider").slider(sliderOptions);
$.getJSON('json/questions.json', function(data) {
// generating some DOM elements...
$('#parentElement .slider').slider(sliderOptions);
});
});
Instead of calling on directly on the element, call it on a parent that isn't dynamically added and then use the optional selector parameter to narrow it to the element.
$('.parent').on('click', '.element', () => {
// do something
});
The difference between this and:
$('.element').on('click', () => {});
is with $('.element').on(), you're only applying the listener to the elements that are currently in that set. If it's added after, it won't be there.
Applying it to $(.parent), that parent is always there, and will then filter it to all of it's children, regardless when they're added.
the easiest way is to add this after you add/generate your DOM
$('script[src="site.js"]').remove();
$('head').append('<script src="site.js"></script>');
of course your js function that generates DOM needs to be on another file than your site.js

Add click event on div tag using JavaScript

I have a div tag in my form without id property. I need to set an on-click event on this div tag.
My HTML code:
<div class="drill_cursor" >
....
</div>
I don't want to add an id property to my div tag.
How can I add an on-click event on this tag using JavaScript?
Pure JavaScript
document.getElementsByClassName('drill_cursor')[0]
.addEventListener('click', function (event) {
// do something
});
jQuery
$(".drill_cursor").click(function(){
//do something
});
Try this:
var div = document.getElementsByClassName('drill_cursor')[0];
div.addEventListener('click', function (event) {
alert('Hi!');
});
Just add the onclick-attribute:
<div class="drill_cursor" onclick='alert("youClickedMe!");'>
....
</div>
It's javascript, but it's automatically bound using an html-attribute instead of manually binding it within <script> tags - maybe it does what you want.
While it might be good enough for very small projects or test pages, you should definitly consider using addEventListener (as pointed out by other answers), if you expect the code to grow and stay maintainable.
Recommend you to use Id, as Id is associated to only one element while class name may link to more than one element causing confusion to add event to element.
try if you really want to use class:
document.getElementsByClassName('drill_cursor')[0].onclick = function(){alert('1');};
or you may assign function in html itself:
<div class="drill_cursor" onclick='alert("1");'>
</div>
the document class selector:
document.getElementsByClassName('drill_cursor')[0].addEventListener('click',function(){},false)
also the document query selector https://developer.mozilla.org/en-US/docs/Web/API/document.querySelector
document.querySelector(".drill_cursor").addEventListener('click',function(){},false)
Separate function to make adding event handlers much easier.
function addListener(event, obj, fn) {
if (obj.addEventListener) {
obj.addEventListener(event, fn, false); // modern browsers
} else {
obj.attachEvent("on"+event, fn); // older versions of IE
}
}
element = document.getElementsByClassName('drill_cursor')[0];
addListener('click', element, function () {
// Do stuff
});

Using .on() and targeting elements with a specific attribute

I understand you can use .on() to attach a single click event to an element and then specify which child elements receive the click. So, for example:
$(this.el).on("click", "span", function () {
alert("Bloop!");
});
I need to be a bit more specific and target selectors with a particular attribute, like this:
$(this.el).on("click", "span[data-placeholder]", function () {
alert("Bloop!");
});
That doesn't seem to work, though. As soon as I add the attribute it stops working. No errors, just doesn't seem to find the elements.
Is that the expected behavior? Is there a way around it?
CLARITY
$(this.el) is just a div that contains a number of elements, some of which are <span data-placeholder="First Name"></span> tags. There could be dozens of those <span> tags and I didn't want that many event listeners, so I thought I'd use .on() to add the click to the parent container.
Here's JSFiddle showing your example working, with both existing <span>s and with newly created ones.
Just to be clear, this will work with your event delegation:
var span = $('<span>Test</span>');
span.attr('data-placeholder', 'test'); // declare as an attribute
$(this.el).append(span);
span.click();
This will not:
var span = $('<span>Test</span>');
span.data('placeholder', 'test'); // declare with .data()
$(this.el).append(span);
span.click();
jQuery's .data() method will read properties from data attributes if declared, but does not store them as attributes on the element when adding data.
Here's another JSFiddle.
try
$("span[data-placeholder]", this.el).on("click", function () {
alert("Bloop!");
});
You can choose to filter your spans
$('span', this.el).filter(function() {
return $(this).hasAttr('data-placeholder');
}).on('click', function() {
//This is for all the spans having data-placeholder
//...
});
Or if the placeholder is set via data api:
$(this.el).filter(function() {
return $(this).data('placeholder') != 'undefined';
}).on('click', function() {
//This is for all the spans having data-placeholder
//...
});
This functions above select those elements specifically, if event delegation on the OP is needed, then you can do the following:
$('span', this.el).on('click', 'span', function() {
if($(this).data('placeholder') != 'undefined') {
alert('bloop');
}
});
add a id to your span and pin point it using # tag

.class selector not working

I'm working in a card game system that the player can select the card by clicking on it and then select the place to put it on. My problem is that when the player click on the target place, nothing happens.
This is my try: http://jsfiddle.net/5qMHz/
And this is my code:
function target() {
$(".target").on("click", function() {
$("#"+x).appendTo(this);
console.log(x);
});
};
What's wrong?
Try binding with document, since you change the class during document ready and there was no element with the class target initially
$(document).on("click",".target", function() {
$("#" + x).appendTo(this);
console.log(x);
}
WORKING FIDDLE
Firstly, your practice of putting function references in to jQuery objects is rather odd. The problem however is that because the .target class is applied after DOM load you need to use a delegate selector. Try this:
var $card
$(".card").on("click", function () {
$card = $(this);
if ($(".myslot").length) {
if ($(".myslot").is(':empty')) {
$(".myslot:empty").addClass("target");
} else {
alert('No empty slots');
}
}
});
$('.field').on('click', ".target", function () {
$card.appendTo(this);
$card = $();
});
Example fiddle
At the moment you are trying to bind the event handler, the elements don't have a class target yet. From the documentation:
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on().
(Technically the elements exist, but they are not (yet) addressable by the class target)
You have three options to solve this:
Add the class to your HTML markup.
Bind the handler after you added the class to the elements.
Use event delegation.
The first two don't really fit to your use case, since your are adding the class target in response to an other event and the number of elements with the class target changes over time. This is a good use case for event delegation though:
$('.field').on('click', '.target', function() {
// ...
});

Categories

Resources