討論 » 開發

Help: how to make it work when occur a dynamically change in the page ????

§
發表於:2019-01-23
編輯:2019-01-24

Help: how to make it work when occur a dynamically change in the page ????

It's a little script i test for: http://portail.free.fr/programme-tv/grille-tv/

It help me to highlight these elements (film /serie etc) with CSS

But if i navigate in the Tv programe (without refresh the page) it don't take the change in it.

What i need to add in the script?

PS: Why in the code displaying here (in Geasyfork Forum) show additional visible br and p in it ? Usually i used the balise "code" but .... How put code with markdown inside disscussion ?

// ==UserScript==
// @name          TEST - FREE Programme TV v.1
// @namespace https://greasyfork.org/fr/users/7434-janvier56
// @homepage https://greasyfork.org/fr/users/7434-janvier56

// @description   Just script - Companion for FREE Programme TV 

//
// @version       v.01.00
//
// @include       http://portail.free.fr/programme-tv/grille-tv/*
//
// @grant       none
//
// @run-at      document-start
//
//
// ==/UserScript==


/*
======== pseudo elements  - innerHTML - Using attr(), with pseudo-elements and JavaScript
== https://tiffanybbrown.com/2014/11/using-attr-with-pseudo-elements-and-javascript/
 we'll set a data-txt attribute using DOM scripting.
 Here we've just copied the innerHTML of our paragraph element
 to the data-txt attribute when the DOMContentLoaded event fires.
window.addEventListener('DOMContentLoaded', function(){
    var p = document.querySelector('p');
    p.dataset.txt = p.innerHTML;
}
window.addEventListener('DOMContentLoaded', function(){
    var p = document.querySelector('p');
    p.dataset.txt = p.innerHTML;
    p.classList.add('triptych');
},false);

*/

/* ONLY ONE
window.addEventListener('DOMContentLoaded', function(){
    var p = document.querySelector('.titre  + br + .type');
    p.dataset.txt = p.innerHTML;
    p.classList.add('DEL');
},false);
*/

// MULTI SELECT : https://demos.tiffanybbrown.com/2014/attr/index.html
window.addEventListener('DOMContentLoaded', function(){
        var p = document.querySelectorAll('.titre  + br + .type');
        Array.prototype.map.call(p, function(o){
            o.dataset.txt = o.innerHTML;
            o.classList.add('DEL');
        });
    },false);

// IMAGES for touches programe
window.addEventListener('DOMContentLoaded', function(){
        var p = document.querySelectorAll('#listechaines img[src^="/_/img/tv/chaines/"]');
        Array.prototype.map.call(p, function(o){
            o.dataset.txt = o.title;
            o.classList.add('DEL2');
        });
    },false);
woxxom管理員
§
發表於:2019-01-24

Since the page is not reloaded you need to use MutationObserver or recheck the page periodically in setTimeout.

// ==UserScript==
// @name          TEST - FREE Programme TV v.1
// @namespace https://greasyfork.org/fr/users/7434-janvier56
// @homepage https://greasyfork.org/fr/users/7434-janvier56
// @description   Just script - Companion for FREE Programme TV
//
// @version       v.01.00
//
// @include       http://portail.free.fr/programme-tv/grille-tv/*
//
// @run-at      document-start
// ==/UserScript==

(() => {
  onIdOnce('listechaines', () => {
    onSelector('.titre  + br + .type', els => els.forEach(el => {
      el.dataset.txt = el.innerHTML;
      el.classList.add('DEL');
    }));
    onSelector('#listechaines img[src^="/_/img/tv/chaines/"]', els => els.forEach(el => {
      el.dataset.txt = el.title;
      el.classList.add('DEL2');
    }));
  });

  ///////////////////////////////////////////////////////////////
  // superfast one-time detection by id
  function onIdOnce(id, callback) {
    new MutationObserver((_, ob) => {
      const el = document.getElementById(id);
      if (el) {
        ob.disconnect();
        callback(el);
      }
    }).observe(document, {subtree: true, childList: true});
  }

  ///////////////////////////////////////////////////////////////
  // slow detection by selector
  function onSelector(selector, callback) {
    if (onSelector.selectors) {
      const all = onSelector.selectors;
      onSelector.selectors = [[selector, callback]];
      onSelector.onMutation([{addedNodes: [document.documentElement]}]);
      onSelector.selectors = all;
      all.push([selector, callback]);
      return;
    }
    onSelector.selectors = [];
    onSelector.onMutation = mutations => {
      var selectors = onSelector.selectors;
      var found = selectors.map(() => []);
      for (var i = 0, m; (m = mutations[i++]);) {
        for (var j = 0, node, added = m.addedNodes; (node = added[j++]);) {
          if (node instanceof Element) {
            for (var k = 0, s; (s = selectors[k]); k++) {
              var sel = s[0];
              if (node.matches(sel)) {
                found[k].push(node);
              }
              if (node.firstElementChild && node.querySelector(sel)) {
                found[k].push(...node.querySelectorAll(sel));
              }
            }
          }
        }
      }
      found.forEach((els, i) => els.length && selectors[i][1](els));
    };
    onSelector.observer = new MutationObserver(onSelector.onMutation);
    onSelector.observer.observe(document, {
      subtree: true,
      childList: true,
    });
  }
})();
§
發表於:2019-01-24

Ha, i am without voice: Thanks wOxxOm ! ;-) I test that and i try to understand how it work...

PS: Markdown is great but more difficult for me. And yes, i need an extra coffee : I have not see the format icon for code here.....

1 - Test with code icon from here (seems not provide syntax highlighting): // superfast one-time detection by id function onIdOnce(id, callback) { new MutationObserver((_, ob) => { const el = document.getElementById(id); if (el) { ob.disconnect(); callback(el); } }).observe(document, {subtree: true, childList: true}); }

2 - Test from your link: Blocks of code are either fenced by lines with three back-ticks ```, or are indented with four spaces. I recommend only using the fenced code blocks -- they're easier and only they support syntax highlighting.

var s = "JavaScript syntax highlighting";
alert(s);
// slow detection by selector
  function onSelector(selector, callback) {
    if (onSelector.selectors) {
      const all = onSelector.selectors;
      onSelector.selectors = [[selector, callback]];
      onSelector.onMutation([{addedNodes: [document.documentElement]}]);
      onSelector.selectors = all;
      all.push([selector, callback]);
      return;
    }
    onSelector.selectors = [];
    onSelector.onMutation = mutations => {
      var selectors = onSelector.selectors;
      var found = selectors.map(() => []);
      for (var i = 0, m; (m = mutations[i++]);) {
        for (var j = 0, node, added = m.addedNodes; (node = added[j++]);) {
          if (node instanceof Element) {
            for (var k = 0, s; (s = selectors[k]); k++) {
              var sel = s[0];
              if (node.matches(sel)) {
                found[k].push(node);
              }
              if (node.firstElementChild && node.querySelector(sel)) {
                found[k].push(...node.querySelectorAll(sel));
              }
            }
          }
        }
      }
      found.forEach((els, i) => els.length && selectors[i][1](els));
    };
    onSelector.observer = new MutationObserver(onSelector.onMutation);
    onSelector.observer.observe(document, {
      subtree: true,
      childList: true,
    });
  }
})();
§
發表於:2019-01-24
編輯:2019-01-24

I tested very quickly your script example: It seems not working (it didn't add the .DEL).

I use it to make an userstyle like:

.type.DEL[data-txt="Documentaire"] {
    background: darkseagreen none repeat scroll 0 0;
    color: #2d2d2d;
    font-family: "CarroisGothic";
    font-size: 12px;
}
.type.DEL {
    color: #2d2d2d;
    display: inline-block;
    font-family: "CarroisGothic";
    font-size: 12px;
    padding: 5px;
    text-align: center;
    width: 180px;
}

Maybe it is possible to transform directly the innerHTML to a class attribute: Documentaire became .Documentaire ????

發表回覆

登入以回復