dmlogv
@dmlogv
Универсальный человек

VK: как повесить JS-обработчик на подгружаемые посты?

Делаю юзерскрипт (затем доработаю до расширения для Chrome) для ВКонтакте, втыкающий дополнительную кнопку в посты с плеером. Основная проблема — каким образом нересурсоемко навешивать кнопку на подгружаемые по мере достижения конца страницы посты.

Какие есть идеи:
1. Вызывать обработчик по document.body.onresize. Не прокатывает, уж почему — не знаю.
2. Брать Стену приступом по таймеру. Но как-то это... топорно?
3. Переполошить дуровские скрипты и найти, каким событием оканчивается подгрузка и подцепиться туда. Работаю над этим.

Объясните, почему я делаю всё неправильно?
  • Вопрос задан
  • 2841 просмотр
Решения вопроса 1
sergey-gornostaev
@sergey-gornostaev
Седой и строгий
MutationObserver - то, что тебе нужно. Делал userscript для одноклассничков, посмотри.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
mlnkv
@mlnkv
JavaScript Developer
https://developer.mozilla.org/en-US/docs/Web/Guide...
найти элемент в который вставляются посты и повесить событие
var wrapper = document.getElementById("feed_rows");
wrapper.addEventListener("DOMNodeInserted", function (ev) {
  /* вставляем кнопку */
});
Ответ написан
@artishok
кратко
Примерно так
spoiler
function getOffset(elem) {
    if (elem.getBoundingClientRect) {
        // "правильный" вариант
        return getO<sub></sub>ffsetRect(elem)
    } else {
        // пусть работает хоть как-то
        return getOffsetSum(elem)
    }
}

function getOffsetSum(elem) {
    var top=0, left=0
    while(elem) {
        top = top + parseInt(elem.offsetTop)
        left = left + parseInt(elem.offsetLeft)
        elem = elem.offsetParent
    }

    return {top: top, left: left}
    return top;
}

function getOffsetRect(elem) {
    // (1)
    var box = elem.getBoundingClientRect()

    // (2)
    var body = document.body
    var docElem = document.documentElement

    // (3)
    var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop
    var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft

    // (4)
    var clientTop = docElem.clientTop || body.clientTop || 0
    var clientLeft = docElem.clientLeft || body.clientLeft || 0

    // (5)
    var top  = box.top +  scrollTop - clientTop
    var left = box.left + scrollLeft - clientLeft

    //return { top: Math.round(top), left: Math.round(left) }
    return Math.round(top);
}

	
	


function fun() {

	your script

}


function ge(el) {
  return (typeof el == 'string' || typeof el == 'number') ? document.getElementById(el) : el;
}

function geByClass(searchClass, node, tag) {
  node = node || document;
  tag = tag || '*';
  var classElements = [];

  if (node.getElementsByClassName) {
    var nodes = node.getElementsByClassName(searchClass);
    if (tag != '*') {
      tag = tag.toUpperCase();
      for (var i = 0, l = nodes.length; i < l; ++i) {
        if (nodes[i].tagName.toUpperCase() == tag) {
          classElements.push(nodes[i]);
        }
      }
    } else {
      classElements = Array.prototype.slice.call(nodes);
    }
    return classElements;
  }
  var els = geByTag(tag, node);
  var pattern = new RegExp('(^|\\s)' + searchClass + '(\\s|$)');
  for (var i = 0, l = els.length; i < l; ++i) {
    if (pattern.test(els[i].className)) {
      classElements.push(els[i]);
    }
  }
  return classElements;
}

function geByTag(searchTag, node) {
  return (node || document).getElementsByTagName(searchTag);
}


window.onload = function(){	
	fun();	
}


function scrollToTop(speed) {
  return scrollToY(0, speed);
}

function scrollGetY(withFinal) {
  // withFinal - use last value from scrollToY, when available
  if ((withFinal || (browser.safari && withFinal === undefined)) && cur.scrollFinalY !== undefined) {
    return cur.scrollFinalY;
  }
  return window.pageYOffset || scrollNode.scrollTop || document.documentElement.scrollTop;
}


if (!window._ua) {
  var _ua = navigator.userAgent.toLowerCase();
}
if (!window.locDomain) {
  var locDomain = location.host.toString().match(/[a-zA-Z]+\.[a-zA-Z]+\.?$/)[0];
}
if (!window.StaticFiles) {
  var StaticFiles = {};
}

var browser = {
  version: (_ua.match( /.+(?:me|ox|on|rv|it|era|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
  opera: /opera/i.test(_ua),
  msie: (/msie/i.test(_ua) && !/opera/i.test(_ua)),
  msie6: (/msie 6/i.test(_ua) && !/opera/i.test(_ua)),
  msie7: (/msie 7/i.test(_ua) && !/opera/i.test(_ua)),
  msie8: (/msie 8/i.test(_ua) && !/opera/i.test(_ua)),
  msie9: (/msie 9/i.test(_ua) && !/opera/i.test(_ua)),
  mozilla: /firefox/i.test(_ua),
  chrome: /chrome/i.test(_ua),
  safari: (!(/chrome/i.test(_ua)) && /webkit|safari|khtml/i.test(_ua)),
  iphone: /iphone/i.test(_ua),
  ipod: /ipod/i.test(_ua),
  iphone4: /iphone.*OS 4/i.test(_ua),
  ipod4: /ipod.*OS 4/i.test(_ua),
  ipad: /ipad/i.test(_ua),
  android: /android/i.test(_ua),
  bada: /bada/i.test(_ua),
  mobile: /iphone|ipod|ipad|opera mini|opera mobi|iemobile|android/i.test(_ua),
  msie_mobile: /iemobile/i.test(_ua),
  safari_mobile: /iphone|ipod|ipad/i.test(_ua),
  opera_mobile: /opera mini|opera mobi/i.test(_ua),
  opera_mini: /opera mini/i.test(_ua),
  mac: /mac/i.test(_ua)
};

window.onscroll = function () {
	var el = ge('show_more_link');
	var ch = window.innerHeight || document.documentElement.clientHeight || bodyNode.clientHeight,
		st = scrollGetY(), top, ntop = 0, el, nel, bits, posts = [];

	if (st + ch + 1000 > el.offsetTop) {
	 
	}
	
	fun();
	
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы