primers

Want to directly see the implementation can skip the lead

When completing a company project, one section of the interaction requires clicking the small arrow to appear in a drop-down list, and clicking somewhere else disappears the drop-down list, like this:

$(".box").on("click".function(e){$(this).find('.list-box').show() ... . $(document).one("click".function(){$(".list-box").hide()
    })
    e.stopPropagation()
});
$(".list-box").on("click".function(e){e.topPropagation () ··· ·});Copy the code

The above code basically does what you need, but sometimes you need to pull out the handler bound to the document first and change the binding to:

$(document).off('click', handler).one('click', handler)
Copy the code

This is to prevent binding the same event to document multiple times. While looking through the elder-UI source code for el-Button, I found that the click event function bound to the el-Button looks like this:

methods: {
  handleClick(evt) {
    this.$emit('click', evt); }}Copy the code

El-button has this click behavior:

el-button
javascript
css
css

.el-button:focus..el-button:hover {
    color: #409eff;
    border-color: #c6e2ff;
    background-color: #ecf5ff;
}
Copy the code

Obviously, the click style is not controlled by :hover, only: Focus. However, when I added “focus” to the div, I found that it did not work, and there was no extra attribute in the el-Button source code for template:

<template>
  <button
    class="el-button"
    @click="handleClick"
    .Omit >. omit</button>
</template>
Copy the code

El-button is a button label, which can use the function of “focus”. Therefore, I query the description of “focus” in MDN.

CSS pseudo-classes: Focus represents the element that gets focus (such as form input). It is triggered when the user clicks or touches the element or selects it using the keyboard’s TAB key.

I noticed that after searching for the element in focus, a global HTML attribute called tabIndex popped up. Let’s look at MDN’s description of it:

The tabIndex global attribute indicates whether its element can be focused and if/where it participates in sequential keyboard navigation (usually using the Tab key, hence the name).

Tabindex allows elements to be focused, and: Focus allows them to be focused, so CSS is available for clicking on a drop-down list. It’s not that clicking on the element actually produces this effect, it’s that when you click on the element, the element is focused, it looks like it was focused

implementation

Here is the HTML code to add “tabIndex” = -1 to the element we want to focus on. We use “tabIndex” = -1 as much as possible. See MDN for more details:

<div class="component-once-show">
    <span class="label">This is a text</span>
    <! -- Small arrow -->
    <span class="arrow-icon" tabindex="1">
    </span>
    <! -- Drop down list -->
    <div class="content-list" tabindex="1">
      <div class="list-item">1</div>
      <div class="list-item">2</div>
      <div class="list-item">3</div>
      <div class="list-item">4</div>
      <div class="list-item">5</div>
      <div class="list-item">6</div>
    </div>
</div>
Copy the code

Put the CSS code again (where the small arrows are simulated by :after content, and the special characters for content can be seen in HTML, JS, CSS special characters) :

/* The basic style of the entire box */
.component-once-show{
    / *... Omit extraneous styles */
    position: relative;
}
/* Basic style of small arrow */
.component-once-show .arrow-icon{
    margin-left: 12px;
    /* When focusing, there is a default outline that needs to be removed */
    outline: none; 
}
.component-once-show .arrow-icon:after{
    /* Small arrow pointing down */
    content: '\25BC';
    font-size: 12px;
    cursor: pointer;
}
/* Small arrow pointing up when focusing */
.component-once-show .arrow-icon:focus:after{
    content: '\25B2';
}
/* Small arrows display a drop-down list */ when focusing
.component-once-show .arrow-icon:focus + .content-list{
    visibility: visible;
}
/* The basic style of the drop-down arrow */
.component-once-show .content-list{
    visibility: hidden;
    position: absolute;
    outline: none;
    /* omit extraneous styles */
}
/* The drop-down list is a sibling element. If you do not want the drop-down list to disappear when you click it, you need to add :focus, and :hover, and do not connect */
.component-once-show .content-list:focus{
    visibility: visible;
}
.component-once-show .content-list:hover {
    visibility: visible;
}
    
Copy the code

Final effect:

css

.component-once-show{
    width: 200px;
    height: 30px;
    line-height: 30px;
    border: 1px solid #eeeeee;
    border-radius: 3px;
    text-align: center;
    box-shadow: 0 0 5px 2px #eeeeee;
    position: relative;
}
.component-once-show .arrow-icon{
    margin-left: 12px;
    outline: none;
}

.component-once-show .arrow-icon:after{
    content: '\25BC';
    font-size: 12px;
    cursor: pointer;
}

.component-once-show .arrow-icon:focus:after{
    content: '\25B2';
}

.component-once-show .arrow-icon:focus + .content-list{
    visibility: visible;
}

.component-once-show .content-list{
    visibility: hidden;
    position: absolute;
    width: 100%;
    border: 0px solid;
    border-radius: 3px;
    box-shadow: 0 0 5px 2px #eeeeee;
    margin-top: 5px;
    outline: none;
}

.component-once-show .content-list:focus{
    visibility: visible;
}

.component-once-show .content-list:hover {
    visibility: visible;
}

.component-once-show .content-list .list-item{
    background: #ffffff;
    height: 30px;
    line-height: 30px;
    transition: background .2s ease;
}

.component-once-show .content-list .list-item:hover{
    background: #eeeeee;
}
Copy the code

Practical significance

The practical significance of this effect is very small in my opinion, tabIndex is used more for web accessibility. The only good thing about this effect is that you can separate the style from the behavior, so that when you click, you don’t have to think about the style and you focus more on the behavior. This effect can of course be controlled through addClass in javascript, which is relatively inexpensive and more flexible. Clicking somewhere else to make the drop-down list disappear can be done with the TabIndex + onBlur event, without the risk of tying the event to the document. How to hide a menu with jQuery? Rezero’s answer.

Afterword.

If there is anything improper in the article, please correct it.