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

Я разрабатываю надстройку для Firefox. Мне нужно выделить элементы на веб-странице, используя XPath элемента. Я могу это выделить. Проблема в том, что элементы выглядят искаженно. Они теряют равновесие. Пожалуйста, сконцентрируйтесь на том, как я добавляю свойство display к родительскому элементу, который вызывает у меня проблемы в функции elementHover.

Ниже приведен код, который я пробовал:

$(document).on('mouseenter', 'span[name=element-span]', function() {
    var xpath = $(this).next('input').val();
    $(this).closest("li").addClass("hovered");
    browser.tabs.executeScript(tempTabId, {
        code: "var css = '.highlistelement{" + "outline:2px solid #F70B0B !important;" + "border:2px solid red !important;" +
        "-webkit-box-shadow:0 0 0 2px #F70B0B !important, 0 0 0 2px #F70B0B !important;" + "}'," +
        "head = document.getElementsByTagName('head')[0],style = document.createElement('style');" + "style.type = 'text/css';" +
        "if (style.styleSheet){style.styleSheet.cssText = css;} " + "else {style.appendChild(document.createTextNode(css));" + "}head.appendChild(style);"
    });
    browser.tabs.executeScript(tempTabId, {
        code: "var css = '.block{" + "display:inline-block  !important;" +"};"
    });
    browser.tabs.executeScript(tempTabId, {
        code: "var css = '.displayBlock{" + "display:inline-block !important;" +"}',"+
        "head = document.getElementsByTagName('head')[0],style = document.createElement('style');" + "style.type = 'text/css';" +
        "if (style.styleSheet){style.styleSheet.cssText = css;} " + "else {style.appendChild(document.createTextNode(css));" + "}head.appendChild(style);"
    });
    browser.tabs.executeScript(tempTabId, {
        code: elementHover(xpath, "highlistelement","displayBlock","block")
    });
});

function elementHover(xpath, highlightClass,displayClass,blockClass) {
    var str = 'var path="' + xpath + '";' +
        'var iterator = document.evaluate(path, document, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null); ' +
        'try {' +
        'var thisNode = iterator.iterateNext();' +
        'while (thisNode) {' +
        'thisNode.classList.add("' + highlightClass + '");' +
        'pnode=thisNode.parentNode;'+
        ' while(pnode){'+
        'if(pnode.style.getPropertyValue("display")==="none")'+
        '{'+
        'pnode.classList.add("'+blockClass+'");' +
        '}' +
        'else if(pnode.style.getPropertyValue("display")==="block"){' +
        'pnode.style.display="block"' +
         '}'+
        'else if(pnode.style.getPropertyValue("display")==="inline-block"){' +
        'pnode.style.display="inline-block"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="flex"){' +
        'pnode.style.display="flex"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="inline"){' +
        'pnode.style.display="inline"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="inline-flex"){' +
        'pnode.style.display="inline-flex"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="inline-table"){' +
        'pnode.style.display="inline-table"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="list-item"){' +
        'pnode.style.display="list-item"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="run-in"){' +
        'pnode.style.display="run-in"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="table"){' +
        'pnode.style.display="table"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="table-caption"){' +
        'pnode.style.display="table-caption"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="table-column-group"){' +
        'pnode.style.display="table-column-group"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="table-header-group"){' +
        'pnode.style.display="table-header-group"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="table-footer-group"){' +
        'pnode.style.display="table-header-group"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="table-row-group"){' +
        'pnode.style.display="table-row-group"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="table-cell"){' +
        'pnode.style.display="table-cell"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="table-column"){' +
        'pnode.style.display="table-cell"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="table-row"){' +
        'pnode.style.display="table-row"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="initial"){' +
        'pnode.style.display="initial"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="inherit"){' +
        'pnode.style.display="inherit"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="")' +
        '{'+
        'pnode.classList.add("'+displayClass+'");' +
        'var evObj = document.createEvent("Events");'+
        ' evObj.initEvent("mouseover", true, false);'+
        'pnode.dispatchEvent(evObj);'+
        '}else  if(pnode.style.getPropertyValue("visibility")==="hidden")'+
        '{'+
        'pnode.style.visibility = "visible";' +
        '}' +
        'thisNode.scrollIntoView(true);' +
        'pnode=pnode.parentNode;'+
        '}' +
        'thisNode = iterator.iterateNext();' +
        '}' +
        '} catch (e) {' +
        '}';
    return str;
}

Пожалуйста, найдите образец изображения ниже, чтобы понять проблему:

введите здесь описание изображения

Обратите внимание на изображение. Когда я выделяю текст «Gmail», оставшиеся две ссылки перемещаются на следующую строку.


person Narayana Bojja    schedule 27.01.2017    source источник
comment
Пожалуйста, поместите свой более длинный код в отдельный файл, а не в виде длинных многострочных строк. Намного легче понять, находится ли код в другом правильно отформатированном файле. Если вы собираетесь поместить код в многострочную строку, то, по крайней мере, отформатируйте его так, чтобы он читался с обычным отступом.   -  person Makyen♦    schedule 27.01.2017
comment
Пожалуйста, отредактируйте вопрос по теме: включите полный минимальный воспроизводимый пример, который дублирует проблему. Включая manifest.json, некоторые скрипты background / content / popup / HTML. Вопросы, требующие помощи по отладке (почему этот код не работает?), должны включать: ► желаемое поведение, ► конкретную проблему или ошибку и ► кратчайший код, необходимый для воспроизведения это в самом вопросе. Вопросы без четкой постановки проблемы не будут полезны другим читателям. См .: Как создать минимальный воспроизводимый пример, О каких темах я могу спросить здесь? и Как спросить.   -  person Makyen♦    schedule 27.01.2017
comment
Если вы уже понимаете, что изменение стиля display для предков элемента вызывает интересующую вас проблему, почему вы все еще меняете стиль display? Должен признать, учитывая объем кода, который вы посвятили изменению стиля display предка, я предположил, что изменения макета в результате изменения стиля display были желательными.   -  person Makyen♦    schedule 27.01.2017


Ответы (1)


Применяемые стили изменяют макет. Вы меняете размер блока, который вас интересует, и меняете значение стиля display для всех его родительских элементов.

Добавление границы изменяет размер отображаемого элемента

В частности, вы добавляете границу: border:2px solid red !important;.

Перед применением вашего стиля модель коробки представляет собой коробку размером 34 × 24:

Поле перед рамкой

После добавления границы размер прямоугольника составляет 38 × 28 (по 2 дополнительных пикселя с каждой стороны).

После добавления границы

Если вы не хотите, чтобы макет изменялся, убедитесь, что добавляемые стили не изменяют размер поля, в котором отображается элемент. В этом случае, поскольку вы также применяете стиль outline:2px solid #F70B0B !important;, вы можете получить очень похожий эффект, просто не используя стиль border:2px solid red !important;.

Ниже приведен быстрый пример, показывающий, как добавление границы изменяет размер элемента по сравнению с контуром, который этого не делает. Граница или контур добавляются при наведении курсора.

.borderOnHover:hover {
  border:2px solid red !important;
}
.outlineOnHover:hover {
  outline:2px solid #F70B0B !important;
}
<span class="borderOnHover">Border changes the size</span>
<span>Other Text</span>
<br/>
<br/>
<span class="outlineOnHover">Outline does not change the size</span>
<span>Other Text</span>
<br/>

Изменение свойства display для всех предков

Ваш код также проходит через изменение свойства display для всех предков элемента. То, что каждый из них заменяется, зависит от его предыдущего значения. Это можно сделать либо путем изменения атрибута display, либо путем добавления класса displayBlock. Вы также добавляете класс block, но никогда не определяете класс block, поэтому он не имеет никакого эффекта. Чтобы не повлиять на макет, вам не нужно изменять свойство display для элемента или любого из его предков.

Ваш block класс CSS никогда не создается. Вы назначаете текст переменной css, но тогда значение переменной немедленно изменяется на текст для вашего класса displayBlock, который затем добавляется как <style>.

person Makyen♦    schedule 27.01.2017
comment
Спасибо за ваши старания. Но это не решило мою проблему. - person Narayana Bojja; 27.01.2017
comment
@Narayana, я обновил это, чтобы упомянуть, что вы не должны изменять стиль display ни для одного из предков элемента или элемента. Я раньше не упоминал об этом, потому что вы явно собираетесь приложить немало усилий, чтобы изменить этот стиль на всех предках. Учитывая такой уровень усилий, я предположил, что это то, что вы действительно хотите изменить. Однако он, безусловно, меняет макет. Если вы не хотите, чтобы макет вообще не менялся, вам не нужно изменять этот стиль ни на каких элементах. - person Makyen♦; 27.01.2017
comment
Спасибо за ваш ответ. Если я не изменю свойство отображения родительских элементов, я не смогу выделить всплывающие элементы. Есть ли способ выделить элементы во всплывающем окне без изменения свойства отображения? - person Narayana Bojja; 27.01.2017
comment
@Narayana, вам нужно будет быть более конкретным, чтобы передать то, что вы хотите. О каком именно всплывающем окне вы имеете в виду? Вы спрашиваете о всплывающем окне для вашего расширения? Мне или кому-либо другому понадобятся явные примеры того, что вас беспокоит. - person Makyen♦; 27.01.2017