Защо моята функция GreaseMonkey неочаквано се извиква многократно?

Нещо ми липсва, не съм сигурен защо функцията „addIcon()“ се извиква няколко пъти.

дадени:

<div class="ticketpostcontainer">Some text</div>
<div class="ticketpostcontainer">Some text</div>
<div class="ticketpostcontainer">Some text</div>

Използвайки помощната функция waitForKeyElements, резултатът е, че всеки елемент div получава моята „икона за свиване“ три пъти:

// ==UserScript==
// @name        Collapse Kayako Response
// @grant               Sandbox
// @namespace   http://my.chiromatrixbase.com/fisher.chiromatrix.com/collaps_div.js
// @include     http://imatrixsupport.com/*
// @require     http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js
// ==/UserScript==
/*jslint plusplus: true, undef: true, sloppy: true, vars: true, white: true, indent: 2, maxerr: 30 */

//Enable or disable GreaseMonkey function, GM_log
var GM_Debug = 1;

if (!GM_Debug) {
  var GM_log = function () {};
}
//If FireBig is active, send GM log events to FB.
if (unsafeWindow.console && GM_Debug) {
  var GM_log = unsafeWindow.console.log;
}

GM_log("Running collapse kayako response script");

//Don't run on frames or iframes.
if (window.top !== window.self) {
      return;
}

waitForKeyElements(".ticketpostcontainer", addIcon);

function addIcon() {
  var i, toCollapse = document.getElementsByClassName('ticketpostcontainer'), j = toCollapse.length;

  GM_log("Number of elements to collapse: " + toCollapse.length);

  for (i = 0; i < j; i++) {
    var curElement = toCollapse[i];

    var p = document.createElement('p');
    var a = document.createElement('a');
    var span = document.createElement('span');

    styleLink(a);
    styleParagraph(p);
    styleSpan(span);
    p.appendChild(a);
    p.appendChild(span);
    a.appendChild(document.createTextNode('-'));
    span.appendChild(document.createTextNode(' Some text'));

    a.addEventListener("click", toggle, false);

    curElement.parentNode.insertBefore(p, curElement);
  }

  function toggle(e) {
    if (this.firstChild.nodeValue === '-') {
      this.parentNode.nextSibling.style.display = 'none';
      this.firstChild.nodeValue = '+';
      this.nextSibling.style.display = 'inline';

    } else {
      this.parentNode.nextSibling.style.display = 'block';
      this.firstChild.nodeValue = '-';
      this.nextSibling.style.display = 'none';
    }
    e.preventDefault();
  }

  function styleLink(a) {
    a.href = '#';
    a.style.fontWeight = 'bold';
    a.style.background = '#F6F1E7';
    a.style.border = '1px solid #cccccc';
    a.style.color = '#B24C58';
    a.style.textDecoration = 'none';
    a.style.width = '15px';
    a.style.height = '15px';
    a.style.textAlign = 'center';
    a.style.fontSize = '100%';
    a.style.margin = '0 5px 5px 8px';
    a.style.cssFloat = 'left';
    a.style.display = 'block';
    a.style.lineHeight = '13px';
  }

  function styleParagraph(p) {
    p.style.margin = '0 0 0 0';
    p.style.lineHeight = '16px';
    p.style.clear = 'both';
    p.style.height = '15px';
  }

  function styleSpan(span) {
    span.style.display = 'none';
  }
}

person Ryan Fisher    schedule 30.09.2012    source източник


Отговори (2)


addIcon свива всички елементи ticketpostcontainer, но waitForKeyElements ще го задейства и изпълни за всичките три елемента ticketpostcontainer. Опитайте нещо подобно, за да го стартирате веднъж за всеки:

function addIcon($el) {
    var curElement = $el.get(0); // get DOM element
    // proceed as above but without the for loop
}
person Owlvark    schedule 30.09.2012
comment
+1; По същество правилно, но би трябвало повече подробности. Покажете действителните модификации на кода. - person Brock Adams; 30.09.2012
comment
А, не разбирах как функционира помощната програма waitForKeyElements. Мислех, че просто се задейства, когато беше намерено първото копие на елемент ticketpostcontainer. - person Ryan Fisher; 30.09.2012

Това е модифицираната част от кода, която вече функционира правилно и връзка към пълния скрипт, ако някой го хареса .

waitForKeyElements(".ticketpostcontainer", addIcon);

function addIcon($el) {
  var curElement = $el.get(0);

  var p = document.createElement('p');
  var a = document.createElement('a');
  var span = document.createElement('span');
  var strong = document.createElement('srong');

    GM_log("Node: " + curElement.className); //Debug

    var node = curElement.getElementsByClassName('ticketpostbarname');
    var posterName = node[0].textContent;
    GM_log("Poster Name: " + node[0].textContent); //Debug

    node = curElement.getElementsByClassName('ticketbarcontents');
    var postDate = node[0].textContent;
    GM_log("Post Date: " + node[0].textContent); //Debug

  styleLink(a);
  styleParagraph(p);
  styleSpan(span);
  styleStrong(strong);
  p.appendChild(a);
  p.appendChild(span);
  a.appendChild(document.createTextNode('-'));
  span.appendChild(strong);
  strong.appendChild(document.createTextNode(' ' + posterName));
  span.appendChild(document.createTextNode(" (" + postDate + ")"));

  a.addEventListener("click", toggle, false);

  curElement.parentNode.insertBefore(p, curElement);
person Ryan Fisher    schedule 30.09.2012