I'm appending values into a div through jQuery, but I've realized what gets appended isn't affected by my javascript functions.
$(".div").append("<input type='text' class='textForm' placement='Value' />");
What I have setup in my javascript code is that it takes the attribute placement of any class "textForm" and makes it a value. But I've realized that once a value is appended, it isn't effected by my javascript. Any ideas on how to fix this issue?
If you are currently using
$(".textForm").click(){}
then now use
$(document).on("click",".textForm",function(){//Dtuff here})
This will attach the .on("click") to the document object and as such it will be enabled on all elements that exist and all elements that are created matching the .textForm selector.
I guess you have some events bounded to some elements like which are not working after the append . something like this.
$(function(){
$(".someClass").click(function(){
//dome some thing
});
});
If you want the same functionality to work on the newly injected( dynamically added via append /jquery ajax etc...) DOM elements, you should consider using jquery on. So your code should be changed like this
$(function(){
$(document).on("click",".someClass",function(){
//dome some thing
});
});
on will work for current and future elements
I'm not sure I understand the bit about why you're copying values from the placement attribute into the input value, but I can offer this suggestion to get your form fields to appear.
$("div").each(function() {
$(this).append($("<input type='text' class='textForm' placement='Value' />"))
});
I'm assuming that you want to identify your div via the tag name, and not the class name. If this is the case, your jQuery selector will need to be "div", and not ".div". Also, you need to wrap your HTML in $() in order to generate a DOM element.
Related
So I'm using this code to:
$('.something').on('click', function () {
console.log($(this).data('id'));
}
And for some reason, if I modify the data-id using the inspector, jQuery still sees the id that was there in the beginning. However, I tried the same thing using JS and it does see the changes. This makes me wondering if jQuery caches in some way the elements selected and uses them instead of the actual DOM.
Can someone please explain what happens and how jQuery does the event binding in the background?
Later edit: I want to specify that I'm talking about the "data-" attribute that I put in the HTML, not about the '.data()' provided by jQuery. Not sure if it's the same thing.
jQuery caches elements selected?
No. But the data managed by data is stored in an object cache maintained by jQuery, keyed by a unique identifier jQuery adds to the element (so it can look up the data). data is only initialized from data-* attributes, it is not an accessor for them. It's both more and less than that.
If you're interested, you can see that as an "expando" property on the element instance, it'll start with "jquery" and have a long number attached to it (currently; it's undocumented — for good reason — so this may change):
var foo = $("#foo");
console.log(foo.data("info")); // hi there
console.log("Expando name: " + Object.getOwnPropertyNames(foo[0]).find(name => name.startsWith("jQuery")));
<div id="foo" data-info="hi there"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I have common jQuery function and two div tags. Both div tags have different names but both containing elements of identical ids now i want to use this common Jquery function for them both?
I have implemented common function but it's not working for both.
Here's link to my jsfiddle -jsfiddle.net/xS7zF/1/
In my jsfiddle there are two div tags namely example1 and example2 and both tags have elements of identical ids. Function is working fine for first div but not for second.
please help me to sort out this.
Yeah, under the hood, jQuery selection on an ID will use the Document.GetElementById() function implemented by the browser, which is really fast, but (i guess depending on the browser) will stop after it finds the first element, since ID's should be unique and no further searching is needed after the first one is found.
For instance, rename the divs with id="eb" to class="eb" and you can still target specific elements using $("#example1 .eb") and $("#example2 .eb")
UPDATE:
Using your new Fiddle I created this: http://jsfiddle.net/xS7zF/5/
I cleaned up a lot of code and hopefully you can see what I have done. I changed all elements that appear twice from id to class. Now, when you attach an event to an element using $(".classname").click(), it attaches to all the elements. In the handler function where you set HTML and do your show()/hide(), you don't target a specific element using it's ID, but you find it relative to the element that does the event. You can do this using parent(), parentsUntil(), next(), find(), etc. Check jQuery docs for all possibilities. So for instance, the change-handler attaches to all inputs with name=Assets. But instead of doing $("#b1").show(), I go to the parent of the specific input that fires using $(this).parent(). Then I find the element with a class=".b1", which it will only find the one that is next to this specific input and I set the HTML to just that element.
Since there is another input, the same actions happen when THAT input changes, but instead it finds IT's parent, and finds the element with class=".b1" that is next to IT. So both divs with input are contained since they act on elements relative to itself and not across the document.
For extra fun and to show you how flexible this way of programming is, here is a fiddle with the Javascript-code unchanged, but with the exact same question-div copied 8 times. No matter how many times you repeat this, the same code will act on as many divs as you create since everything works relative. http://jsfiddle.net/xS7zF/7/
Hopefully this helps, the rest is up to you!
ID's must be unique, you should not repeat them. You could replace id with class and in the jQuery function do (".ub").each() or manually referencing the object using eq(x). e.g. (".ub").eq(1).
You shouldn't assign same id's to different elements.
You CAN but you SHOULDN'T. Instead of giving the same id, use class
IDs must be unique, try fix this, change to classes.
You can try something like this:
$("div div:first-child")
instead of
$("#eb")
But depends of the rest of your page code. So, change to classes first and use
$(".eb")
when jQuery / javascript find the first ID it would ignore the rest, please read more about it
http://www.w3schools.com/tags/att_global_id.asp
Noob Question on Data Attribute
I was wondering will using data-attribute in jQuery Selector can bring any trouble in the future?
I'm trying to reduced the usage of .class and #id as jQuery Selector, since most of data I'm working on will generated from data-attribute
example of the code
$(document).ready(function(){
var mydata = $(document).data('my-data-attribute');
});
will the code above slowing the load time?
or
$('[data-suffix-attribute="some_value"]').each(function(){
......
});
or
$('[data-suffix-attribute="delete"]').click(function(){
// delete action happening here
});
will this bring trouble?
$(document).ready(function(){
var mydata = $(document).data('my-data-attribute');
});
The code above will not work. If you want to read the HTML5 data attribute of an element using the jQuery .data() method firstly you need to select the relevant element using a jQuery selector and then you can use the method as is shown below:
var mydata = $('.example').data('suffix');
This will read the value of the data-suffix attribute of an element with a class of "example".
The other important thing to note when using the .data() method is that you have to omit the data- prefix from the selector to read the value stored in that attribute.
The way you have selected the attribute before the .each() method will work:
$('[data-suffix-attribute="some_value"]');
However, it would be better if you can narrow it down to a specific element like:
$('div[data-suffix-attribute="some_value"]');
This is because the first selector will go through every node in the document which will take more time whereas the second will only go through the div tags in the document.
The attribute selector is supported by the native query selectors so it is fine. As far as future is concerned I don't think in near future it will be a problem.
But it will be better if you can use a element selector attached to the attribute selector like $('div[data-suffix-attribute="delete"]')
If you are very worried about performance it will be a better choice to add a class attribute to the desired elements and then use class selector
It would be better to use id in selector which is fast obviously,
If you have multiple data attributes then it is better to use $('[data-suffix-attribute="delete"]').click();.
Instead of this you can use the parent selector for your data-attribute elements like,
$('#parentId').on('click','[data-suffix-attribute="delete"]',function(){
// delete action happening here
});
#parentId contains all data attribute elements
Hey guys bit of an odd questions but if I add div tags using JQuery .html() and give them an ID can I then use .click on them? The code might explain what I am trying to do. If not is there a possible work around?
I am trying to dynamically change my site without going to a new site.
So if I create Divs with an ID.
$("#funTime").click(function(){
var htmls = $("#content2").html();
$("#content2").html(htmls + " <div id='button1'>Create</div><div id='button2'>Annimate</div><div id='button4'>Clear</div>");
});
$("#button1").click(function(){create();});
$("#button2").click(function(){forannimation();});
$("#button3").click(function(){createOnMouse();});
It does not work but I do not know why.
Thanks in advance.
No you would need .on() to be able to handle dynamic added elements.
$('#content2').on('click', '#button1', function() {
// do your stuff
});
Also note that you can only add a single element with a certain id to the DOM. In your example everytime when the element with id #funTime is clicked you add en element with the same id.
You could improve your code by adding the button with some class instead of an id to the DOM or having a counter to produce unique ids. Or by preventing other clicks on #funTime by using .one() depending on your needs.
You can only assign an event handler to an element that exists. So the assignment of handlers should be done after the creation of the elements:
$("#funTime").click(function(){
var htmls = $("#content2").html();
$("#content2").html(htmls + " <div id='button1'>Create</div><div id='button2'>Annimate</div><div id='button4'>Clear</div>");
$("#button1").click(function(){create();});
$("#button2").click(function(){forannimation();});
$("#button3").click(function(){createOnMouse();});
});
However, several calls clicks on funtime will result in several elements with the same id, which results in an invalid document. Either prevent duplicate ids (e.g. implement a counter) or use classes.
You can actually create elements, bind events to them, all before they are on the screen. Backbone and others to it this way too.
var myNewDiv = $("<div ...>");
myNewDiv.click(function(){});
$(something).append(myNewDiv);
If you want to add events to things that are not yet on the page you must you use jQuery delegate.
You should use an on() listener for dynamically added elements
$("#content2").on('click','#button1',function(){create();});
This will add a listener to check for live added buttons in the selected container (#content2)
To do add thehandler as elements are created would need to add it within the click handler right after elements are appended....otherwise need to use delegation methods like on()
This would work:
$("#funTime").click(function(){
var htmls = $("#content2").html();
$("#content2").html(htmls + " <div id='button1'>Create</div><div id='button2'>Annimate</div><div id='button4'>Clear</div>");
/* elements exist can add event handlers*/
$("#button1").click(function(){create();});
$("#button2").click(function(){forannimation();});
$("#button3").click(function(){createOnMouse();});
});
More common current practice is to use delegation that allows for future elements and can be run on page load
For each checkbox on the web page, I replace it with a slider that I borrowed from jsfiddle.net/gnQUe/170/
This is done by going through the elements when the document is loaded.
Now the problem is that when more content is loaded via ajax, the new checkboxes are not transformed.
To solve the problem, I used AjaxComplete event to go through all the elements again and replace the checkboxes with sliders.
Now the problem happens that elements that were already replaced, get two sliders. To avoid that I check if the checkbox is hidden and next element is div of class "slider-frame", then don't process the re-process the element.
But I have a lot of other such controls as well, and I am presume I am not the only one that has this problem. Is there another easy way around it?
There exists jQuery live/on( http://api.jquery.com/on/ ) event but it requires an event as an argument? whereas I would like to change the look of my controls when they are rendered.
Another example of the same problem is to extend some controls that are loaded via ajax with jQuerys autocomplete plugin.
Is there a better way to accomplish this other than changing some attributes on the element.
To summarize, on document load I would like to process every element in DOM, but when more elements are loaded via ajax then I want to change only the new elements.
I would assume that when the element's are transformed into a slider, a class is added to them. So just add a not clause.
$(".MySelector").not(".SomeClassThatSliderAddsToElement").slider({});
So in the case of your code do something like this
$('.slider-button').not(".sliderloaded").addClass("sliderloaded").toggle(function(){
$(this).addClass('on').html('YES');
$('#slider').val(true);
},function(){
$(this).removeClass('on').html('NO');
$('#slider').val(false);
});
Since you said you do not want to add anything else, how about you change the toggle function to click.
$(document).on("click", ".slider-button", function(){
var elem = $(this);
elem.toggleClass("on");
var state = elem.hasClass("on");
elem.text(state?"YES":"NO");
elem.parent().next().val(state);
});
Running fiddle: http://jsfiddle.net/d9uFs/