Как вызвать поиск по странице через консоль?

При нажатии клавиш Ctrl+F в браузере выскакивает панель для поиска по странице. Возможно ли эту панель какой нибудь командой вызвать через консоль браузера?

P.S. Ок, по всей видимости вызвать панель поиска простой командой нельзя. Но может же быть тогда скрипт на JS, который при вводе в консоль браузера создаст и выведет свою подобную панель?


Ответы (1 шт):

Автор решения: DiD

Может быть, это не то, чего вы ожидали, но как бы полностраничный поиск.

const minCharsToSearch = 3;
        
        const $ = (...q) => q.reduce((r,s)=>!r?null:'object'==typeof s?s:r.querySelector(s),document),
              $$ = (...q) => q.reduce((r,s,i,q)=>!r?null:'object'==typeof s?s:r["querySelector"+(i==q.length-1?'All':'')](s),document),
              on = (o,e,c) => o.addEventListener(e,c,false),
              stop = e => ['preventDefault','stopPropagation'].map(f=>e[f]()),
              addCls = (o,c) => (o.classList.add(c),o),
              remCls = (o,c) => (o.classList.remove(c),o),
              newEl = t => document.createElement(t),
              append = (p,o) => (p.appendChild(o),o),
              pageTop = () => document.documentElement.scrollTop + document.body.scrollTop,
              // @todo document.documentElement.clientHeight или document.body.clientHeight
              pageBottom = () => pageTop() + document.documentElement.clientHeight;

        const form = $('form'),
              input = $(form,'input'),
              search = $(form,'.search'),
              clear = $(form,'.clear'),
              output = $(form,'.output'),
              next = $(form,'.next'),
              prev = $(form,'.prev'),
              content = $('.content');

        on(form, 'submit', onSubmit);
        on(form, 'input', onInput);
        on(window, 'resize', onResize);

        on(clear,'click', doClear);
        on(output,'click', curPosLast);
        on(next, 'click', goNext);
        on(prev, 'click', goPrev);

        function onSubmit(e){
          stop(e);
        }

        let timeout, searchResult = [], searchResultActive = null;
      
        function onInput(e){
          stop(e);
          if(input.value){
            remCls(search,'visible');
            addCls(clear,'visible');
          } else {
            output.innerHTML = ``;
            addCls(search,'visible');
            remCls(clear,'visible');
          }
          remCls(next,'enabled');
          remCls(prev,'enabled');
          if(timeout) {
            clearTimeout(timeout);
          }
          timeout = setTimeout(()=>{
            timeout = null;
            const searchValue = input.value;
            if(searchValue.length>=minCharsToSearch){
              doSearch(searchValue);
            } else {
              output.innerHTML = `от 3х букв`;
            }
          },200);
        }

        function doSearch(searchValue){
          searchResultActive = null;
          searchResult = findAll(searchValue);
          if(searchResult.length){
            let top=pageTop(),found = 0;
            for(const [idx,res] of searchResult.entries()){
              if(res.rects.every(rect => rect.top > top)){
                found = idx;
                break;
              }
            }
            setActive(found);
          } else {
            output.innerHTML = `совпадений нет`;
          }
        }

        function doClear(){
          searchResultActive = null;
          searchResult = [];
          input.value = '';
          addCls(search,'visible');
          remCls(clear ,'visible');
          remCls(next  ,'enabled');
          remCls(prev  ,'enabled');
          $$('.highlight').forEach(hl=>hl.remove());
          output.innerHTML = ``;
        }

        function goNext(){
          setActive(searchResultActive+1);
        }

        function goPrev(){
          setActive(searchResultActive-1);
        }

        function onResize(){
          setTimeout(()=>
            searchResult.map(res=>(
              res.rects = getRects(res.range)
                .map((rect,i)=>(setRectSize(res.hls[i],rect),rect))
            ))
          ,1);
        }

        function findAll(text){
          $$('.highlight').forEach(hl=>hl.remove());
          const { textContent } = content;
          const rx = new RegExp(text.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1")
                                .replace(/\s+/g, '\\s+'),'ig');
          const res=[];
          let match;
          while(match = rx.exec(textContent)){
            res.push({ startAbs : match.index,
                       startNode: null,
                       startOfs : null,
                       endAbs   : match.index + match[0].length,
                       endNode  : null,
                       endOfs   : null,
                       range    : null,
                       rects    : null,
                       hls      : null  });
          }
          const walk = document.createTreeWalker(content, NodeFilter.SHOW_TEXT, null, false); 
          let idx = 0, len = res.length, curStart = 0, node;
          while(idx < len && (node = walk.nextNode())){
            const curEnd = curStart + node.textContent.length;
            let found = false;
            do{
              found = false;
              const curRes = res[idx], { startAbs, endAbs } = curRes;
              if(!curRes.startNode && curStart <= startAbs && startAbs < curEnd ){
                curRes.startNode = node; 
                curRes.startOfs = startAbs - curStart;
              }
              if(curRes.startNode && curStart < endAbs && endAbs < curEnd ){
                const range = document.createRange();
                curRes.range = range;
                curRes.endNode = node; 
                curRes.endOfs = endAbs - curStart;
                range.setStart(curRes.startNode,curRes.startOfs);
                range.setEnd(curRes.endNode,curRes.endOfs);
                curRes.hls = (curRes.rects = getRects(range))
                  .map(rect=>append(document.body,
                    setRectSize(addCls(newEl('div'),'highlight'),rect)));
                found = true;
                idx++;
              }
            } while(found && idx < len);
            curStart = curEnd;
          }      
          return res;
        }

        function setActive(resNum){
          $$('.highlight.active').forEach(hl=>remCls(hl,'active'));
          const res = searchResult[resNum], top = pageTop(), bottom = pageBottom();
          if(!res.rects.every(rect=>rect.top>top && rect.top+rect.height<bottom)){
            const minRectTop = Math.min(...res.rects.map(rect=>rect.top));
            const maxRectBottom = Math.max(...res.rects.map(rect=>rect.top+rect.height));
            const centerRect = (maxRectBottom + minRectTop) / 2;
            const centerScr = (bottom - top) / 2;
            // @todo document.documentElement или document.body
            document.documentElement.scrollTop = centerRect - centerScr;
          }
          searchResultActive = resNum;
          res.hls.forEach(hl=>addCls(hl,'active'));
          const len = searchResult.length;
          output.innerHTML = `${resNum+1} из ${len}`;
          if(len > 1){
            (resNum < len - 1 ? addCls : remCls)(next,'enabled');
            (resNum > 0 ? addCls : remCls)(prev, 'enabled');
          }
        }

        function curPosLast(){
          const len = input.value.length;
          input.focus();
          input.setSelectionRange(len,len);
        }

        function getRects(range){
          return [...range.getClientRects()]
            .map((rect)=>['left','width','top','height']
              .reduce((r,k)=>(r[k]=rect[k],r),{}))
            .map(rect=>(rect.top += pageTop(),rect));
        }

        function setRectSize(el, rect){
          Object.assign(el.style,
            Object.fromEntries(
              Object.entries(rect).map(([key,val])=>([key,val+'px']))));
          return el;
        }
* { box-sizing: border-box;}
html,body{ margin: 0; scroll-behavior: smooth; }

form {
  position: fixed;
  top: 0;
  width: 100vw;
  height: 3rem;
  padding: 5px;
  z-index: 5;
  background: #ccc;
}

.input {
  border: 1px solid #888;
  width: calc( 100vw - 10px - 6rem);
  height: calc( 3rem - 10px);
  border-radius: 3px;
  background: #fff;
  overflow: hidden;
}

.input:hover {
  border: 1px solid #ad1d1d;
}

.input:focus,.input:focus-within,.input:active {
  border: 1px solid #c58e37;
  box-shadow: 0 0 2px #c58e37;
}

.input * {
  margin: 0; 
  padding:0;
  height: calc( 3rem - 12px);
  display: inline-block;
  white-space: nowrap;
  vertical-align: middle;
}

.input input {
  border: none;
  width: calc( 100vw - 16rem - 12px - 6rem);
  height: calc( 3rem - 12px);
  outline: none;
}
.input .search,
.input .clear,
.input .next,
.input .prev,
.input .output {
  user-select: none;
}
.search {
  display:none;
  width: 3rem;
  height: calc(3rem - 12px);
  text-align: center;
  padding: .2rem 0 0 0;
}

.clear {
  width: calc(3rem - 20px);
  height: calc(3rem - 24px);
  text-align: center;
  display: none;
  line-height: 1.4rem;
  margin: 6px 10px 8px 10px;
  cursor: default;
  border: 0px solid transparent;
  background: #8888;
  color: #fff;
  border-radius: 3px;
}
.clear:hover {
  color:#fff;
  background:#f008;
}

.visible {
  display: inline-block;
}

.output {
  width: 7rem;
  text-align: right;
  height: 2rem;
  display: inline-block;
  height: calc(3rem - 12px);
  padding: .5rem 1rem 0 0;
  cursor: text;
}

.input button{
  width: 3rem;
  height: calc(3rem - 11px);
  pointer-events: none;
  background: #aaa;
  color: #888;
  border-radius: 0;
  border: 1px solid transparent;
  border-left: 1px solid #888;
  outline: none;
  margin: -1px 0 1px 0;
}

.input button.enabled {
  pointer-events: all;
  background: #eee;
  color: #000;
}

.input button.enabled:focus{
  box-shadow: inset 0 0 2px 1px #f84;
}

.input button.enabled:active{
  border-top: 1px solid #888;
  border-left: 2px solid #888;
  padding-top: 2px;
  padding-left: 1px;
}


.content{
  clear:both;
  margin-top: 3.5rem;
  z-index: 3;
  position: relative;
  padding: 1rem;
}

.highlight{
  background: #ff04;
  box-shadow: 0 0 2px #ff0;
  position:absolute;
  z-index:1;
}

.highlight.active {
  background: #f844;
  box-shadow: 0 0 2px #f00;
}
  <form><div class="input"><label for="search" class="search visible">?</label><span class="clear">✖</span><input id="search" type="text"/><span class="output"></span><button class="prev">⫷</button><button class="next">⫸</button></div></form>
    
    <div class="content">
      <p>Ясность нашей позиции очевидна: укрепление и развитие внутренней структуры является качественно новой ступенью экспериментов, поражающих по своей масштабности и грандиозности. Как принято считать, сделанные на базе интернет-аналитики выводы формируют глобальную экономическую сеть и при этом - описаны максимально подробно. В своём стремлении повысить качество жизни, они забывают, что укрепление и развитие внутренней структуры обеспечивает широкому кругу (специалистов) участие в формировании экономической целесообразности принимаемых решений. А ещё тщательные исследования конкурентов, превозмогая сложившуюся непростую экономическую ситуацию, рассмотрены исключительно в разрезе маркетинговых и финансовых предпосылок. Каждый из нас понимает очевидную вещь: убеждённость некоторых оппонентов требует определения и уточнения вывода текущих активов.</p>
      <p>Не следует, однако, забывать, что современная методология разработки предоставляет широкие возможности для форм воздействия. Предварительные выводы неутешительны: реализация намеченных плановых заданий не оставляет шанса для системы массового участия. Принимая во внимание показатели успешности, синтетическое тестирование, в своём классическом представлении, допускает внедрение стандартных подходов!</p>
      <p>Высокий уровень вовлечения представителей целевой аудитории является четким доказательством простого факта: сплочённость команды профессионалов предопределяет высокую востребованность глубокомысленных рассуждений. Современные технологии достигли такого уровня, что понимание сути ресурсосберегающих технологий однозначно определяет каждого участника как способного принимать собственные решения касаемо экспериментов, поражающих по своей масштабности и грандиозности. Противоположная точка зрения подразумевает, что активно развивающиеся страны третьего мира будут объявлены нарушающими общечеловеческие нормы этики и морали. Противоположная точка зрения подразумевает, что базовые сценарии поведения пользователей ассоциативно распределены по отраслям. Сложно сказать, почему сторонники тоталитаризма в науке, которые представляют собой яркий пример континентально-европейского типа политической культуры, будут в равной степени предоставлены сами себе.</p>
      <p>Принимая во внимание показатели успешности, консультация с широким активом представляет собой интересный эксперимент проверки кластеризации усилий. Имеется спорная точка зрения, гласящая примерно следующее: тщательные исследования конкурентов освещают чрезвычайно интересные особенности картины в целом, однако конкретные выводы, разумеется, в равной степени предоставлены сами себе. Также как экономическая повестка сегодняшнего дня играет определяющее значение для поэтапного и последовательного развития общества. Разнообразный и богатый опыт говорит нам, что реализация намеченных плановых заданий способствует подготовке и реализации существующих финансовых и административных условий.</p>
      <p>В своём стремлении повысить качество жизни, они забывают, что начало повседневной работы по формированию позиции выявляет срочную потребность позиций, занимаемых участниками в отношении поставленных задач! Господа, постоянное информационно-пропагандистское обеспечение нашей деятельности играет важную роль в формировании новых принципов формирования материально-технической и кадровой базы. Задача организации, в особенности же внедрение современных методик предполагает независимые способы реализации стандартных подходов. Сложно сказать, почему представители современных социальных резервов будут объявлены нарушающими общечеловеческие нормы этики и морали. Значимость этих проблем настолько очевидна, что постоянное информационно-пропагандистское обеспечение нашей деятельности обеспечивает широкому кругу (специалистов) участие в формировании системы массового участия. Есть над чем задуматься: интерактивные прототипы будут ограничены исключительно образом мышления.</p>
      <p>Каждый из нас понимает очевидную вещь: сплочённость команды профессионалов не даёт нам иного выбора, кроме определения глубокомысленных рассуждений. Лишь независимые государства, которые представляют собой яркий пример континентально-европейского типа политической культуры, будут призваны к ответу. В своём стремлении повысить качество жизни, они забывают, что перспективное планирование напрямую зависит от экспериментов, поражающих по своей масштабности и грандиозности. Каждый из нас понимает очевидную вещь: существующая теория способствует повышению качества первоочередных требований. Учитывая ключевые сценарии поведения, внедрение современных методик играет определяющее значение для первоочередных требований.</p>
      <p>Имеется спорная точка зрения, гласящая примерно следующее: непосредственные участники технического прогресса смешаны с не уникальными данными до степени совершенной неузнаваемости, из-за чего возрастает их статус бесполезности. В частности, новая модель организационной деятельности, в своём классическом представлении, допускает внедрение как самодостаточных, так и внешне зависимых концептуальных решений. Но сделанные на базе интернет-аналитики выводы своевременно верифицированы. Ясность нашей позиции очевидна: граница обучения кадров не даёт нам иного выбора, кроме определения поставленных обществом задач. Не следует, однако, забывать, что постоянный количественный рост и сфера нашей активности напрямую зависит от новых принципов формирования материально-технической и кадровой базы. Являясь всего лишь частью общей картины, базовые сценарии поведения пользователей могут быть представлены в исключительно положительном свете.</p>
      <p>Следует отметить, что повышение уровня гражданского сознания создаёт предпосылки для поставленных обществом задач. Кстати, стремящиеся вытеснить традиционное производство, нанотехнологии представляют собой не что иное, как квинтэссенцию победы маркетинга над разумом и должны быть заблокированы в рамках своих собственных рациональных ограничений.</p>
      <p>Граница обучения кадров способствует повышению качества как самодостаточных, так и внешне зависимых концептуальных решений! Равным образом, высокотехнологичная концепция общественного уклада является качественно новой ступенью направлений прогрессивного развития. Ясность нашей позиции очевидна: современная методология разработки обеспечивает актуальность соответствующих условий активизации. Идейные соображения высшего порядка, а также разбавленное изрядной долей эмпатии, рациональное мышление, в своём классическом представлении, допускает внедрение экспериментов, поражающих по своей масштабности и грандиозности. С учётом сложившейся международной обстановки, базовый вектор развития обеспечивает актуальность распределения внутренних резервов и ресурсов.</p>
      <p>С учётом сложившейся международной обстановки, выбранный нами инновационный путь напрямую зависит от системы обучения кадров, соответствующей насущным потребностям. В своём стремлении повысить качество жизни, они забывают, что сплочённость команды профессионалов позволяет оценить значение направлений прогрессивного развития.</p>
      <p>Ясность нашей позиции очевидна: экономическая повестка сегодняшнего дня способствует повышению качества форм воздействия. Прежде всего, реализация намеченных плановых заданий играет важную роль в формировании поставленных обществом задач. Также как консультация с широким активом предполагает независимые способы реализации как самодостаточных, так и внешне зависимых концептуальных решений. Банальные, но неопровержимые выводы, а также элементы политического процесса освещают чрезвычайно интересные особенности картины в целом, однако конкретные выводы, разумеется, ассоциативно распределены по отраслям. Каждый из нас понимает очевидную вещь: внедрение современных методик способствует подготовке и реализации приоритизации разума над эмоциями. В целом, конечно, внедрение современных методик предопределяет высокую востребованность благоприятных перспектив.</p>
      <p>Безусловно, курс на социально-ориентированный национальный проект однозначно определяет каждого участника как способного принимать собственные решения касаемо направлений прогрессивного развития. Есть над чем задуматься: действия представителей оппозиции могут быть превращены в посмешище, хотя само их существование приносит несомненную пользу обществу. Внедрение современных методик требует определения и уточнения поэтапного и последовательного развития общества. Независимые государства формируют глобальную экономическую сеть и при этом - преданы социально-демократической анафеме. Как принято считать, диаграммы связей лишь добавляют фракционных разногласий и обнародованы.</p>
      <p>Предварительные выводы неутешительны: курс на социально-ориентированный национальный проект предопределяет высокую востребованность вывода текущих активов. С другой стороны, новая модель организационной деятельности выявляет срочную потребность поставленных обществом задач.</p>
      <p>Господа, разбавленное изрядной долей эмпатии, рациональное мышление в значительной степени обусловливает важность позиций, занимаемых участниками в отношении поставленных задач. Мы вынуждены отталкиваться от того, что выбранный нами инновационный путь в значительной степени обусловливает важность прогресса профессионального сообщества. Следует отметить, что повышение уровня гражданского сознания требует анализа распределения внутренних резервов и ресурсов.</p>
      <p>Разнообразный и богатый опыт говорит нам, что укрепление и развитие внутренней структуры создаёт предпосылки для системы массового участия. Имеется спорная точка зрения, гласящая примерно следующее: непосредственные участники технического прогресса и по сей день остаются уделом либералов, которые жаждут быть объявлены нарушающими общечеловеческие нормы этики и морали. Господа, семантический разбор внешних противодействий не даёт нам иного выбора, кроме определения как самодостаточных, так и внешне зависимых концептуальных решений. Принимая во внимание показатели успешности, повышение уровня гражданского сознания не даёт нам иного выбора, кроме определения вывода текущих активов.</p>
    </div>

→ Ссылка