在继续之前等待DOM元素中的特定文本

时间:2017-06-03 15:43:56

标签: javascript jquery

我有一个函数应该在返回值之前等待一些文本更改:

function getElementText() {
   while(isLoading()) {
   }
   return $('#element').text();
}

function isLoading() {
    return  $('#element')[0] &&
            $('#element').text().indexOf('Loading') >= 0;
}

但是我认为空的while不是一个好的选择(它会阻止事件循环吗?)

3 个答案:

答案 0 :(得分:1)

不需要jQuery或任何其他外部库,只需使用MutationObserver:https://developer.mozilla.org/en/docs/Web/API/MutationObserver

这是一个简单的示例,当您的文字发生变化时,您会收到characterData类型的通知(在我的示例中为5秒后):



// select the target node
var target = document.getElementById('some-id');
 
// create an observer instance
var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    console.log(mutation.type);
  });    
});
 
// configuration of the observer:
var config = { attributes: true, childList: true, characterData: true, attributes: true, subtree: true };
 
// pass in the target node, as well as the observer options
observer.observe(target, config);
 
// later, you can stop observing
//observer.disconnect();
setTimeout(function() {
	target.innerText = 'Changed text!';
}, 5000);

<div id="some-id">
  AAA
</div>
&#13;
&#13;
&#13;

从观察者的配置中移除您不需要监视更改的所有属性

答案 1 :(得分:1)

rxjs的优雅方式:

&#13;
&#13;
var source = document.getElementById('source');
var target = document.getElementById('target');

Rx.Observable.fromEvent(source, 'keyup')
  .filter( (e) => e.target.value === 'Admin' )
  .subscribe( () => target.innerText = "Matched." );
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.0/Rx.min.js"></script>

<input id="source" /> <strong>input 'Admin' to trigger</strong>
<p id="target">Not match.</p>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

当元素发生更改时,将触发DOMSubtreeModified事件,因此您可以使用它来检测文本是否已加载。

您可以使用回调函数在加载时返回值。甚至更好:(jQuery)承诺!

&#13;
&#13;
var element = document.getElementById('element');

function isLoading() {
    return element.innerText.indexOf('Loading') >= 0;
}

function getElementText() {
    var def = $.Deferred();

    if (!isLoading()) {
        def.resolve(element.innerText);
        return def.promise();
    }

    $(element).on('DOMSubtreeModified', function () {
        if (!isLoading()) {
            def.resolve(element.innerText);
        }
    });

    return def.promise();
}

getElementText().then(function (text) {
    // Text is loaded!
    alert(text);
});

// Load text after 3 seconds for demonstration
setTimeout(function () {
    element.innerText = 'Changed!';
}, 3000);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="element">Loading</div>
&#13;
&#13;
&#13;