Xpath: get last element of branch - html

Is any solution how get last N-grandchildren if know his N-grandparent. Its like: I know start point of branch and I need take last element of this branch.
<div class="start-parent">
...
... // a lot of other elements
...
<div class="last-child end-of-branch"></div>
</div>

Assuming you html looks like this:
<div class="start-parent">
<div class="first-child of-branch"></div>
<div class="second-child of-branch">
<div class="a grand-child of-branch"></div>
<div class="last grand-child end-of-branch"></div>
</div>
<div class="last-child end-of-branch"></div>
</div>
This expression:
//div[#class="start-parent"]//*/*[last()]/#class
selects
last grand-child end-of-branch
while this one
//div[#class="start-parent"]/div[1]/following-sibling::div[last()]/#class
selects
last-child end-of-branch

Related

How to tab directly to child element and ignore parent

Currently I have a list like so:
<div class="list">
<div class="padding">
<div class="clickable-item">item 1</div>
</div>
<div class="padding">
<div class="clickable-item">item 2</div>
</div>
</div>
With the keyboard I would like to tab to the clickable-items one after another.
Currently it's tabbing through the 'padding' elements instead.
Is there any way I can tell the browser to ignore the padded parent and tab straight to the child?
Here's a few things to think about:
<div class="clickable-item" /> isn't indicating that it's a clickable item. See: Making a clickable <div> accessible through tab structure? on why using a div isn't always the best solution and using a button or a tag is better for accessibility.
Unlike what Anis R. said, if you want to keep the logical flow for tabbing based on the ordre of the page, you want to use tabindex="0" on the elements.
If you must use a div, think about using <div class"clickable-item" role="button" /> on your div in order to indicate that it is indeed something clickable.
You can set the tabindex attribute on the desired elements. The tab index number determines the order in which the elements are visited.
Edit: As FullOnFlatWhite and Graham Ritchie mentioned, it's generally better to use tab indices of zero (not positive), or use role="button" on your div.
<div class="list">
<div class="padding">
<div class="clickable-item" tabindex="0">item 1</div>
</div>
<div class="padding">
<div class="clickable-item" tabindex="0">item 2</div>
</div>
</div>

Outside elements with if condition, inside element always exist (Vue.js)

I have one question. Is it any simple way to make class 'a' elements with if condition, class 'b' element always exist.
<div v-if="aaa===1" class='a'>
<div class='b'></div>
</div>
or i have to write two times.
<div v-if="aaa===1" class='a'>
<div class='b'></div>
</div>
<div v-else class ='b'></div>
i think writing two is really redundant

Am I allowed to use element from a parent block, inside a children block?

I would like to know if, according to BEM methodology, I can have the following structure:
.block1
.block1__element1
.block2
.block1__element2 <-- ??
Am I allowed to use an element from a parent block, inside a children block?
Thanks.
UPDATE:
This is the actual DOM structure:
<div class="head">
<div class="head__user"></div>
<div class="head__nav">
<div class="menu">
// <-- ???
</div>
</div>
</div>
According to best practices of BEM methodology: am I allowed to move the element with head__user inside the menu block? Or all elements inside the menu block need to start with the menu__ prefix?
I hope this clears out the problem.
I been using BEM for sometime and from what I got it's not recommended nor intended to be used like that. You can nest different BEM elements to each other like menu-blockintohead-block, but menu-block items should not go outside its parent menu-block, like you should not put menu-block__item at the top of head-block. Does it makes sense? :)
To illustrate there are two ways to go. What should be noted here is that depending on the scale of your project and how you build things (component based?). If you don't have a large project and are not doing or reusing the menu else where you can do it both ways. Lets say your menu is huge amount of html/css I would do it like #1
This is not correct
<div class="head">
<div class="head__user"></div>
<div class="head__nav">
<div class="menu">
<div class="head__something"></div>
</div>
</div>
</div>
Recommended solution
Based on this part of the documentation. Now you can chop your own header design into blocks, does this below match?
<div class="head">
<div class="head__user"></div>
<div class="head__nav">
<div class="menu">
<div class="menu__something"><img src="" class="menu__image" /></div>
</div>
</div>
</div>
I think this variant is allowed:
<div class="head">
<div class="head__nav">
<div class="menu">
<div class="head__user"></div>
</div>
</div>
</div>
I haven't found the current part in the official BEM documentation, but I've found this part:
The block name defines the namespace, which guarantees that the elements are dependent on the block (block__elem).
A block can have a nested structure of elements in the DOM tree:
Example
<div class="block">
<div class="block__elem1">
<div class="block__elem2">
<div class="block__elem3"></div>
</div>
</div>
</div>
However, this block structure is always represented as a flat list of elements in the BEM methodology:
Example
.block {}
.block__elem1 {}
.block__elem2 {}
.block__elem3 {}
This allows you to change a block's DOM structure without making changes in the code for each separate element:
Example
<div class="block">
<div class="block__elem1">
<div class="block__elem2"></div>
</div>
<div class="block__elem3"></div>
</div>
The block's structure changes, but the rules for the elements and their names remain the same.
I understand it as there is only one rule about HTML structure for elements in BEM: an element has to be inside its block (it doesn't matter how deep).
One possible problem that I can imagine for this case is using some of BEM tree formats. But if you don't need it, I think there's no problem.
I would consider making the potential head__something into simply something, and then to provide multiple modifications of it. e.g. something--head and something--menu.
<div class="head">
<div class="head__user"></div>
<div class="head__nav">
<div class="menu">
<div class="something--menu" />
</div>
</div>
<div class="something--head" />
</div>
Also, refactoring further, I would consider getting rid of head__nav as it probably does not add any richer semantics than menu.
<div class="head">
<div class="head__user"></div>
<div class="menu">
<div class="something--menu" />
</div>
<div class="something--head">for those cases where you want <code>something</code> directly descending from <code>head</code></div>
</div>

Get child by it's parent's another child

My HTML looks like that:
<div class="parent">
<div class="url">
LINK
</div>
<div class="stats">
<div class="a">12</div>
<div class="b">14</div>
</div>
</div>
<div class="parent">
<div class="url">
LINK
</div>
<div class="stats">
<div class="a">133</div>
<div class="b">13</div>
</div>
</div>
<div class="parent">
<div class="url">
LINK
</div>
<div class="stats">
<div class="a">4</div>
<div class="b">46</div>
</div>
</div>
Is this possible to get parent's child which is found by another, the same parent child?
So, I want to get contents of class b of second parent. But I want to find bu it's href parameter.
Like that-
XPath finds parent, which has child url and a with href parameter http://url.com/view/364
XPath takes contents of class b in the same parent
If you don't understand, I basically need that XPath gets number 13 (contents of b), but find it using href parameter.
Is this possible? How this can be done?
An even cleaner approach is (line break only for readability)
//div[#class = 'parent' and div[#class = 'url']
/a/#href = 'http://url.com/view/364']/div[#class = 'stats']/div[#class = 'b']
It is better than the answer you found yourself (actually, it's a good thing you found an answer yourself!) because there are no unnecessary parent axis (..) steps in it.
It is better than
(//a[#href='http://url.com/view/364']/following::div[#class='b'])[1]
because following::div[#class = 'b'] selects a div element that follows the context item, even if it is in another div[#class = 'parent']. For instance, if the document looked like
<html>
<div class="parent">
<div class="url">
LINK
</div>
<div class="stats">
<div class="a">133</div>
</div>
</div>
<div class="parent">
<div class="url">
LINK
</div>
<div class="stats">
<div class="a">4</div>
<div class="b">46</div>
</div>
</div>
</html>
then the result would be
<div class="b">46</div>
Well, a cleaner approach would be to use the following axis and then select the first node with class='b'.
"(//a[#href='http://url.com/view/364']/following::div[#class='b'])[1]"
I found the answer.
It is easy to do that -
//*[#class="parent"]/div[#class="url"]/a[#href="http://url.com/view/364"]/../../div[#class="stats"]/div[#class="b"]

Proper nesting - namespace collisions

I need a little advice on nesting HTML elements. I have a general structure where X contains a New section (where I'll add form elements for creating an X) and a List section that displays whatever Xs already exist:
<div id="X">
<div id="New">
...
</div>
<div id="List">
...
</div>
</div>
now it turns out I need to have two on the page:
<div id="X">
...
</div>
<div id="Y">
...
</div>
so whilst I can differentiate the 2 News like this:
#X #New {} /* in CSS */
$('#Y #New') /* in jQuery */
I'm left with the queasy feeling that #New should be unique in the document... so one alternative might be:
<div id="X">
<div id="XNew">
...
</div>
<div id="XList">
...
</div>
</div>
but then the notion of using X for nesting (as a namespace) seems moot since I've flattened the names... or perhaps another:
<div id="X">
<div class="New">
...
</div>
<div class="List">
...
</div>
</div>
but here I'm using a class where I really mean to designate a single element. How do you all do this sort of thing?
IDs should always be unique. That's why they're called identifiers. Using a class is the correct solution in this case. Then you can easily reference the elements via #X .New and #x .List for example. This also makes it easier to apply common styles and behaviour to all List and New divs.