2017-12-21 13 views
1

このコードは、データIDの間で最も高い数値を選択し、ライムの背景を追加します。
このコードは、ページが最初に読み込まれたときにのみ動作しますが、ページが読み込まれると、data-idが変更されていて新しいデータIDを検索していませんでした。コードを再起動するための関数を追加しましたが、動作しません。コードをもう一度開始するには? (動的に更新されるページで)

変化するデータIDを見つけて石灰の背景を追加するにはどうすればよいですか?

私はTampermonkeyとGreasemonkeyで使用しています。

var i = 0, howManyTimes = 20; 
 
function f() { 
 
    maxData = $(".answers li[data-id]").get().reduce((maxObj, crrntNode) => { 
 
     var node = $(crrntNode).data("id"); 
 
     var idVal = parseInt(node.substr(node.length - 4), 16); 
 

 
     if (idVal > maxObj.value) { 
 
      maxObj.value = idVal; 
 
      maxObj.node = crrntNode; 
 

 
     } 
 
     return maxObj; 
 
    }, 
 
     { value: 0, node: null } 
 
    ); 
 
    // $("body").append (`<p>The highest data-id value was ${maxData.value}.</p>`) 
 
    $(maxData.node).css("background", "lime").attr("id", "findvalue"); 
 

 
    $(document).ready(function() { //When document has loaded 
 

 
     setTimeout(function() { 
 
      // document.getElementById("findvalue").setAttribute("id", "oldvalue"); 
 
      $('li').css("background", ""); 
 
     }, 100); //Two seconds will elapse and Code will execute. 
 
    }); 
 

 
    var x = Math.floor((Math.random() * 500) + 1); 
 
    i++; 
 
    if (i < howManyTimes) { 
 
     setTimeout(f, x); 
 
    } 
 
} 
 
f();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="question-text" class="question sp-element border-radius active">What is favorite colour?</div> 
 
<ul class="answers" id="answers"> 
 
    <li data-id="58b9890062279282090ddc61" class="answer active">Purple</li> 
 
    <li data-id="58b9890062279282090ddc85" class="answer active">Blue</li> 
 
    <li data-id="58b9890062279282090ddc64" class="answer active">Yellow</li> 
 
    <li data-id="58b9890062279282090ddc66" class="answer active">Red</li> 
 
</ul>

+0

::[11195658](/ Q/11195658)、[14024120](/とにかく

は、ここに新しい/ MutationObserverを使用して答えを変更を検出する方法でありますq/14024120)、および[17385145](/ q/17385145)である。 –

答えて

1

ハッキングしようとしているページ/サイトは、明らかにAJAX経由で更新されています。これはwaitForKeyElements()またはMutationObserverに最も適したジョブです。
これはsetTimeout()には適していません。とにかく、setInterval()はよりフィット感があります。

また、スクリプトが@run-at document-startに設定されていない限り、$(document).readyは必要ありません。ほぼQさんの複製

function highliteMaxAnswer() { 
 
    var maxData  = $(".answers li[data-id]").get().reduce ((maxObj, crrntNode) => { 
 
     //-- Don't trust page to update data. But we know attributes are changing. 
 
     var nodeId = $(crrntNode).attr ("data-id"); 
 
     var idVal = parseInt (nodeId.slice (-4), 16); 
 
     if (idVal > maxObj.value) { 
 
      maxObj.value = idVal; 
 
      maxObj.node = crrntNode; 
 
     } 
 
     return maxObj; 
 
     }, 
 
     {value: 0, node: null} 
 
    ); 
 
    $(".answers li[data-id]").css ("background", ""); 
 
    $(maxData.node).css ("background", "lime"); 
 
} 
 
highliteMaxAnswer(); 
 

 
var answerObsrvr = new MutationObserver (answerChangeHandler); 
 
var obsConfig  = { 
 
    childList: true, attributes: true, subtree: true, attributeFilter: ['data-id'] 
 
}; 
 
answerObsrvr.observe (document.body, obsConfig); // Use container versus body, if possible. 
 

 
function answerChangeHandler (mutationRecords) { 
 
    var answersChanged = false; 
 

 
    mutationRecords.forEach (muttn => { 
 
     if (muttn.type === "attributes") 
 
      answersChanged = true; 
 
     else if (muttn.type === "childList" && muttn.addedNodes && muttn.addedNodes.length) { 
 
      for (let nwNode of muttn.addedNodes) { 
 
       if (nwNode.attributes && nwNode.attributes["data-id"]) { 
 
        answersChanged = true; 
 
        break; 
 
       } 
 
      } 
 
     } 
 
    }); 
 
    if (answersChanged) highliteMaxAnswer(); 
 
} 
 

 
/*--------------------------------------------------------------------- 
 
All code, below, is just to simulate the changing page. 
 
Do not include it in your script. 
 
*/ 
 
$("button").click (function() { 
 
    this.qCnt = this.qCnt || 1; 
 
    this.qCnt++; 
 
    $("#question-text").text (`What is your favorite color ${this.qCnt}?`); 
 

 
    $(".answer").each (function() { 
 
     var newDataId = "58b9890062279282090d" + getRandomHexWord(); 
 
     //-- Use attr() versus data() to simulate what website does. 
 
     $(this).attr ("data-id", newDataId); 
 
    }); 
 
}); 
 
function getRandomHexWord() { 
 
    return ('0000' + parseInt (65536 * Math.random()).toString (16)).slice (-4); 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="question-text" class="question">What is your favorite color?</div> 
 
<ul class="answers" id="answers"> 
 
    <li data-id="58b9890062279282090ddc61" class="answer">Purple</li> 
 
    <li data-id="58b9890062279282090ddc85" class="answer">Blue</li> 
 
    <li data-id="58b9890062279282090ddc64" class="answer">Yellow</li> 
 
    <li data-id="58b9890062279282090ddc66" class="answer">Red</li> 
 
</ul> 
 
<button>Simulate New Question</button>

+0

ありがとう、私を救った@Brock Adams –

+0

あなたは大歓迎です;喜んで助けてください。 –

0

まず、あなたは、再びあなたは、この動作が発生しますが、何度も関数を呼び出すために何かをする必要があります。

次に、コード内のどこかでカウンタをゼロに戻してください。

i++; 
if (i < howManyTimes) { 
    setTimeout(f, x); 
} 

setTimeoutは、カウンタが制限変数よりも小さい場合にのみ呼び出されます。カウンタをリセットすると、f()が呼び出されたときにsetTimeoutを再度呼び出すことができます。

関連する問題