LINUX.ORG.RU

поясните про XPatch

 , ,


0

1

В дебрях html есть некий элемент:

<body>
   ...
   <table>
       <tbody id="parent-1" class="parent-node">
          <tr id="child-1" class="child-node">
             <td class="title-text">
                Тюльпан
             </td>
          </tr>
       </tbody>
       /* другие аналогичные древа элементов, число и содержимое которых может быть разным */
   </table>
   ...
<body>
Который содержит текст «Тюльпан», предположим пользователю не интересно читать про тюльпаны и вообще у него на цветы аллергия, он набирает (а может даже выбирает) ключевое слово в специальном поле, а дальше вступает в работу JS код, который скроет родительский элемент у которого в детях есть элемент title-text с ключевым словом или словами.
function hideByTitle() {
   var __t         = this;
   this.input      = document.CreateElement('input')
   this.input.type = 'text'
   this.input.id   = 'hide-by-title-text'
   this.input.placeholder = 'Чемодан, Чебуреки, Чебоксары'
   this.input.addEventListener('focusout', function(e) {
      var keywords = __t.input.value.split(', ');
      /*
          ...
      */
   }, false)
}

Можно собирать все элементы .title-text, и проверять их содержимое через `.indexOf >= 0` или регулярными выражениями, потом возвращиться на два родителя выше и добалять `.style['display'] = 'none'` или просто какой нибудь скрывающий класс. Но это же харам какой то будет - элементов может быть очень много, ключевых слов тоже, и ведь все это надо запускать только после того как страница будет полностью загружена.

Здорово было бы если бы CSS позволял делать что нибудь подобное

td.title-text[text*="Тюльпан"]::parent()::parent() { display:none!important; }
можно тогда собирать его динамически добавлять на страницу сразу и не парится правильно ли введены значения или не правильно, есть элемент на странице или появиться потом и сколько их будет вообще, но CSS так делать не умеет.

Почитал немного про XPatch и ... ничего не понял правильно ли я понимаю как он работает? Позволит ли реализовать то что мне нужно?

function getElementByXpath(path, value) {
	var TYPE;
	switch (value) {
		case 9: TYPE = 'FIRST_ORDERED_NODE_TYPE';      break;
		case 8: TYPE = 'ANY_UNORDERED_NODE_TYPE';      break;
		case 7: TYPE = 'ORDERED_NODE_SNAPSHOT_TYPE';   break;
		case 6: TYPE = 'UNORDERED_NODE_SNAPSHOT_TYPE'; break;
		case 5: TYPE = 'ORDERED_NODE_ITERATOR_TYPE';   break;
		case 4: TYPE = 'UNORDERED_NODE_ITERATOR_TYPE'; break;
		case 3: TYPE = 'BOOLEAN_TYPE';  	       break;
		case 2: TYPE = 'STRING_TYPE';   	       break;
		case 1: TYPE = 'NUMBER_TYPE';   	       break;
		default:TYPE = 'ANY_TYPE';
	}
	return document.evaluate(path, document.body, null, XPathResult[TYPE], null);
}
console.log(getElementByXpath('//td[@class="title-text"][text()="Тюльпан"]', 8))

вот оно возвращает какой то объект с одной нодой (с самой первой которую нашел)

XPathResult { resultType: 8, singleNodeValue: <td.title-text>, invalidIteratorState: false }
как это использовать я вообще не понимаю, я думал он мне позволит задавать какие нибудь правила для конкретных (в том числе и по их содержимому) элементов дерева xml/html
//td[@class="title-text"][text()="Тюльпан"]::parent::parent:css(display:none)
а он получается просто захватывает элементы что ли?
Просто я много раз натыкался на сравнение XPatch и CSS, не просто же так в самом деле - значит при помощи них делают примерно одно и то же (как мне подумалось)

Сами мы в XPatch ни в зуб ногой, подайте советов мудрых люди добрые, кто сколько может (в интернетах примеры очень пресные и описывают в основном брождение по элементам xml, а что и как при помощи него делают я так и не понял)

★★★

Последнее исправление: uin (всего исправлений: 1)

Блин, я не туда написал же, надо было в Web-dev.
Можно перенести как нибудь?

uin ★★★
() автор топика
Ответ на: комментарий от uin

Да можно тему и не переносить — хпач есть много где, и если что-либо его реализует, то работает нативно одинаково.

Ну да — он просто возвращает тебе коллекцию узлов DOM'а по твоим условия, а дальше ты уже делаешь с ними что тебе нужно.

deep-purple ★★★★★
()

к вышесказанному можно альтернативно навелосипедить xslt стиль и натравливать его тем или иным способом на страницу.

MKuznetsov ★★★★★
()

<html>
<head>
<meta charset="windows-1251" />

</head>
<body>


<table>
       <tbody id="parent-1" class="parent-node">
          <tr id="child-1" class="child-node">
             <td class="title-text">
                Тюльпан
             </td>
          </tr>
      <tr id="child-2" class="child-node">
                   <td class="title-text">
                роза 
                   </td>
                </tr>
      
             </tbody>
   </table>
<input id="i">
<button id="b"> delete </button>

<script>

b.onclick=function(){
  var re=new RegExp(i.value, "i")
  ;[].forEach.call(document.querySelectorAll("table tr"), function(el){
    if(re.test(el.innerHTML)) el.style.display="none" 
  })
}

</script>

</body>
</html>
nondeterminism
()
Ответ на: комментарий от deep-purple

Хм, ну ладно, все равно поди быстрее чем яваскриптом элементы собирать и проверять, к тому же мне может в будущем потребуется заменять какие нибудь слова или символы.
А как коллекцию то получить? он мне только один элемент выдает

singleNodeValue: <td.title-text>

И можно как нибудь так написать, что бы он как бы сразу родителя мне выдал?

в доках написано

.. или :parent
А примеров использования нигде не показывают.
//../../td[@class="title-text"][text()="Тюльпан"]
как правильно?

MKuznetsov Интересно тоже, благодарю.

uin ★★★
() автор топика
Ответ на: комментарий от nondeterminism

Ну что сказать, логично, вот только я пытаюсь как раз избежать такой реализации.

uin ★★★
() автор топика
Ответ на: комментарий от nondeterminism

Ну хочу css-like RealTime понимаешь, сверхбыстрый сверхпростой, с регекспами возиться не хочу.

uin ★★★
() автор топика
Ответ на: комментарий от nondeterminism

Ну, селекторы XPatch почти так же быстры как CSS, хотя realtime -a как я понял уже не получится, да, но все равно это намного быстрей чем - собирать все элементы со страницы, по внутренностям каждого проходить регекспом, а потом что то добавлять, это при том что ключевых слов пользователь может добавить сколько захочет, а элементов может оказаться около сотни или больше, и эту работу надо будет проделывать при каждом обновлении страницы, а еще новые элементы должны появляться динамически. Этот код же мигом жирнющими подпорками облагородится, пожалей меня, не имел цели тебя как то обидеть если что.

uin ★★★
() автор топика
Ответ на: комментарий от uin

и эту работу надо будет проделывать при каждом обновлении страницы

Не при обновлении, а по клику. Не разу не сталкивался, чтобы подобный банальный перебор элементов вызывал сколько-нибудь ощутимые тормоза. foreach можно заменить на for, будет еще быстрей. Но дело твое, я спорить не собирался, просто высказал мнение. То что ты пытаешься сделать похоже на преждевременную оптимизацию. Вообще, по моим наблюдениям, больше всего тормозов идет от частых перерисовок страницы, сам JS нынче очень быстр. Чтобы от него что-то где то начало тормозить это надо очень постараться.

nondeterminism
()

ANY_UNORDERED_NODE_TYPE и должен возвращать единственный элемент. Тебе нужен или SNAPSHOT, или ITERATOR.

anonymous
()
Ответ на: комментарий от nondeterminism

Не при обновлении, а по клику.

Ага, лошадь - не корова, пользователь - не человек, но все же я пока еще не настолько к ним безжалостен и буду скидывать значение еще и в localStorage и при первичной инициализации вытаскивать и применять.

Вообще, по моим наблюдениям, больше всего тормозов идет от частых перерисовок страницы, сам JS нынче очень быстр

На firefox к сожалению не особо быстр, ну и помимо этого кода работает много еще другого

foreach кстати ниразу то и не медленней циклов.

uin ★★★
() автор топика
Ответ на: комментарий от uin

foreach кстати ниразу то и не медленней циклов.


test=function(f, repeat, name){
 console.time(name)
 while(repeat--)f()
 console.timeEnd(name)
}
arr=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
f1=function(){arr.forEach(function(x){})}
f2=function(){for(var i; i<arr.lenght; i++){}}

repeat=100000

test(f1, repeat, "foreach")
test(f2, repeat, "for")

// ::: foreach: 227ms
// ::: for: 4ms

nondeterminism
()
Ответ на: комментарий от nondeterminism

Присваивание пропустил.


test=function(f, repeat, name){
 console.time(name)
 while(repeat--)f()
 console.timeEnd(name)
}
arr=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
f1=function(){arr.forEach(function(x){})}
f2=function(){for(var i=0; i<arr.lenght; i++){}}

repeat=100000

test(f1, repeat, "foreach")
test(f2, repeat, "for")

// ::: foreach: 226ms
// ::: for: 3ms

//fixed

Но сути не меняет

nondeterminism
()
Ответ на: комментарий от nondeterminism

foreach: 3.24мс
for: 4.62мс
> Firefox 37.0.2

uin ★★★
() автор топика
Ответ на: комментарий от anonymous

Не, ну вообще судя по jsperf

for(i = 0; i < obj/arr.lenght; i++)
самый быстрый на V8 быстрее и foreach и всех остальных, даже на первый взгляд абсолютно аналогичного
for(i = 0; arr[i]; i++)
, причем существенно и хрен знает почему, а на FF он наоборот почему то самый медленный, судя по тому же jsperf

uin ★★★
() автор топика
Последнее исправление: uin (всего исправлений: 1)
Ответ на: комментарий от anonymous

Для быдла это полный абзац, конечно:)

Ты не понял. Тебе как бы намекнули, что программист на JS обязан быть программистом по-определению, иначе он сможет родить только обезьяний код, вроде того, что родил ТС. Для жаба-мартышек это не обязательно. Улавливаешь разницу?

Представь себе мартышку, перед которой висит 5 разноцветных веревок, а сзади устройство, которое бьет ей по башке каждый раз, когда она дергает за красную и желтую. Как ты думаешь, сколько мартышке надо времени, чтобы научится? Теперь найди пару отличий между ней и тобой. Первое я тебе подскажу, так и быть, у тебя веревок больше, и это, кстати, делает тебе честь, в сравнении с ней.

aedeph_ ★★
()
Последнее исправление: aedeph_ (всего исправлений: 1)
Ответ на: комментарий от uin

Нет, это цитаты великого программиста anonimous'а ( nondeterminism - это его свежая незабаненная версия), несущего жалким лоровцам свет и знание. Сегодня он нас поучил инверсиям регулярных выражений, бенчмаркам невыполняющихся циклов и философией ООП с точки зрения декларативного форвардинга статичных недоразумений.

aedeph_ ★★
()
Последнее исправление: aedeph_ (всего исправлений: 1)
Ответ на: комментарий от anonymous

Вот спасибо!
HTML Collection правда не получается, да это впрочем и ожидаемо можно впринципе потом их все собрать да и все после добавления им классов

function hideBy(something) {
   var __t         = this;
   this.elems      = grabElems()
   this.input      = document.CreateElement('input')
   this.input.type = 'text'
   this.input.id   = 'hide-by-' + something
   this.input.placeholder = 'Чемодан, Чебуреки, Чебоксары'
   this.input.addEventListener('focusout', function(e) {
      var i, n, nodes, keywords = __t.input.value.split(', ');
      for (i = 0; i < keywords.length; i++) {
          nodes = getElementByXpath('//td[@class="+ something +"][text()="'+ keywords[i] +'"]/parent::*/parent::*', 7);
          for (n = 0; n < nodes.snapshotLength; n++) {
	      nodes.snapshotItem(n).classList.add('autohidden')
          }
      }
      
   }, false)
   function grabElems() {
      var docQsAll = document.querySelectorAll
      return {
          hidden: docQsAll('.'+ something +'.autohidden'),
          showin: docQsAll('.'+ something +'.showhidden')
      }
   }
}

Там еще и функции какие то есть, можно наверно даже замену слов в тексте реализовать
Надо бы получше покурить этот Xpatch

Всем вообщем спасибо, вроде бы получил чего хотел.

uin ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.