0

Basically I want to do something like this:

$("#myElement").ready(function(){
    $("#myElement").attr("id", "new-id");
});

Is this possible? I've looked at jQuery live() which is now deprecated and instead they recommend to use on(), but all solutions I've seen requires event handlers to be attached to the element, such as click, hover etc. I don't want to attach event handlers, I want to simply modify the HTML that is loaded, when it's loaded in the future.

The HTML is loaded by ajax and in this particular case I have no access to modify the ajax file.

Weblurk
  • 6,562
  • 18
  • 64
  • 120
  • could you show your ajax function that create the elements? – Merlin Jan 07 '14 at 14:43
  • 1
    ready pseudo event must be bound only to document. Here, ready event is fired once DOM is ready, nothing about element "#myElement" added or not in DOM – A. Wolff Jan 07 '14 at 14:43
  • @daguru Sorry. It's a long and complicated function that would add more confusion that clarity in this case. But basically it "just" adds the html into a container, based on some settings. – Weblurk Jan 07 '14 at 14:45
  • If you look at the duplicate question I proposed: The accepted answer, in the **update** part, seems to be what you are looking for – musefan Jan 07 '14 at 14:45
  • PS: sorry, didn't saw that: ` I have no access to modify the ajax file.` You could use ajax global method for that – A. Wolff Jan 07 '14 at 14:48
  • Look at this, but you necessarily have to use event handlers: [Link][1] [1]: http://stackoverflow.com/questions/18254257/get-val-of-dynamically-created-input-field/18254670#18254670 – Alexander Ceballos Jan 07 '14 at 14:49
  • @musefan Thank you, on DOMNodeInserted event worked flawlessly. Precisely what I was after. But I can mark a comment as answered. Write a short answer about it and I'll mark yours as answer. – Weblurk Jan 07 '14 at 15:03

4 Answers4

2

MutationObserver

Using MutationObserver is the currently recommended method, although browser support requires IE11+:

var target = document.getElementById('content');

var observer = new MutationObserver(function (mutations) {
    mutations.forEach(function (mutation) {
        for (var i = 0; i < mutation.addedNodes.length; i++) {
            var addedNode = mutation.addedNodes[i];
            if (addedNode.id == "myElement") {
                alert("#myElement added!");
            }
        }
    });
});

var config = {
    attributes: true,
    childList: true,
    characterData: true
};
observer.observe(target, config);

Here is a working example


Mutation Events (deprecated)

This method is deprecated, but will offer browser support from IE9+:

This feature has been removed from the Web. Though some browsers may still support it, it is in the process of being dropped. Do not use it in old or new projects. Pages or Web apps using it may break at any time.

(Above extract taken from here)

With Mutation Events there is an event called DOMNodeInserted which you can listen out for, you can also specify the #myElement selector to get the exact element(s) you want.

This example uses JQuery:

$(document).on('DOMNodeInserted', '#myElement', function(){
    $("#myElement").attr("id", "new-id");
});

NOTE: document should be replaced with what ever selector you need, the more you can limit the area the better.

Here is a working example (element added after 2 seconds)

musefan
  • 47,875
  • 21
  • 135
  • 185
  • using this event on document level could really be a performance killer, but that's depend of OP site of course – A. Wolff Jan 07 '14 at 15:13
  • As @toutpt already pointed out towards Nunners, Mutation Events are deprecated. [MutationObserver](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) should be used instead – though I would prefer [Watch.js](https://github.com/melanke/Watch.JS?utm_source=javascriptweekly) – A.Kalkhoff Jan 07 '14 at 15:14
  • @A.Kalkhoff as i'm aware of, watch.js is for javascript object, not DOM node – A. Wolff Jan 07 '14 at 15:15
  • @A.Wolff: I didn't have anything else to work with, but yes the more specific the better – musefan Jan 07 '14 at 15:15
  • @musefan ya true, but, at least, this should be specified i think. EDIT: ok, i see your EDIT ;) +1 even i'd personally never use this kind of event – A. Wolff Jan 07 '14 at 15:17
  • @A.Wolff ah, true. Has been a while since I last used it – I had in mind that it was possible to watch a property of an element and thus achieving the wanted effect, my bad there :/ – A.Kalkhoff Jan 07 '14 at 15:18
  • @A.Kalkhoff this is still a great plugin imo ;) – A. Wolff Jan 07 '14 at 15:19
  • @A.Kalkhoff: It seems browser support is more restricted for MutationObserver, but I will add something about it to my answer! – musefan Jan 07 '14 at 15:20
  • @musefan You should at least mention the state of deprecation and thus possibly future risks – A.Kalkhoff Jan 07 '14 at 15:22
  • @A.Kalkhoff: yep, done that now. phew, that was hard work – musefan Jan 07 '14 at 15:46
  • @musefan Well deserved upvote there ;) Good work! – A.Kalkhoff Jan 07 '14 at 15:48
1

Using global ajax:

$(document).ajaxSuccess(function (event, xhr, settings) {
   if(settings.url === "urlOfSpecificAjax" && $("#myElement").length)
      $("#myElement").attr("id", "new-id");
});

This supposes the ajax request is done using jQuery and global option not set to false (true is default)

A. Wolff
  • 74,033
  • 9
  • 94
  • 155
0

you need to use a delegated selector. It would look at the static parent element (that is in the DOM) and then find something inside of it by the id you want.

$('.parent-in-DOM').on('click', '#thing-not-in-DOM',function(){
var id = $(this).attr('id');//$(this) is it
    alert("i found "+id);
});

check out jquery .on()

Aage Torleif
  • 1,907
  • 1
  • 20
  • 37
  • Correct me if I'm not understanding this correctly: Wouldn't this only work if the '.parent-in-DOM' is clicked? It does detect whether the element has been created or not, but it does not fire at the moment it is created (which is the goal) – A.Kalkhoff Jan 07 '14 at 15:03
-1

There are no events emited when dom is modified, so you can't bind on an event.

You are loading content with ajax and you want it to be modified by javascript, so you have to plug into the ajax callback

You must write a transform function that will be called by your ajax callback:

var transformid = function(){
   $("#myElement").attr("id", "new-id");
}

$.ajax({
  url: "your.php",
}).done(function() {
  transformid();
});
toutpt
  • 5,145
  • 5
  • 38
  • 45