简体   繁体   中英

How to use jQuery to change attributes of a newly created element

I have the following code:

if (secsleft < 10) {
    var msg = 'No activity detected in the last 10 seconds.';
    if (auth == "true"){
        msg += '<br />You will be logged out in <br /><p id="counter">' + secsleft + '</p><br /> more seconds if no activity is detected.'; 
    } else {
        msg += '<br />You will be redirected in <br /><p id="counter">' + secsleft + '</p><br /> more seconds if no activity is detected.';
    }
    if (secsleft < 4) {
        //$("#counter").css({"color":"red"});
        //$("#counter").css("color", "red");
        document.getElementById("counter").style.color = "red";
    }
    Message('<span id="timer">' + msg + '</span>', 10000);
}

The intent obviously is to change the color of the counter to red when less than four seconds are left. The problem is that the p tag with id="counter" is first created in the IF statement. If I was looking to bind an event to it, I know how to do it. It would be something like:

$(document).on(eventName, "#counter", function() {});

But that doesn't work for attributes. I have tried all kinds of combinations as you can see from the commented code in the inner IF, but none work. Incidentally (and surprisingly to me), I can get the attribute easily, so for example:

alert($("#counter").css("color"));

gives me the right value. So, how does one change the value?

The issue is that you're not actually creating the element until after that if statement, so all of your jQuery selectors and getElementById calls will not find anything on the page since there is nothing with an id of "counter" yet. You've simply made a string that you will later convert into an actual element.

What you need to do is create an actual element and then using a reference to it you can change its attributes before you even put it on the page.

var counter = document.createElement('p');
counter.id = 'counter';
counter.style.color = red;

Or something along those lines. I've shown you the vanilla JS solution here but you can do the same using jQuery:

var counter = $('<p></p>');
counter.attr('id','counter');
counter.css('color','red');

You can't use document.getElementById() for elements which have not yet been added to the document. That's why it doesn't work.

You could simplify your code a lot.

  if (secsleft < 10) {
    var color = secsleft < 4 ? 'red' : 'inherit';
    var action = auth === 'true' ? 'logged out' : 'redirected';
    var msg = 'No activity detected in the last 10 seconds.'
            + '<br />You will be '+ action +' in '
            + '<span style="color: '+ color +'">' + secsleft + '</span>'
            + ' more seconds if no activity is detected.';  
    Message('<span id="timer">' + msg + '</span>', 10000);
  }

I don't see much jQuery but you did add it as a tag. So why not do something like this?

$("body").find("#counter").css("color", "red");

The first problem is that you haven't yet added the #counter element to the document , meaning you can't use the document.getElementByID(...); method on it ( yet ).

To be able to manipulate a element, you would have to add it to the document, to do this you would use:

// appends the new "div" element to the body (I.E: inserts the new element at the end of the body)
$("body").append("<div id='element-id'>Hello World!</div>");

You could also use these methods:

// replaces the "innerHTML" of the "body" element with the new "div" element
$("body").html("<div id='element-id'>Hello World!</div>");
// prepends the new div to the body (I.E: inserts the element as the first child not the last child)
$("body").prepend("<div id='element-id'>Hello World!</div>");

Now, the second problem is that you are getting the value of the CSS property and NOT setting it.

To get the current value of a CSS property you would use this:

$("#element-id").css("property-name")

To change the value of a CSS attribute in jQuery you would use this:

// listen for an event to occur
$(document).on("event-name", function() {
  // change a single property of the element
  $("#element-id").css("property", "new-value");
});

You could also change multiple properties of the element at once, using a JavaScript object like this:

// listen for an event to occur
$(document).on("event-name", function() {
  // change multiple properties of the element using a JavaScript object
  $("#element-id").css({
    "property-name-one": "new-value",
    "property-name-two": "new-value"
  });
});

For more information on the jQuery methods mentioned above, visit the links below:

Hope this helps, good luck and all the best.

I think there is a neater way to achieve what you are looking for rather can adding in the styles using jQuery. Instead it is better to allow your CSS to handle the styles and the jQuery to add in classes where appropriate.

In the below code the <4 check is used to assign a value to a counterClass variable which is then added to you counter element. You can then add a css rule to achieve the red colour.

if (secsleft < 10) {
    var counterClass = "";
    if (secsleft < 4) {
        counterClass = "warning";
    }
    var msg = 'No activity detected in the last 10 seconds.';
    if (auth == "true") {
        msg += '<br />You will be logged out in <br />p id="counter" class="' + counterClass + '">' + secsleft + '</p><br /> more seconds if no activity is detected.';
    } else {
        msg += '<br />You will be redirected in <br /><p id="counter" class="' + counterClass + '">' + secsleft + '</p><br /> more seconds if no activity is detected.';
    }
    Message('<span id="timer">' + msg + '</span>', 10000);
}

Hope this helps.

You will not get element using getElementById which have not yet been added to DOM. you can use inline styles.

if (secsleft < 10) {
                var alertColor = "inherit";
                if(secsleft < 4) {
                    alertColor = "red";
                }
                var msg = 'No activity detected in the last 10 seconds.';
                if (auth == "true"){
                    msg += '<br />You will be logged out in <br /><p id="counter" style="' + alertColor + '">' + secsleft + '</p><br /> more seconds if no activity is detected.'; 
                } else {
                    msg += '<br />You will be redirected in <br /><p id="counter" style="' + alertColor + '">' + secsleft + '</p><br /> more seconds if no activity is detected.';
                }                    
                Message('<span id="timer">' + msg + '</span>', 10000);
            }

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