Javascript: как создать элемент кнопки без текстового содержимого

В html у меня есть элемент кнопки без текста. У него есть дочерний элемент svg с несколькими путями и прямоугольниками. Работает нормально:

Я пытаюсь создать это в javascript. Проблема в том, что кнопки не видно. Если я задаю ему какой-то текст с помощью textContent или innerHtml, кнопка будет видна вместе с текстом, но svg не будет. Как я могу создать эту кнопку в javascript? Это код:

var myButton = document.createElement("button");
myButton.setAttribute("class", "my-button");
myButton.setAttribute("id", "foo");

var mySVG = document.createElement("svg");
mySVG.setAttribute("id", "my-svg");
mySVG.setAttribute("viewBox", "0 0 12.25 15.45");

var icon1 = document.createElement("g");
icon1.setAttribute("class", "g-element1");
icon1.setAttribute("id", "g1");

var iconPath = document.createElement("path");
iconPath.setAttribute("d", "M0,25L0,0l12.25,7.7L0,15.45z");

var icon2 = document.createElement("g");
icon2.setAttribute("class", "g-element2");
icon2.setAttribute("id", "g2");

var rect1 = document.createElement("rect");
rect1.setAttribute("x", "0");
rect1.setAttribute("y", "0");
rect1.setAttribute("width", "4.1");
rect1.setAttribute("height", "15.45");

var rect2 = document.createElement("rect");
rect2.setAttribute("x", "8.1");
rect2.setAttribute("y", "0");
rect2.setAttribute("width", "4.1");
rect2.setAttribute("height", "15.45");

icon1.appendChild(iconPath);
icon2.appendChild(rect1);
icon2.appendChild(rect2);

mySVG.appendChild(icon1);
mySVG.appendChild(icon2);

myButton.appendChild(mySVG);

document.getElementById('some-element').appendChild(myButton)
.my-button {
  font-size: 14px;
  height: 17px;
  cursor: pointer;
  margin-left: 5px;
  &:hover, &:focus {
    opacity: .8;
  }
}
<div id = "some-element">
<button class = "my-button" id = "foo">
    <svg id = "my-svg" viewBox = "0 0 12.25 15.45">
        <g class = "g-element1" id = "g1">
            <path d = "M0,25L0,0l12.25,7.7L0,15.45z"/>
        </g>
        <g class = "g-element2" id = "g2">
            <rect x = "0" y = "0" width = "4.1" height = "15.45"/>
            <rect x = "8.1" y = "0" width = "4.1" height = "15.45"/>
         </g>
     </svg>
 </button>
 </div>

Кроме того, когда я создаю только кнопку в javascript и не устанавливаю для нее текст (и не svg), кнопка не отображается.

Можете ли вы попробовать добавить текстовый узел с пустым пространством? document.createTextNode ("\ u00A0");

Xedret 19.07.2018 21:13

Как указано в здесь, вы можете попробовать document.createElementNS("http://www.w3.org/2000/svg", "svg"); вместо document.createElement("svg");, но это всего лишь идея

Henrique Pauli 19.07.2018 21:16

Я вижу две кнопки при запуске опубликованного примера кода. Ни в одном из них нет никакого SVG, но я не уверен, что должен отображать SVG. Обратите внимание, что вы должны использовать уникальные идентификаторы в своем HTML.

Heretic Monkey 19.07.2018 21:22

@HenriquePauli Это на самом деле почти правильно, за исключением того, что мне пришлось использовать эту конструкцию для всех дочерних элементов svg и их атрибутов, таких как здесь. Теперь это работает. Спасибо за предложение.

T.Poe 19.07.2018 21:54
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
4
270
4

Ответы 4

Ваш код на самом деле в порядке, но вам понадобится способ добавить кнопку в DOM, например, если вы хотите добавить ее в тело, вам, возможно, придется сделать что-то вроде

document.body.appendChild(playButton)

Вы также можете добавить его к существующему элементу на веб-странице.

Конечно, я добавляю его в DOM (я сказал в вопросе, что кнопка работает, если я помещаю в нее какой-то textContent.), Я просто не включил ее в пример, извините. Обновлено. Так что должно быть что-то

T.Poe 19.07.2018 21:12

Кажется, что SVG сжимается до нулевой ширины и высоты внутри кнопки. Вы можете предотвратить это, установив для него явную ширину и высоту:

.my-button {
  font-size: 14px;
  height: 17px;
  cursor: pointer;
  margin-left: 5px;
  &:hover, &:focus {
    opacity: .8;
  }
}
#my-svg {width: 100%; height: 100%}
<div id = "some-element">
<button class = "my-button" id = "foo">
    <svg id = "my-svg" viewBox = "0 0 12.25 15.45">
        <g class = "g-element1" id = "g1">
            <path d = "M0,25L0,0l12.25,7.7L0,15.45z"/>
        </g>
        <g class = "g-element2" id = "g2">
            <rect x = "0" y = "0" width = "4.1" height = "15.45"/>
            <rect x = "8.1" y = "0" width = "4.1" height = "15.45"/>
         </g>
     </svg>
 </button>
 </div>

То же самое должно применяться независимо от того, определен ли SVG встроенным или сгенерированным сценарием. Но обратите внимание, что при создании узлов, отличных от HTML, необходимо использовать .createElementNS() и включить пространство имен, как показано ниже:

var myButton = document.createElement("button");
myButton.setAttribute("class", "my-button");
myButton.setAttribute("id", "foo");

var svgns = "http://www.w3.org/2000/svg";

var mySVG = document.createElementNS(svgns, "svg");
mySVG.setAttribute("id", "my-svg");
mySVG.setAttribute("viewBox", "0 0 12.25 15.45");

var icon1 = document.createElementNS(svgns, "g");
icon1.setAttribute("class", "g-element1");
icon1.setAttribute("id", "g1");

var iconPath = document.createElementNS(svgns, "path");
iconPath.setAttribute("d", "M0,25L0,0l12.25,7.7L0,15.45z");

var icon2 = document.createElementNS(svgns, "g");
icon2.setAttribute("class", "g-element2");
icon2.setAttribute("id", "g2");

var rect1 = document.createElementNS(svgns, "rect");
rect1.setAttribute("x", "0");
rect1.setAttribute("y", "0");
rect1.setAttribute("width", "4.1");
rect1.setAttribute("height", "15.45");

var rect2 = document.createElementNS(svgns, "rect");
rect2.setAttribute("x", "8.1");
rect2.setAttribute("y", "0");
rect2.setAttribute("width", "4.1");
rect2.setAttribute("height", "15.45");

icon1.appendChild(iconPath);
icon2.appendChild(rect1);
icon2.appendChild(rect2);

mySVG.appendChild(icon1);
mySVG.appendChild(icon2);

document.getElementById('some-element').appendChild(mySVG)
#my-svg {
  width: 100%;
  height: 100%
}

button {height: 14px}
<button id = "some-element"></div>

Установка элемента svg как innerHTML для button может дать вам результат.

document.getElementById('foo').innerHTML = '<svg id = "my-svg" viewBox = "0 0 12.25 15.45"><g class = "g-element1" id = "g1"><path d = "M0,25L0,0l12.25,7.7L0,15.45z"/></g><g class = "g-element2" id = "g2"><rect x = "0" y = "0" width = "4.1" height = "15.45"/><rect x = "8.1" y = "0" width = "4.1" height = "15.45"/></g></svg>';
.my-button {
  font-size: 14px;
  height: 17px;
  cursor: pointer;
  margin-left: 5px;
  &:hover, &:focus {
    opacity: .8;
  }
}

svg
{
    height:100%;
  width:100%;
}
<div id = "some-element">
<button class = "my-button" id = "foo">
 </button>
 </div>

При создании элементов SVG (включая элементы внутри тега SVG) с использованием JavaScript необходимо использовать document.createElementNS(namespaceURI, qualifiedName) с соответствующим URI пространства имен http://www.w3.org/2000/svg. Вам также необходимо назначить высоту для элемента SVG.

Поскольку вам нужно использовать пространство имен для каждого элемента, который вы создаете в теге SVG, а также для самого тега SVG, вы можете захотеть каррировать функцию для экономии места и предотвращения опечаток:

const createSVGElement = qn => document.createElementNS("http://www.w3.org/2000/svg", qn);

Вот ваш код исправлен:

var myButton = document.createElement("button");
myButton.setAttribute("class", "my-button");
myButton.setAttribute("id", "foo");

const createSVGElement = qn => document.createElementNS("http://www.w3.org/2000/svg", qn);

var mySVG = createSVGElement("svg");
mySVG.setAttribute("id", "my-svg");
mySVG.setAttribute('height', "14px");
mySVG.setAttribute("viewBox", "0 0 12.25 15.45");

var icon1 = createSVGElement("g");
icon1.setAttribute("class", "g-element1");
icon1.setAttribute("id", "g1");

var iconPath = createSVGElement("path");
iconPath.setAttribute("d", "M0,25L0,0l12.25,7.7L0,15.45z");

var icon2 = createSVGElement("g");
icon2.setAttribute("class", "g-element2");
icon2.setAttribute("id", "g2");

var rect1 = createSVGElement("rect");
rect1.setAttribute("x", "0");
rect1.setAttribute("y", "0");
rect1.setAttribute("width", "4.1");
rect1.setAttribute("height", "15.45");

var rect2 = createSVGElement("rect");
rect2.setAttribute("x", "8.1");
rect2.setAttribute("y", "0");
rect2.setAttribute("width", "4.1");
rect2.setAttribute("height", "15.45");

icon1.appendChild(iconPath);
icon2.appendChild(rect1);
icon2.appendChild(rect2);

mySVG.appendChild(icon1);
mySVG.appendChild(icon2);

myButton.appendChild(mySVG);

document.getElementById("some-element").appendChild(myButton);
.my-button {
  font-size: 14px;
  height: 17px;
  cursor: pointer;
  margin-left: 5px;
  &:hover, &:focus {
    opacity: .8;
  }
}
<div id = "some-element">
<button class = "my-button" id = "foo">
    <svg id = "my-svg" viewBox = "0 0 12.25 15.45" height = "14px">
        <g class = "g-element1" id = "g1">
            <path d = "M0,25L0,0l12.25,7.7L0,15.45z"/>
        </g>
        <g class = "g-element2" id = "g2">
            <rect x = "0" y = "0" width = "4.1" height = "15.45"/>
            <rect x = "8.1" y = "0" width = "4.1" height = "15.45"/>
         </g>
     </svg>
 </button>
 </div>

Другие вопросы по теме