Вы не хотите, занятой-ждать, потому что никаких других JavaScript не могут работать (не говоря уже о больших частях интерфейса браузера), и поэтому свойство не будет определено.
В идеале, независимо от того, что это свойство будет иметь событие, которое оно запускает, в которое вы можете подключиться. Я собираюсь предположить, что вы посмотрели и не нашли его. :-)
После того, как поддержка последней вещи в ECMAScript6 (ака «ES6») становится широко распространенным (не в настоящее время), вы может быть в состоянии использовать Proxy
для этого (при условии вашей целевой браузеры позволили Proxy
на их экземплярах HTML-элементов). Но достаточно широко распространенная поддержка Proxy
займет пару лет, если не дольше (и Proxy
не может быть прорежена/полифорирована). (В ES7, вы могли бы использовать Object.observe
, но предположительно Proxy
, который определяется током [по состоянию на июнь 2015] стандарт будет широко поддерживаемый до того, как технология ES7 есть.)
До /, если вы не можете использовать Proxy
, таймер действительно является правильным способом справиться с этой ситуацией. При необходимости это может быть действительно агрессивный таймер.
Если элемент известно, существует, но вы ждете собственности:
check(function(element) {
// It's there now, use it
// x = element.jsMF2
});
function check(callback) {
var element = document.querySelector('#embed-container #mf2-events');
if (element && 'jsMF2' in element) {
setTimeout(callback.bind(null, element), 0);
} else {
setTimeout(check.bind(null, callback), 0);
}
}
Большинство браузеров будет срабатывать этот таймер сразу когда поток JavaScript доступен первый пару раз, затем выключите его, по крайней мере, на 4 мс для последующих вызовов. Все еще довольно быстро.
Вам не обязательно быть гиперагрессивным; люди медленны по сравнению с компьютерами, вы, вероятно, могли бы использовать 10, 20 или даже 50 мс.
Если есть любые шанса, что свойство не будет отображаться, вы хотите, чтобы остановить эту повторную серию setTimeout
в конечном итоге (после секунды, после 10 секунд, через 30 секунд, после 60 секунд, независимо от Уместно к использованию дело). Вы можете сделать это, помня, когда вы начали, а потом просто отказаться, а не перепланирование, если это было слишком долго:
var started = Date.now();
check(function(element) {
// It's there now, use it
// x = element.jsMF2
});
function check(callback) {
var element = document.querySelector('#embed-container #mf2-events');
if (element && 'jsMF2' in element) {
setTimeout(callback.bind(null, element), 0);
} else {
if (Date.now() - started > 1000) { // 1000ms = one second
// Fail with message
} else {
setTimeout(check.bind(null, callback), 0);
}
}
}
Side Примечание: Запрос,
var document.querySelector('#embed-container #mf2-events');
... есть немного странно. В нем говорится: Дайте мне первый элемент с id
mf2-events
, найденным внутри элемента с id
embed-container
.Но id
значения должно быть быть уникальным на странице. Итак, все, что на самом деле говорит, это «Получить tme элемент #mfs-events
, но только если он находится внутри элемента #embed-container
».
Если что нет действительно то, что вы имели в виду, то значительно быстрее
var document.getElementById('mf2-events');
... был бы в путь.
Вы имеете в виду * многопоточную программу C, это то, что вы сделали бы. JavaScript в браузерах (кроме случаев, когда они используются в качестве веб-работников) действительно выполняется в одном потоке. –
Вам нужно будет либо опросить с помощью 'setTimeout()', либо вы можете использовать ['MutationObserver'] (https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) в современном браузере , Спиннинг в цикле 'while' просто заблокирует браузер, и это никогда не будет успешным, потому что никакой другой код не может работать, чтобы фактически вызвать изменение. – jfriend00
@ user3689167: Правильно, но если программа была действительно однопоточной, она была бы занята - ждать вечно - потому что никогда не появляется возможность установить jsMF2. Для этого * while * busy-waiting вам нужно как минимум два потока. –