简体   繁体   中英

Why isn't my jQuery function being executed when a value is greater than?

I have a table with a row defined like this:

<tr>
  <td id="to-watch">
      @Model.Results.Seats
  </td>
</tr>

Edit: The table values are being updated by ajax calls to an action which is returning data to the table in a partial

I want to log to the console when the value is greater than 2, here is the jQuery code I have:

$('#to-watch')
    .change(function () {
        if ($('#to-watch').val() > 2) {
            console.log("************ WINNER ***************");
        }
    });

I have checked in Chrome debugging tools nothing is being logged to the console when the value is greater than 2 - I rarely use jQuery / JavaScript, and after some looking, haven't been able to find the answer..

Edit: I'm making the ajax call like this:

$(document).ready(function () {

    (function loop(i) {
        setTimeout(function () {
            callAjax(i);
            //console.log("works " + i);
        },
            500); // ms
        function callAjax(i) {
            $.ajax({
                url: '/Home/StartElection',
                type: 'POST',
                data: "test",
                async: true
            })
                .done(function (partialViewResult) {
                    $("#partialTable").html(partialViewResult);
                }).always(function () {
                    if (--i) loop(i);
                });
        };
    })(650);
});

There are a couple of problems here.


Firstly, the change event is for input fields. It will execute the callback whenever the value of the input field changes.

There is an equivalent for when any html changes, using Mutation Observers , but it's overly complex for this scenario, as you know when the html changes, and it is done via your code.


Secondly, you are attaching an event listener to #to-watch , which I assume is nested inside #partialTable . Now we already know the change event won't work anyway, but even if this was an input field, we would have the following problem:

  1. Attach listener to DOM element with #to-watch
  2. Make ajax call
  3. On return of ajax call, replace all of #partialTable with a new version of it.
  4. The old #to-watch element is now gone, and so is it's event listener. It can't be triggered anymore.

The solution to this is called event delegation . Meaning you attach the listener to a parent element that doesn't change, and it checks if any child elements matching the selector are changed. This means that id the child elements were changed dynamically, the listener will still work.


Then there are also the aforementioned:

$('...').text() will give you the contents of any DOM element, where as $('...').val() will give the value of an input field

JQUERY .text() docs

JQUERY .val() docs

You want to do a numerical comparison ( X > Y ), so you should convert the string "2" which is the text of $('#to-watch') into an integer with parseInt(x)


The solution to your problem

When you update the #partialTable , you know that the #to-watch element has received a new value, so now is the time to check it:

      function callAjax(i) {
        $.ajax({
            url: '/Home/StartElection',
            type: 'POST',
            data: "test",
            async: true
        }).done(function (partialViewResult) {
            $("#partialTable").html(partialViewResult);
            if (parseInt($('#to-watch').text()) > 2) {
              console.log("************ WINNER ***************");
            }
        }).always(function () {
            if (--i) loop(i);
        });
    };

您可以尝试使用JQuery函数中的text()代替val()。

Please try text() .

text() - Sets or returns the text content of selected elements
html() - Sets or returns the content of selected elements (including HTML markup)
val() - Sets or returns the value of form fields

Please check the this link for DOM Insertion using Jquery

$(body).on('mycontentchange','#to-watch', function() {//make sure #to-watch is available in DOM while binding, or use `on` to delegate the event
    console.log('new content updated',$('#to-watch').text());
});

            .done(function (partialViewResult) {
                $("#partialTable").html(partialViewResult);
                $('#to-watch').trigger('mycontentchange');
            }).always(function () {
                if (--i) loop(i);
            });

This is just a direct answer to the question, you probably have better ways to solve the problem :) This is an overkill as @jeremy pointed out considering your continuous polling.

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