Поле ввода SVG

Я пытаюсь заставить одно из моих текстовых полей SVG принимать ввод от пользователя, когда он нажимает на него. Есть ли способ сделать это?

    const wrapper = document.getElementById('wrapper');
    const text = document.getElementById('Username');
    
    const inputWrapper = document.getElementById('input-wrapper');
    const input = document.getElementById('input');
    const button = document.getElementById('button');
    
    
    text.addEventListener('click', () => {
      text.classList.toggle('hide');
      inputWrapper.classList.toggle('hide');
      input.focus();
    });
    
    button.addEventListener('click', () => {
      text.classList.toggle('hide');
      inputWrapper.classList.toggle('hide');
    });
    
    input.addEventListener('change', (e) => {
      text.innerText = e.target.value;
    });
         .cls-1 {
            clip-path: url(#clip-Login_page);
          }
    
          .cls-2 {
            opacity: 0.67;
            fill: url(#pattern);
          }
    
          .cls-3 {
            fill: #d9d9d9;
          }
    
          .cls-3, .cls-5 {
            stroke: #0d0d0d;
          }
    
          .cls-4 {
            fill: url(#pattern-2);
          }
    
          .cls-5 {
            fill: #f2f2f2;
          }
    
          .cls-6, .cls-7 {
            fill: #707070;
            font-family: Georgia;
          }
    
          .cls-6 {
            font-size: 25px;
          }
    
          .cls-7 {
            font-size: 20px;
          }
    
          .cls-8 {
            stroke: none;
          }
    
          .cls-9 {
            fill: none;
          }
    
          .cls-10 {
            fill: #fff;
          }
    
          .cls-11 {
            filter: url(#Rectangle_5);
          }
    
          .cls-12 {
            filter: url(#Amcan_logo);
          }
    
          .cls-13 {
            filter: url(#Rectangle_2);
          }
    	  .hide {
    		display: none;
    		}
 
    <svg xmlns = "http://www.w3.org/2000/svg" xmlns:xlink = "http://www.w3.org/1999/xlink" viewBox = "0 0 375 667">
      <defs>
 
        <pattern id = "pattern" preserveAspectRatio = "none" width = "100%" height = "100%" viewBox = "0 0 1920 1080">
          <image width = "1920" height = "1080" xlink:href = "img/Amcan.gif"/>
        </pattern>
        <filter id = "Rectangle_2" x = "11" y = "178" width = "354" height = "63" filterUnits = "userSpaceOnUse">
          <feOffset dy = "5" input = "SourceAlpha"/>
          <feGaussianBlur stdDeviation = "3" result = "blur"/>
          <feFlood flood-opacity = "0.161"/>
          <feComposite operator = "in" in2 = "blur"/>
          <feComposite in = "SourceGraphic"/>
        </filter>
        <pattern id = "pattern-2" preserveAspectRatio = "none" width = "100%" height = "100%" viewBox = "0 0 593 186">
          <image width = "593" height = "186" xlink:href = "img/Amcan_logo.png"/>
        </pattern>
        <filter id = "Amcan_logo" x = "13" y = "28" width = "349" height = "123" filterUnits = "userSpaceOnUse">
          <feOffset dy = "10" input = "SourceAlpha"/>
          <feGaussianBlur stdDeviation = "3" result = "blur-2"/>
          <feFlood flood-opacity = "0.161"/>
          <feComposite operator = "in" in2 = "blur-2"/>
          <feComposite in = "SourceGraphic"/>
        </filter>
        <filter id = "Rectangle_5" x = "77" y = "369" width = "222" height = "63" filterUnits = "userSpaceOnUse">
          <feOffset dy = "5" input = "SourceAlpha"/>
          <feGaussianBlur stdDeviation = "3" result = "blur-3"/>
          <feFlood flood-opacity = "0.161"/>
          <feComposite operator = "in" in2 = "blur-3"/>
          <feComposite in = "SourceGraphic"/>
        </filter>
        <clipPath id = "clip-Login_page">
          <rect width = "375" height = "667"/>
        </clipPath>
      </defs>
    		
      <g id = "Login_page" data-name = "Login page" class = "cls-1">
        <rect class = "cls-10" width = "375" height = "667"/>
        <rect id = "Amcanerino" class = "cls-2" width = "510" height = "667" transform = "translate(-71)"/>
        <g class = "cls-13" transform = "matrix(1, 0, 0, 1, 0, 0)">
          <g id = "Rectangle_2-2" data-name = "Rectangle 2" class = "cls-3" transform = "translate(20 182)">
            <rect class = "cls-8" width = "336" height = "45"/>
            <rect class = "cls-9" x = "0.5" y = "0.5" width = "335" height = "44"/>
          </g>
        </g>
        <g class = "cls-12" transform = "matrix(1, 0, 0, 1, 0, 0)">
          <rect id = "Amcan_logo-2" data-name = "Amcan_logo" class = "cls-4" width = "331" height = "104" transform = "translate(22 28)"/>
        </g>
        <g id = "Rectangle_3" data-name = "Rectangle 3" class = "cls-5" transform = "translate(20 250)">
          <rect class = "cls-8" width = "336" height = "45"/>
          <rect class = "cls-9" x = "0.5" y = "0.5" width = "335" height = "44"/>
        </g>
        <g id = "Rectangle_4" data-name = "Rectangle 4" class = "cls-5" transform = "translate(20 311)">
          <rect class = "cls-8" width = "336" height = "45"/>
          <rect class = "cls-9" x = "0.5" y = "0.5" width = "335" height = "44"/>
        </g>
        <g class = "cls-11" transform = "matrix(1, 0, 0, 1, 0, 0)">
          <g id = "Rectangle_5-2" data-name = "Rectangle 5" class = "cls-3" transform = "translate(86 373)">
            <rect class = "cls-8" width = "204" height = "45"/>
            <rect class = "cls-9" x = "0.5" y = "0.5" width = "203" height = "44"/>
          </g>
        </g>
        <text id = "SUBMIT" class = "cls-6" transform = "translate(139 405)"><tspan x = "0" y = "0">SUBMIT</tspan></text>
    	<text id = "Login" class = "cls-6" transform = "translate(156 214)"><tspan x = "0" y = "0">Login</tspan></text>
    	
    	<div id = "wrapper">
      <text id = "Username" class = "cls-7" transform = "translate(142 280)"><tspan x = "0" y = "0">Username</tspan></text>
      <div id = "input-wrapper" class = "hide">
        <input id = "input" type = "text" value = "Username"/>
        <button id = "button">Submit</button>
      </div>
    </div>
        <text id = "Password" class = "cls-7" transform = "translate(145 341)"><tspan x = "0" y = "0">Password</tspan></text>
      </g>
    </svg>

Это измененный код, предложенный Solo.

Это довольно сложно. Чтобы иметь возможность редактировать текст svg, вы должны поместить svg в контентный элемент. Однако вам нужен способ защитить остальную часть содержимого внутри svg от удаления. Это ручка, в которой текст внутри SVG доступен для редактирования: Навыки, пригодные для SVG Также: у вас есть <div> внутри svg, но вы не используете <foreignObject> Это недопустимый код

enxaneta 30.11.2018 16:00
Поведение ключевого слова "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) для оценки ваших знаний,...
1
1
5 921
5

Ответы 5

используйте contenteditable на tspan

подробнее здесь - https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Editable_content

How does it work?

All you have to do is set the contenteditable attribute on nearly any HTML element to make it editable.

function toggleEdit() {
  var text = document.getElementById('Username');
  var tspan = text.firstElementChild;
  tspan.setAttribute('contenteditable', true);
}
<text id = "Username" class = "cls-7" transform = "translate(142 280)"><tspan x = "0" y = "0">Username</tspan></text>
<div><button onclick = "toggleEdit();">Edit input</button></div>

Я думаю, что он предназначен только для HTML <div>, он не работает, когда я меняю код :(

Daniel Klas 30.11.2018 13:23

@DanielKlas developer.mozilla.org/en-US/docs/Web/Guide/HTML/…

line88 30.11.2018 13:24

Какое отношение имеет к редактируемым элементам SVG, как просил ОП?

40detectives 20.04.2021 04:34

Нет необходимости в jquery или JS, Просто добавьте contenteditable = "true" к этому текстовому элементу, и все готово ...

<text contenteditable = "true" id = "Username" class = "cls-7" transform = "translate(142 280)"><tspan x = "0" y = "0">Username</tspan></text>

Это не позволяет мне изменять текст.

Daniel Klas 30.11.2018 14:14

Да, фрагмент на этом сайте работает отлично, но когда я добавляю его в свой документ, он просто ничего не делает.

Daniel Klas 30.11.2018 14:22

<tspan> и <text> - это не элементы html, а элементы svg со своими собственными атрибутами. Свойство contenteditable не существует в tspan (вы можете console.info document.querySelector("#myTspan").isContentEditable, он вернет undefined.

Однако он может наследовать свойства от своих родителей. Таким образом, в случае встроенного svg в файл HTML, упаковка вашего svg в редактируемый элемент будет работать в некоторых браузерах, но все ваши тексты затем станут редактируемыми.

<div contenteditable = "true">
<svg>
<text id = "Username" class = "cls-7" transform = "translate(142 20)"><tspan x = "0" y = "0">Username</tspan></text>
</svg>
</div>

В автономном SVG у вас нет возможности работать с contenteditable, поскольку это часть спецификации HTML, а не SVG.

Вы должны использовать сценарий, как предлагают другие ответы, но внимательно прочитайте (поскольку вы сначала не упомянули, что это был автономный svg): Включение JavaScript в SVG

Текст «Имя пользователя» исчез, но я все еще не могу добавить текст вместо него :(

Daniel Klas 30.11.2018 14:16

Спасибо большое за помощь, ребята! Я обнаружил, что для этого могу просто использовать форму подсказки JavaScript. Все, что мне нужно было сделать, это реализовать следующее:

<script>
	function changeUsername()
	{
		document.getElementById('Username').textContent = prompt("Please enter your Username");
	}
	</script>

<rect onclick = "changeUsername()" class = "cls-8" width = "336" height = "45"/>

Совершенно забыл о существовании оперативной формы! Еще раз всем спасибо :)

Да и нет, вы не можете редактировать текст напрямую, но вы можете поместить ввод поверх него. См. Код ниже:

.input-real {
  background: rgba(255, 255, 255, 0);
  color: transparent;
  padding: 0;
  border: 0 none transparent;
  line-height: 0;
}

.input-real:focus {
  background: rgba(255, 255, 255, 1);
  color: #333;
}

.input-real,
.input-mimic {
  font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
  font-size: 14px;
}
<svg viewBox = "0 0 375 667">
  <text id = "Username" class = "input-mimic" x = "50" y = "50" alignment-baseline = "hanging">Username</text>
  <foreignObject width = "50" height = "23" x = "50" y = "46">
    <input id = "input" class = "input-real" type = "text" value = "Username"/>
  </foreignObject>
</svg>

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