RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1270263
Accepted
Sevastopol'
Sevastopol'
Asked:2022-04-15 00:57:54 +0000 UTC2022-04-15 00:57:54 +0000 UTC 2022-04-15 00:57:54 +0000 UTC

如果选择了两个元素,则显示隐藏元素

  • 772

我有一张带点(标记)的地图:

.map {position: relative; width: 800px; height: 506px;}
.dot {display: block; position: absolute; width: 30px; height: 30px; background-color: gold; border-radius: 30px; cursor: pointer; text-align: center; line-height: 30px;}
.dot:hover::before {content: ""; position: absolute; top: -10px; left: -10px; width: 50px; height: 50px; border-radius: 50px; background-color: gold; animation: animate 1.5s infinite normal ease-out;
}
@keyframes animate {from {transform: scale(0); opacity: .5}to {transform: scale(2); opacity: 0;}}

.aa {top: 440px; left: 260px;}
.bb {top: 320px; left: 380px;}
.cc {top: 260px; left: 240px;}

.win {display: none; position: absolute; top: 150px; left: 200px; width: 200px; height: 50px; background: pink; border: 1px solid black; padding: 5px;}

.close {position: absolute; top: -1px; right: -1px; border: 1px solid black; padding: 5px 10px; cursor: pointer;}
<div class="map">
  <img src="https://isstatic.askoverflow.dev/0lfnZ.jpg">
  <span class="dot aa">A</span>
  <span class="dot bb">B</span>
  <span class="dot cc">C</span>
</div>

<div class="win ab">Окно AB<span class="close">X</span></div>
<div class="win ac">Окно AC<span class="close">X</span></div>

<div class="win ba">Окно BA<span class="close">X</span></div>
<div class="win bc">Окно BC<span class="close">X</span></div>

<div class="win ca">Окно CA<span class="close">X</span></div>
<div class="win cb">Окно CB<span class="close">X</span></div>

问题:选择两个点时如何显示隐藏元素?更详细地说,场景如下:

  1. 当您单击一个点(例如,点A)时,它被选中。当您再次单击同一点时,我们会删除选择。⇒ 结果什么也没发生。

1.1。我们可以选择一个点并取消选择它,例如,使用javascript, 通过在单击附加类的元素时添加/删除:

let items;
let item;
window.addEventListener('load', () => {
  dots = document.getElementsByClassName('dot');
  for(let dot of dots) {
    dot.addEventListener('click', () => {
      //for(let it of dots) it.classList.remove('active');
      dot.classList.toggle('active')
    });
  }
});
.map {position: relative; width: 800px; height: 506px;}
.dot {display: block; position: absolute; width: 30px; height: 30px; background-color: gold; border-radius: 30px; cursor: pointer; text-align: center; line-height: 30px;}
.dot:hover::before {content: ""; position: absolute; top: -10px; left: -10px; width: 50px; height: 50px; border-radius: 50px; background-color: gold; animation: animate 1.5s infinite normal ease-out;
}
@keyframes animate {from {transform: scale(0); opacity: .5}to {transform: scale(2); opacity: 0;}}

.aa {top: 440px; left: 260px;}
.bb {top: 320px; left: 380px;}
.cc {top: 260px; left: 240px;}

.active {background-color: red;}
<div class="map">
  <img src="https://isstatic.askoverflow.dev/0lfnZ.jpg">
  <span class="dot aa">A</span>
  <span class="dot bb">B</span>
  <span class="dot cc">C</span>
</div>

  1. 当您单击一个点(例如,点A)时,它被选中。我们点击另一个点(例如点B),它也被选中 ⇒ 结果显示了一个隐藏元素。

2.1。选择点时:
A和B- 具有类的元素.ab
A和- 具有类C的元素和 - 具有类的元素.ac
B和- 具有类的元素和- 具有类的元素并且-显示具有类的元素A.ba
BC.bc
CA.ca
CB.cb

  1. 当您单击<span class="close">X</span>每个隐藏元素中的十字 ( ) ⇒ 元素被隐藏,并且从选定的点中删除高光。
javascript
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    OPTIMUS PRIME
    2022-04-15T05:53:57Z2022-04-15T05:53:57Z

    问题立即出现,“如何组织元素之间的联系”。您的关键粘合剂是类名class="dot aa"。例如,您可以aa通过某个[...elem.classList].filter(e => e.length == 2)[0]将过滤并仅将名称为两个字母的类保留在数组中的某个类,取列表的第 [0] 个元素。但是这种对类名的操作并不是很可靠。您可以放心地忘记它们(例如,添加其他类别的 2 个字母)。

    因此,我将所有必要的名称放入单独的data-属性中,但编写代码的方式是,如果需要,可以切换到具有类名的逻辑。

    它保留在某个数组中以收集被点击的按钮(意味着知道点击的顺序)。每次添加按钮后,检查数组的长度 == 2 ?打开一扇窗户。

    根据任务的心情,可以以非常不同的方式组织代码。
    变化:

    * 以防万一,即使在窗口打开时,也可以通过单击按钮的任意组合来确保工作。一次只能打开一个窗口。

    const _o = {
      all: function (selector, root) {
        return (root || document).querySelectorAll(selector);
      },
    };
    
    /***/
    const KEY = {
      // Вынес использованные data-значения в отдельный объект.
      // Весь код работает на основе строк, выданных отсюда как "ключевые" для
      // элементов: кнопок и окон. При желании можно поменять их на название класса и пр.
    
      of_win: function(node) {
        return node.dataset.key;
      },
    
      for_win: function(dot1, dot2) {
        return dot1.dataset.key + '_' + dot2.dataset.key;
      },
    };
    
    const WIN = new class { /* Всплывающие окна */
    
      constructor() {
        this.map = this.__init__node_map();
        this.now_open = null;
    
        this.__init__listeners();
        // __init__ не имеет специального значения. Но быстрее бросается в глаза.
      }
    
      __init__node_map() {
        let map = {/*
          'ab': div.win.ab (node),
          'ac': div.win.ac (node),
          ...
        */};
    
        for (let node of _o.all('.win')) map[KEY.of_win(node)] = node;
    
        return map;
      }
    
      __init__listeners() {
        let SELF = this;
    
        /***/
        for (let btn of _o.all('.win .close')) {
          btn.addEventListener('click', win_close);
        }
    
        function win_close() {
          SELF.close();
          DOT.unselect_all();
        }
      }
    
      any_open() {
        return !!this.now_open; // !! приводит к логическому типу.
        // now_open - или null или ссылка на открытый HTML элемент;
        // !!null → false   !!HTMLэлемент → true
      }
    
      open(selected_1 /* node */, selected_2 /* node */) {
        if (this.any_open()) this.close();
    
        let key = KEY.for_win(selected_1, selected_2);
        let win = this.map[key];
    
        win.classList.add('active');
    
        this.now_open = win;
      }
    
      close() {
        this.now_open.classList.remove('active');
        this.now_open = null;
      }
    };
    
    const DOT = new class { /* Кнопки на карте */
    
      constructor() {
        this.selected = [/* nodeList */];
    
        this.__init__listeners();
      }
    
      __init__listeners() {
        let SELF = this;
    
        /***/
        for (let dot of _o.all('.dot')) {
          dot.addEventListener('click', toggle_dot);
        }
    
        function toggle_dot() {
          SELF.toggle(this);
        }
      }
    
      /***/
      toggle(elem) {
        let is_active = elem.classList.contains('active');
        this[is_active ? 'unselect' : 'select'](elem);
      }
    
      select(elem) {
        let selected = this.selected;
    
        elem.classList.add('active');
        selected.push(elem);
    
        while (selected.length > 2) this.unselect(selected.shift());
    
        if (selected.length == 2) WIN.open(...selected);
        // (*) Справка: « ...spread, ...rest операторы »
      }
    
      unselect(elem) {
        let selected = this.selected;
    
        elem.classList.remove('active');
    
        let index = selected.indexOf(elem);
        if (index != -1) selected.splice(index, 1);
    
        if (selected.length < 2 && WIN.any_open()) WIN.close();
      }
    
      unselect_all() {
        let sel = this.selected;
    
        for (let i = sel.length - 1; i >= 0; i--) {
          this.unselect(sel[i]);
        }
      }
    };
    .map {position: relative; width: 800px; height: 506px;}
    .dot {display: block; position: absolute; width: 30px; height: 30px; background-color: gold; border-radius: 30px; cursor: pointer; text-align: center; line-height: 30px;}
    .dot:hover::before {content: ""; position: absolute; top: -10px; left: -10px; width: 50px; height: 50px; border-radius: 50px; background-color: gold; animation: animate 1.5s infinite normal ease-out;
    }
    @keyframes animate {from {transform: scale(0); opacity: .5}to {transform: scale(2); opacity: 0;}}
    
    .aa {top: 440px; left: 260px;}
    .bb {top: 320px; left: 380px;}
    .cc {top: 260px; left: 240px;}
    
    /* Добавлены стили: */
    .dot {
        user-select: none;
    }
    
    .dot.active {background-color: red;}
    
    .win {
      display: none;
      position: fixed;
      top: 0;
      left: 0;
    
      text-align: center;
      background: #fffa;
      width: 100%;
      height: 20vh;
    }
    
    .win.active {
      display: block;
    }
    
    .close {
      color: red;
      margin: 2em;
    }
    <div class="map">
      <img src="https://isstatic.askoverflow.dev/0lfnZ.jpg">
      <span class="dot aa" data-key="a">A</span>
      <span class="dot bb" data-key="b">B</span>
      <span class="dot cc" data-key="c">C</span>
    </div>
    
    <div class="win ab" data-key="a_b">Окно AB<span class="close">X</span></div>
    <div class="win ac" data-key="a_c">Окно AC<span class="close">X</span></div>
    
    <div class="win ba" data-key="b_a">Окно BA<span class="close">X</span></div>
    <div class="win bc" data-key="b_c">Окно BC<span class="close">X</span></div>
    
    <div class="win ca" data-key="c_a">Окно CA<span class="close">X</span></div>
    <div class="win cb" data-key="c_b">Окно CB<span class="close">X</span></div>

    要切换到带有类名的选项,您可以替换 KEY 对象中的函数:

    const KEY = {
    
      of_win: function(node) {
        // выдает название первого класса из двух букв.
        return [...node.classList].find(e => e.length == 2); // 'ab'
      },
    
      for_win: function(dot1, dot2) {    
        let key1 = [...dot1.classList].find(e => e.length == 2); // 'aa'
        let key2 = [...dot2.classList].find(e => e.length == 2); // 'bb'
        return key1[0] + key2[0]; // ('aa'[0] → 'a') + ('bb'[0] → 'b') → 'ab'
      },
    
    };
    

    const _o = {
      all: function (selector, root) {
        return (root || document).querySelectorAll(selector);
      },
    };
    
    /***/
    const KEY = {
    
      of_win: function(node) {
        // выдает название первого класса из двух букв.
        return [...node.classList].find(e => e.length == 2); // 'ab'
      },
    
      for_win: function(dot1, dot2) {    
        let key1 = [...dot1.classList].find(e => e.length == 2); // 'aa'
        let key2 = [...dot2.classList].find(e => e.length == 2); // 'bb'
        return key1[0] + key2[0]; // ('aa'[0] → 'a') + ('bb'[0] → 'b') → 'ab'
      },
    
    };
    
    const WIN = new class { /* Всплывающие окна */
    
      constructor() {
        this.map = this.__init__node_map();
        this.now_open = null;
    
        this.__init__listeners();
        // __init__ не имеет специального значения. Но быстрее бросается в глаза.
      }
    
      __init__node_map() {
        let map = {/*
          'ab': div.win.ab (node),
          'ac': div.win.ac (node),
          ...
        */};
    
        for (let node of _o.all('.win')) map[KEY.of_win(node)] = node;
    
        return map;
      }
    
      __init__listeners() {
        let SELF = this;
    
        /***/
        for (let btn of _o.all('.win .close')) {
          btn.addEventListener('click', win_close);
        }
    
        function win_close() {
          SELF.close();
          DOT.unselect_all();
        }
      }
    
      any_open() {
        return !!this.now_open; // !! приводит к логическому типу.
        // now_open - или null или ссылка на открытый HTML элемент;
        // !!null → false   !!HTMLэлемент → true
      }
    
      open(selected_1 /* node */, selected_2 /* node */) {
        if (this.any_open()) this.close();
    
        let key = KEY.for_win(selected_1, selected_2);
        let win = this.map[key];
    
        win.classList.add('active');
    
        this.now_open = win;
      }
    
      close() {
        this.now_open.classList.remove('active');
        this.now_open = null;
      }
    };
    
    const DOT = new class { /* Кнопки на карте */
    
      constructor() {
        this.selected = [/* nodeList */];
    
        this.__init__listeners();
      }
    
      __init__listeners() {
        let SELF = this;
    
        /***/
        for (let dot of _o.all('.dot')) {
          dot.addEventListener('click', toggle_dot);
        }
    
        function toggle_dot() {
          SELF.toggle(this);
        }
      }
    
      /***/
      toggle(elem) {
        let is_active = elem.classList.contains('active');
        this[is_active ? 'unselect' : 'select'](elem);
      }
    
      select(elem) {
        let selected = this.selected;
    
        elem.classList.add('active');
        selected.push(elem);
    
        while (selected.length > 2) this.unselect(selected.shift());
    
        if (selected.length == 2) WIN.open(...selected);
        // (*) Справка: « ...spread, ...rest операторы »
      }
    
      unselect(elem) {
        let selected = this.selected;
    
        elem.classList.remove('active');
    
        let index = selected.indexOf(elem);
        if (index != -1) selected.splice(index, 1);
    
        if (selected.length < 2 && WIN.any_open()) WIN.close();
      }
    
      unselect_all() {
        let sel = this.selected;
    
        for (let i = sel.length - 1; i >= 0; i--) {
          this.unselect(sel[i]);
        }
      }
    };
    .map {position: relative; width: 800px; height: 506px;}
    .dot {display: block; position: absolute; width: 30px; height: 30px; background-color: gold; border-radius: 30px; cursor: pointer; text-align: center; line-height: 30px;}
    .dot:hover::before {content: ""; position: absolute; top: -10px; left: -10px; width: 50px; height: 50px; border-radius: 50px; background-color: gold; animation: animate 1.5s infinite normal ease-out;
    }
    @keyframes animate {from {transform: scale(0); opacity: .5}to {transform: scale(2); opacity: 0;}}
    
    .aa {top: 440px; left: 260px;}
    .bb {top: 320px; left: 380px;}
    .cc {top: 260px; left: 240px;}
    
    /* Добавлены стили: */
    .dot {
        user-select: none;
    }
    
    .dot.active {background-color: red;}
    
    .win {
      display: none;
      position: fixed;
      top: 0;
      left: 0;
    
      text-align: center;
      background: #fffa;
      width: 100%;
      height: 20vh;
    }
    
    .win.active {
      display: block;
    }
    
    .close {
      color: red;
      margin: 2em;
    }
    <div class="map">
      <img src="https://isstatic.askoverflow.dev/0lfnZ.jpg">
      <span class="dot aa">A</span>
      <span class="dot bb">B</span>
      <span class="dot cc">C</span>
    </div>
    
    <div class="win ab">Окно AB<span class="close">X</span></div>
    <div class="win ac">Окно AC<span class="close">X</span></div>
    
    <div class="win ba">Окно BA<span class="close">X</span></div>
    <div class="win bc">Окно BC<span class="close">X</span></div>
    
    <div class="win ca">Окно CA<span class="close">X</span></div>
    <div class="win cb">Окно CB<span class="close">X</span></div>

    • 3

相关问题

  • 第二个 Instagram 按钮的 CSS 属性

  • 由于模糊,内容不可见

  • 弹出队列。消息显示不正确

  • 是否可以在 for 循环中插入提示?

  • 如何将 JSON 请求中的信息输出到数据表 Vuetify vue.js?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5