te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>jquery - How to wait until an element exists with JavaScript? - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

jquery - How to wait until an element exists with JavaScript? - Stack Overflow

programmeradmin3浏览0评论

I'm working with a proxy object where I detect a object value change and then load new content via AJAX, I use a setInterval function to wait until a the element that es in the AJAX request exist and then execute a piece of code. I'm doing in this way because my case requires it. I made a short snippet example:

var handler = {
    makeThings: 0,
    otherStuff: 0
};
var globalHandler = new Proxy(handler, {
    set: function(obj, prop, value) {
        obj[prop] = value
        if (prop == "makeThings") {
            var clearTimeSearchProxy = setInterval(function() {
                if ($("p").length) {
                    console.log("The element finally exist and we execute code");
                    clearTimeout(clearTimeSearchProxy);
                }
            }, 100);
        }
        return true;
    }
});

$(document).ready(function() {
    $("button").on("click", function() {
        globalHandler.makeThings = 1;
        //This element es with ajax but I use a setTimeout for this example
        setTimeout(function() {
            $("#newContent").append("<p>Ajax element</p>");
        }, 2000);
    });
});
<script src=".3.1/jquery.min.js"></script>
<body>
  <button>New content</button>
  <div id="newContent"></div>
</body>

I'm working with a proxy object where I detect a object value change and then load new content via AJAX, I use a setInterval function to wait until a the element that es in the AJAX request exist and then execute a piece of code. I'm doing in this way because my case requires it. I made a short snippet example:

var handler = {
    makeThings: 0,
    otherStuff: 0
};
var globalHandler = new Proxy(handler, {
    set: function(obj, prop, value) {
        obj[prop] = value
        if (prop == "makeThings") {
            var clearTimeSearchProxy = setInterval(function() {
                if ($("p").length) {
                    console.log("The element finally exist and we execute code");
                    clearTimeout(clearTimeSearchProxy);
                }
            }, 100);
        }
        return true;
    }
});

$(document).ready(function() {
    $("button").on("click", function() {
        globalHandler.makeThings = 1;
        //This element es with ajax but I use a setTimeout for this example
        setTimeout(function() {
            $("#newContent").append("<p>Ajax element</p>");
        }, 2000);
    });
});
<script src="https://cdnjs.cloudflare./ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
  <button>New content</button>
  <div id="newContent"></div>
</body>

Now I'm wondering about how to improve the code in a cleaner, efficient and elegant way. I was thinking of using promises instead of setInterval to execute a code when the element that es via AJAX exists in the DOM.

How can I make it work? Should I use other JavaScript functionality for this case instead of promises? I'm stuck with the promise to achieve what I need, this what I have tried so far.

var handler = {
    makeThings: 0,
    otherStuff: 0
};
var globalHandler = new Proxy(handler, {
    set: function(obj, prop, value) {
        obj[prop] = value
        if (prop == "makeThings") {
            var myFirstPromise = new Promise((resolve, reject) => {
                if ($("p").length) {
                    resolve("Exist");
                } else {
                    reject("It doesnt exist.");
                }
            });

            myFirstPromise.then((data) => {
                console.log("Done " + data);
            }).catch((reason) => {
                console.log("Handle rejected promise: " + reason);
            });
        }
        return true;
    }
});

$(document).ready(function() {
    $("button").on("click", function() {
        globalHandler.makeThings = 1;
        //This element es with ajax but I use a setTimeout for this example
        setTimeout(function() {
            $("#newContent").append("<p>Ajax element</p>");
        }, 2000);
    });
});
<script src="https://cdnjs.cloudflare./ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
  <button>New content</button>
  <div id="newContent"></div>
</body>

Share Improve this question edited Aug 8, 2019 at 6:48 BSMP 4,8078 gold badges35 silver badges45 bronze badges asked Aug 7, 2019 at 9:56 SilverSurferSilverSurfer 4,3666 gold badges26 silver badges55 bronze badges 1
  • 1 Does this answer your question? How to wait until an element exists? – Igwe Kalu Commented Jan 18, 2020 at 18:29
Add a ment  | 

3 Answers 3

Reset to default 5

Do not wait. Rather subscribe for notification of a change in the target element.

The API to utilise for listening to changes in the DOM tree is the MutationObserver.

The MutationObserver interface provides the ability to watch for changes being made to the DOM tree. It is designed as a replacement for the older Mutation Events feature which was part of the DOM3 Events specification.

Use it to observe change in an element as follows:

// You selected `$("p")` in your snippet, suggesting you're watching for the inclusion of 'any' `p` element.
// Therefore we'll watch the `body` element in this example
const targetNode = document.body;

// Options for the observer (which mutations to observe)
const config = {
    attributes: false,
    characterData: false,
    childList: true,
    subtree: true
};

// Callback function to execute when mutations are observed
const callback = function(mutationsList, observer) {
    for(let mutation of mutationsList) {

        if ( mutation.type === "childList" ) {
            continue;
        }

        const addedNodes = Array.from( mutation.addedNodes) ;

        if ( addedNodes && addedNodes.some( node => node.nodeName === "P" ) ) {
            observer.disconnect();

            console.log("The element finally exist and we execute code");
        }
    }
};

// Create an observer instance linked to the callback function
const observer = new MutationObserver(callback);

// Start observing the target node for configured mutations
observer.observe(targetNode, config);

I finally made it with MutationObserverinterface in an easy way instead of with promises.

var handler = {
    makeThings: 0,
    otherStuff: 0
};
var globalHandler = new Proxy(handler, {
    set: function(obj, prop, value) {
        obj[prop] = value
        if (prop == "makeThings") {
            var observer = new MutationObserver(function(mutations) {
                if ($("p").length) {
                    console.log("Exist, lets do something");
                    observer.disconnect();
                }
            });
            // start observing
            observer.observe(document.body, {
                childList: true,
                subtree: true
            });
        }
        return true;
    }
});

$(document).ready(function() {
    $("button").on("click", function() {
        $("p").remove();
        globalHandler.makeThings = 1;
        //This element es with ajax but I use a setTimeout for this example
        setTimeout(function() {
            $("#newContent").append("<p>Ajax element</p>");
        }, 2000);
    });
});
<script src="https://cdnjs.cloudflare./ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
  <button>New content</button>
  <div id="newContent"></div>
</body>

rxjs can highly simplify what you are trying to do. A very basic implementation, using only a Subject and subscription:

const {
  Subject
} = rxjs;

const sub = new Subject();

sub.subscribe(e => {
  console.log(`received data ${e}`);
  // do your thing
});

// simulate something async
setTimeout(() => {
  sub.next('foo');
}, 1000);
<script src="https://unpkg./[email protected]/bundles/rxjs.umd.min.js"></script>

发布评论

评论列表(0)

  1. 暂无评论