У меня была та же проблема с vs2013, и изменение политики выполнения не исправить. Единственным рабочим решением, которое я нашел, было удаление Nuget из VS и его установка снова. Шаги здесь: https://stackoverflow.com/a/32619961/3853238
DOMNodeInserted
устарел, наряду с другими событиями мутации DOM, из-за проблем с производительностью - рекомендуется использовать MutationObserver для просмотра DOM. Однако он поддерживается только в новых браузерах, поэтому вы должны вернуться на DOMNodeInserted
, когда MutationObserver
недоступен.
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (!mutation.addedNodes) return
for (var i = 0; i < mutation.addedNodes.length; i++) {
// do things to your newly added nodes here
var node = mutation.addedNodes[i]
}
})
})
observer.observe(document.body, {
childList: true
, subtree: true
, attributes: false
, characterData: false
})
// stop watching using:
observer.disconnect()
Вы можете сделать
$('#yourelement').ready(function() {
});
Обратите внимание, что это будет работать, только если элемент присутствует в DOM при запросе с сервера. Если элемент динамически добавляется через JavaScript, это не сработает, и вам, возможно, придется посмотреть на другие ответы.
.ready()
работает для большинства вещей (если не что-либо), а не только document
. Он просто не будет работать с динамически создаваемыми элементами, даже на .live()
.
– Richard Neil Ilagan
2 April 2011 в 19:47
$(document).ready()
, а не тем элементом, который, по вашему мнению, будет применяться. Вот как работает этот специальный i> прослушиватель. [Д0] Пример
– Shikkediel
2 February 2016 в 19:34
Вот решение, возвращающее обещание в ванильном Javascript (без грязных обратных вызовов). По умолчанию он проверяет каждые 200 мс.
function waitFor(selector) {
return new Promise(function (res, rej) {
waitForElementToDisplay(selector, 200);
function waitForElementToDisplay(selector, time) {
if (document.querySelector(selector) != null) {
res(document.querySelector(selector));
}
else {
setTimeout(function () {
waitForElementToDisplay(selector, time);
}, time);
}
}
});
}
Вы можете прослушивать события DOMNodeInserted
или DOMSubtreeModified
, которые срабатывают всякий раз, когда новый элемент добавляется в DOM.
Существует также плагин LiveQuery jQuery, который будет определять, когда будет создан новый элемент:
$("#future_element").livequery(function(){
//element created
});
Для простого подхода с использованием jQuery я нашел, что это хорошо работает:
// Wait for element to exist.
function elementLoaded(el, cb) {
if ($(el).length) {
// Element is now loaded.
cb($(el));
} else {
// Repeat every 500ms.
setTimeout(function() {
elementLoaded(el, cb)
}, 500);
}
};
elementLoaded('.element-selector', function(el) {
// Element is ready to use.
el.click(function() {
alert("You just clicked a dynamically inserted element");
});
});
Здесь мы просто проверяем каждые 500 мс, чтобы увидеть, загружен ли элемент, когда он есть, мы можем его использовать .
Это особенно полезно для добавления обработчиков кликов к элементам, которые динамически добавлены в документ.
Вот функция, которая действует как тонкая оболочка вокруг MutationObserver. Единственное требование - браузер поддерживает MutationObserver; нет никакой зависимости от JQuery. Выполните фрагмент ниже, чтобы увидеть рабочий пример.
function waitForMutation(parentNode, isMatchFunc, handlerFunc, observeSubtree, disconnectAfterMatch) {
var defaultIfUndefined = function(val, defaultVal) {
return (typeof val === "undefined") ? defaultVal : val;
};
observeSubtree = defaultIfUndefined(observeSubtree, false);
disconnectAfterMatch = defaultIfUndefined(disconnectAfterMatch, false);
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.addedNodes) {
for (var i = 0; i < mutation.addedNodes.length; i++) {
var node = mutation.addedNodes[i];
if (isMatchFunc(node)) {
handlerFunc(node);
if (disconnectAfterMatch) observer.disconnect();
};
}
}
});
});
observer.observe(parentNode, {
childList: true,
attributes: false,
characterData: false,
subtree: observeSubtree
});
}
// Example
waitForMutation(
// parentNode: Root node to observe. If the mutation you're looking for
// might not occur directly below parentNode, pass 'true' to the
// observeSubtree parameter.
document.getElementById("outerContent"),
// isMatchFunc: Function to identify a match. If it returns true,
// handlerFunc will run.
// MutationObserver only fires once per mutation, not once for every node
// inside the mutation. If the element we're looking for is a child of
// the newly-added element, we need to use something like
// node.querySelector() to find it.
function(node) {
return node.querySelector(".foo") !== null;
},
// handlerFunc: Handler.
function(node) {
var elem = document.createElement("div");
elem.appendChild(document.createTextNode("Added node (" + node.innerText + ")"));
document.getElementById("log").appendChild(elem);
},
// observeSubtree
true,
// disconnectAfterMatch: If this is true the hanlerFunc will only run on
// the first time that isMatchFunc returns true. If it's false, the handler
// will continue to fire on matches.
false);
// Set up UI. Using JQuery here for convenience.
$outerContent = $("#outerContent");
$innerContent = $("#innerContent");
$("#addOuter").on("click", function() {
var newNode = $("<div><span class='foo'>Outer</span></div>");
$outerContent.append(newNode);
});
$("#addInner").on("click", function() {
var newNode = $("<div><span class='foo'>Inner</span></div>");
$innerContent.append(newNode);
});
.content {
padding: 1em;
border: solid 1px black;
overflow-y: auto;
}
#innerContent {
height: 100px;
}
#outerContent {
height: 200px;
}
#log {
font-family: Courier;
font-size: 10pt;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>Create some mutations</h2>
<div id="main">
<button id="addOuter">Add outer node</button>
<button id="addInner">Add inner node</button>
<div class="content" id="outerContent">
<div class="content" id="innerContent"></div>
</div>
</div>
<h2>Log</h2>
<div id="log"></div>
Как насчет библиотеки insertionQuery ?
insertionQuery использует обратные вызовы анимации CSS, прикрепленные к селектору (ям), указанным для запуска обратного вызова при создании элемента. Этот метод позволяет запускать обратные вызовы всякий раз, когда создается элемент, а не только в первый раз.
Из github:
Способ не-dom-event для обнаружения узлов, отображающих ,
Это не только для более широкой поддержки браузера. Это может быть лучше, чем DOMMutationObserver для определенных вещей.
Почему?
- Потому что DOM Events замедляет работу браузера, а insertionQuery не работает
- . Поскольку DOM Mutation Observer имеет меньшую поддержку браузера, чем insertionQuery
- . Поскольку с помощью insertionQuery вы можете фильтровать изменения DOM с помощью селекторов без служебных издержек!
Широкая поддержка!
IE10 + и в основном что-нибудь еще (в том числе мобильное)
Я использовал этот подход для ожидания появления элемента, чтобы потом выполнить другие функции.
Предположим, что функция doTheRestOfTheStuff(parameters)
должна вызываться только после появления элемента с идентификатором the_Element_ID
или законченная загрузка, мы можем использовать
var existCondition = setInterval(function() {
if ($('#the_Element_ID').length) {
console.log("Exists!");
clearInterval(existCondition);
doTheRestOfTheStuff(parameters);
}
}, 100); // check every 100ms
У меня была такая же проблема, поэтому я пошел дальше и написал для нее плагин .
$(selector).waitUntilExists(function);
Код:
;(function ($, window) {
var intervals = {};
var removeListener = function(selector) {
if (intervals[selector]) {
window.clearInterval(intervals[selector]);
intervals[selector] = null;
}
};
var found = 'waitUntilExists.found';
/**
* @function
* @property {object} jQuery plugin which runs handler function once specified
* element is inserted into the DOM
* @param {function|string} handler
* A function to execute at the time when the element is inserted or
* string "remove" to remove the listener from the given selector
* @param {bool} shouldRunHandlerOnce
* Optional: if true, handler is unbound after its first invocation
* @example jQuery(selector).waitUntilExists(function);
*/
$.fn.waitUntilExists = function(handler, shouldRunHandlerOnce, isChild) {
var selector = this.selector;
var $this = $(selector);
var $elements = $this.not(function() { return $(this).data(found); });
if (handler === 'remove') {
// Hijack and remove interval immediately if the code requests
removeListener(selector);
}
else {
// Run the handler on all found elements and mark as found
$elements.each(handler).data(found, true);
if (shouldRunHandlerOnce && $this.length) {
// Element was found, implying the handler already ran for all
// matched elements
removeListener(selector);
}
else if (!isChild) {
// If this is a recurring search or if the target has not yet been
// found, create an interval to continue searching for the target
intervals[selector] = window.setInterval(function () {
$this.waitUntilExists(handler, shouldRunHandlerOnce, true);
}, 500);
}
}
return $this;
};
}(jQuery, window));
window.setInterval
). Я не знаю, работает ли MutationObserver
ответ на опрос ...
– sports
30 March 2015 в 21:18
;
в начале функции (;(function ($, window) {
)?
– mrid
23 December 2016 в 11:36
Вот чистая функция Javascript, которая позволяет вам ждать чего угодно. Установите интервал дольше, чтобы получить меньше ресурсов ЦП.
/**
* @brief Wait for something to be ready before triggering a timeout
* @param {callback} isready Function which returns true when the thing we're waiting for has happened
* @param {callback} success Function to call when the thing is ready
* @param {callback} error Function to call if we time out before the event becomes ready
* @param {int} count Number of times to retry the timeout (default 300 or 6s)
* @param {int} interval Number of milliseconds to wait between attempts (default 20ms)
*/
function waitUntil(isready, success, error, count, interval){
if (count === undefined) {
count = 300;
}
if (interval === undefined) {
interval = 20;
}
if (isready()) {
success();
return;
}
// The call back isn't ready. We need to wait for it
setTimeout(function(){
if (!count) {
// We have run out of retries
if (error !== undefined) {
error();
}
} else {
// Try again
waitUntil(isready, success, error, count -1, interval);
}
}, interval);
}
Чтобы вызвать это, например, в jQuery, используйте что-то вроде:
waitUntil(function(){
return $('#myelement').length > 0;
}, function(){
alert("myelement now exists");
}, function(){
alert("I'm bored. I give up.");
});
Вот основная функция JavaScript, чтобы дождаться отображения элемента.
Параметры:
selector
: Эта функция ищет элемент $ {selector } time
: эта функция проверяет, существует ли этот элемент каждые $ {time} миллисекунд. function waitForElementToDisplay(selector, time) {
if(document.querySelector(selector)!=null) {
alert("The element is displayed, you can put your code instead of this alert.")
return;
}
else {
setTimeout(function() {
waitForElementToDisplay(selector, time);
}, time);
}
}
В качестве примера установка selector="#div1"
и time=5000
будет искать HTML-тег, чей id="div1"
каждые 5000 миллисекунд.
querySelector
? developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
– mattsven
20 April 2015 в 17:19
Более чистый пример использования MutationObserver:
new MutationObserver( mutation => {
if (!mutation.addedNodes) return
mutation.addedNodes.forEach( node => {
// do stuff with node
})
})
<div>
? – user2284570 12 October 2014 в 21:01if (mutation.addedNodes.length)
, так какif (mutation.addedNodes)
все равно вернет true, даже если это пустой массив. (2) Вы не можете сделатьmutation.addedNodes.forEach()
, потому что addedNodes является nodeList, и вы не можете перебирать nodeList с forEach. Для решения этого вопроса см. toddmotto.com/ditch-the-array-foreach-call-nodelist-hack – thdoan 15 January 2015 в 05:57