addEventListener 和 `this` 没有按预期工作
addEventListener and `this` not working as expected
我是一名经验丰富的程序员,但对网络编程有些陌生。我正在尝试使用 VS2010 学习 Javascript、HTML5 和 SVG,方法是编写一个使用 Javascript.
玩井字游戏的 HTML 页面
我成功地将九个方块中的每一个都创建为 SVG <rect...>
元素,但是我在处理每个方块的点击事件处理程序时遇到了问题。
这是存在于 HTML 文件中的基本 SVG 元素:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
id="svgTTT" width="150" height="150" viewBox="0 0 300 300" >
<rect width="3" height="300" x="99" fill="#008d46" />
<rect width="3" height="300" x="199" fill="#000000" />
<rect width="300" height="3" y="99" fill="#008d46" />
<rect width="300" height="3" y="199" fill="#d2232c" />
</svg>
这些静态 <rect>
元素绘制了 TicTacToe 棋盘的交叉哈希线。九个棋盘方块是在从 windows 加载事件(下方)调用的 javascript 函数中创建的。
这是 javascript(在 HTML 正文的 <script>
元素中内嵌):
<script type="text/javascript">
function getEl(s) { return document.getElementById(s); }
var svg; // get the TTT svg
// execute after HTML has rendered
window.onload = function () {
svg = getEl("svgTTT");
tttSetupSquares(svg);
alert("click-squares are setup.");
}
var cells = new Array(3);
// setup the click squares
function tttSetupSquares(brd) {
for (var i = 0; i < 3; i++) {
cells[i] = new Array(3);
for (var j = 0; j < 3; j++) {
var x = 3 + (i * 100);
var y = 3 + (j * 100);
var newId = "svgTTTsqr" + i.toString() + j.toString();
// add in new rect with html
brd.innerHTML += "<rect id='"+newId+"' width='93' height='93' "
+ "fill='#00DD00' x='" + x.toString() + "' y ='" + y.toString() + "'"
+ " />";
//find it using the newId
var rect = document.getElementById(newId);
//make a cell object to contain all of this
var cell = {
col: i,
row: j,
pSvg: svg,
rect: rect,
handleClick: function (event) {
try {
// this line fails because `this` is the target, not the cell
var svgNS = this.pSvg.namespaceURI;
var line = document.createElementNS(svgNS, 'line');
this.pSvg.appendChild(line);
}
catch (err) {
alert("handlClick err: " + err);
}
}
}
//add a click handler for the rect/cell
cell.rect.addEventListener("click", cell.handleClick, false);
//(only seems to work the last time it is executed)
//save the cell object for later use
cells[i][j] = cell;
}
}
}
</script>
(我可以提供完整的页面源代码,但只有 HTML 个包含这些的元素。)
问题有两个:
只有最后一个 addEventListener
似乎有效。单击所有其他方块没有任何作用。单击最后一个方块 (svgTTTsqr22) 会 运行 cell.handleClick
但会导致问题 2(如下)。 Chrome 开发人员工具 (F12) 显示所有 <rect>
元素,但最后一个元素没有事件侦听器。
当 cell.handleClick
执行 运行 时,它在第一行 (var svgNS = this.pSvg.namespaceURI;
) 上失败并出现类似“undefined object does没有名为 "namespaceURI" 的 属性 在 Devleoper Tools 中检查表明它失败了,因为 this
没有设置为 cell
对象,而是设置为 SVG <rect>
单击的元素。
所以我的问题是:
一个。我在这里做错了什么,
乙。 can/should 我是怎么做到的?
一些建议:
您可以考虑使用事件委托。如果你使用像 jQuery 或 Angular 或 React 这样的框架或库,它会自动为你进行事件委托。在单独的 DOM 元素上设置多个事件处理程序可能会影响性能。你可以做的是在包装元素上有一个 "click" 处理程序,并使用 event.target
属性 查看实际点击的元素。
svg.addEventListener("click", function (e) {
if (e.target.nodeName === "rect" && (/^svgTTTsqr/).test(e.target.id)) {
// Use a regexp on e.target.id to find your
// cell object in `cells`
}
});
正则表达式可能有点脏,所以也许您应该改用数据属性。
// Generating the HTML
brd.innerHTML += "<rect id='"+newId+"' data-i='" + i + "' data-j='" + j + "' "
// The event handler:
svg.addEventListener("click", function (e) {
if (e.target.nodeName === "rect" && (/^svgTTTsqr/).test(e.target.id)) {
var i = e.target.getAttribute("data-i");
var j = e.target.getAttribute("data-j");
var cell = cells[i][j];
cell.handleClick();
}
});
如果这样做,您还可以轻松地进行另一项性能调整,即首先生成整个 HTML 字符串,然后在一次操作中将其附加到 DOM,因为您不再必须将 HTML 插入 DOM 并在循环时添加事件侦听器。
关于你的问题,
1) 抱歉,帮不了你:( 需要设置一个可执行示例并四处寻找,阅读代码时想不出任何东西。我要去 post这个答案无论如何,希望上面解释的事件委托解决方案可以解决问题。
2) 被调用的原始函数显然将它们的 'this' 绑定到它们被调用的任何范围。调用者还可以显式设置 'this' 绑定到什么。解决方案是创建一个包装的新函数,以便 'this' 被强制成为你想要的任何东西。使用内置 function () {}.bind(cell)
它将 return 一个包装原始函数的新函数,并且在原始 this
中,无论上下文如何,函数 this
将始终设置为 cell
=43=]ed 由 bind
调用。
如上所述,"this" 的问题在于它绑定到一个上下文,而这并不总是您想要的上下文。这类问题有很多解决方案。从臭名昭著的 self=this
技巧到 .bind()
。对此也有很多答案,通常它可能是重复的。可以在这里找到一个很好的答案和一些后续阅读:
var self = this?
或此处:How to change the context of a function in javascript
或者在这里:http://ryanmorr.com/understanding-scope-and-context-in-javascript/
或此处:https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Operators/this
尽管您问题的真正答案非常具体。对于事件处理程序,"this" 问题有一个解决方案。您只需要实现一个 EventListener 接口。这听起来比实际更复杂。事实上这很容易。您的对象只需实现一个功能:.handleEvent
。当您将对象传递给 addEventListener() 函数时,会自动调用此函数。这样做的好处是,使用这种方法,"this" 的上下文将自动正确。无需破解或解决方法。知道一般情况下的解决方法当然很好,但是对于这种特定情况,.handleEvent
是解决方案。
这是一个完整的工作示例:
function getEl(s) { return document.getElementById(s); }
var svg; // get the TTT svg
// execute after HTML has rendered
window.onload = function () {
svg = getEl("svgTTT");
tttSetupSquares(svg);
//alert("click-squares are setup.");
}
var cells = new Array(3);
// setup the click squares
function tttSetupSquares(brd) {
for (var i = 0; i < 3; i++) {
cells[i] = new Array(3);
for (var j = 0; j < 3; j++) {
var x = 3 + (i * 100);
var y = 3 + (j * 100);
var rect= document.createElementNS("http://www.w3.org/2000/svg","rect")
rect.setAttribute("x",x);
rect.setAttribute("y",y);
rect.setAttribute("width",100);
rect.setAttribute("height",100);
rect.setAttribute("fill","grey")
brd.appendChild(rect)
var cell = {
col: i,
row: j,
pSvg: svg,
rect: rect,
handleEvent: function (event) {
try {
// this line fails because `this` is the target, not the cell
var svgNS = this.pSvg.namespaceURI;
var line = document.createElementNS(svgNS, 'line');
line.setAttribute("x1",this.rect.getAttribute("x"))
line.setAttribute("y1",this.rect.getAttribute("y"))
line.setAttribute("x2",this.rect.getAttribute("x")*1+this.rect.getAttribute("width")*1)
line.setAttribute("y2",this.rect.getAttribute("y")*1+this.rect.getAttribute("height")*1)
line.setAttribute("stroke","red")
this.pSvg.appendChild(line);
document.getElementById("out").innerHTML="rect("+this.col+","+this.row+") was clicked"
}
catch (err) {
alert("handlClick err: " + err);
}
}
}
//add a click handler for the rect/cell
cell.rect.addEventListener("click", cell, false);
//(only seems to work the last time it is executed)
//save the cell object for later use
cells[i][j] = cell;
}
}
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
id="svgTTT" width="150" height="150" viewBox="0 0 300 300" >
<rect width="3" height="300" x="99" fill="#008d46" />
<rect width="3" height="300" x="199" fill="#000000" />
<rect width="300" height="3" y="99" fill="#008d46" />
<rect width="300" height="3" y="199" fill="#d2232c" />
</svg>
<div id="out"></div>
对于 EventHandlers,这是正确的解决方案,其他一切都是 hack!
1.缺少事件处理程序
使用 innerHTML
改变元素的内部结构将导致其所有子元素被删除,并且元素的 DOM 子树将通过重新解析 HTML 来重建内容。通过删除子元素,所有以前注册的事件侦听器都将丢失,并且在从 HTML 重建 DOM 时不会自动恢复。要规避此行为,最好避免 innerHTML
,如果可能,请改用直接 DOM 操作。你可以使用这样的东西来插入你的 <rect>
s:
// Use DOM manipulation instead of innerHTML
var rect = document.createElementNS(svg.namespaceURI, 'rect');
rect.setAttributeNS(null, "id", newId);
rect.setAttributeNS(null, "fill", "#00DD00");
rect.setAttributeNS(null, "width", "93");
rect.setAttributeNS(null, "height", "93");
rect.setAttributeNS(null, "x", x);
rect.setAttributeNS(null, "y", y);
svg.appendChild(rect);
2。 this
事件处理程序中的上下文
每当事件侦听器被调用时,this
将绑定到触发事件的元素。但是,在您的代码中,您不需要 this
,因为所有信息都可以通过传递给函数 .tttSetupSquares()
.
的参数 brd
获得
handleClick: function (event) {
try {
var svgNS = brd.namespaceURI;
var line = document.createElementNS(svgNS, 'line');
brd.appendChild(line);
}
catch (err) {
alert("handlClick err: " + err);
}
}
有关工作示例,请参阅以下代码段:
function getEl(s) { return document.getElementById(s); }
var svg; // get the TTT svg
var cells = new Array(3);
// execute after HTML has rendered
!(function () {
svg = getEl("svgTTT");
tttSetupSquares(svg);
alert("click-squares are setup.");
}());
// setup the click squares
function tttSetupSquares(brd) {
for (var i = 0; i < 3; i++) {
cells[i] = new Array(3);
for (var j = 0; j < 3; j++) {
var x = 3 + (i * 100);
var y = 3 + (j * 100);
var newId = "svgTTTsqr" + i.toString() + j.toString();
// Use DOM manipulation instead of innerHTML
var rect = document.createElementNS(svg.namespaceURI, 'rect');
rect.setAttributeNS(null, "id", newId);
rect.setAttributeNS(null, "fill", "#00DD00");
rect.setAttributeNS(null, "width", "93");
rect.setAttributeNS(null, "height", "93");
rect.setAttributeNS(null, "x", x);
rect.setAttributeNS(null, "y", y);
svg.appendChild(rect);
//make a cell object to contain all of this
var cell = {
col: i,
row: j,
pSvg: brd,
rect: rect,
handleClick: function (event) {
try {
//console.log(this);
var svgNS = brd.namespaceURI;
var line = document.createElementNS(svgNS, 'line');
line.setAttributeNS(null, "x1", this.x.baseVal.value);
line.setAttributeNS(null, "y1", this.y.baseVal.value);
line.setAttributeNS(null, "x2", this.x.baseVal.value + this.width.baseVal.value);
line.setAttributeNS(null, "y2", this.y.baseVal.value + this.height.baseVal.value);
brd.appendChild(line);
}
catch (err) {
alert("handlClick err: " + err);
}
}
}
//add a click handler for the rect/cell
cell.rect.addEventListener("click", cell.handleClick, false);
//save the cell object for later use
cells[i][j] = cell;
}
}
}
line {
stroke: red;
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
id="svgTTT" width="150" height="150" viewBox="0 0 300 300" >
<rect width="3" height="300" x="99" fill="#008d46" />
<rect width="3" height="300" x="199" fill="#000000" />
<rect width="300" height="3" y="99" fill="#008d46" />
<rect width="300" height="3" y="199" fill="#d2232c" />
</svg>
我是一名经验丰富的程序员,但对网络编程有些陌生。我正在尝试使用 VS2010 学习 Javascript、HTML5 和 SVG,方法是编写一个使用 Javascript.
玩井字游戏的 HTML 页面我成功地将九个方块中的每一个都创建为 SVG <rect...>
元素,但是我在处理每个方块的点击事件处理程序时遇到了问题。
这是存在于 HTML 文件中的基本 SVG 元素:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
id="svgTTT" width="150" height="150" viewBox="0 0 300 300" >
<rect width="3" height="300" x="99" fill="#008d46" />
<rect width="3" height="300" x="199" fill="#000000" />
<rect width="300" height="3" y="99" fill="#008d46" />
<rect width="300" height="3" y="199" fill="#d2232c" />
</svg>
这些静态 <rect>
元素绘制了 TicTacToe 棋盘的交叉哈希线。九个棋盘方块是在从 windows 加载事件(下方)调用的 javascript 函数中创建的。
这是 javascript(在 HTML 正文的 <script>
元素中内嵌):
<script type="text/javascript">
function getEl(s) { return document.getElementById(s); }
var svg; // get the TTT svg
// execute after HTML has rendered
window.onload = function () {
svg = getEl("svgTTT");
tttSetupSquares(svg);
alert("click-squares are setup.");
}
var cells = new Array(3);
// setup the click squares
function tttSetupSquares(brd) {
for (var i = 0; i < 3; i++) {
cells[i] = new Array(3);
for (var j = 0; j < 3; j++) {
var x = 3 + (i * 100);
var y = 3 + (j * 100);
var newId = "svgTTTsqr" + i.toString() + j.toString();
// add in new rect with html
brd.innerHTML += "<rect id='"+newId+"' width='93' height='93' "
+ "fill='#00DD00' x='" + x.toString() + "' y ='" + y.toString() + "'"
+ " />";
//find it using the newId
var rect = document.getElementById(newId);
//make a cell object to contain all of this
var cell = {
col: i,
row: j,
pSvg: svg,
rect: rect,
handleClick: function (event) {
try {
// this line fails because `this` is the target, not the cell
var svgNS = this.pSvg.namespaceURI;
var line = document.createElementNS(svgNS, 'line');
this.pSvg.appendChild(line);
}
catch (err) {
alert("handlClick err: " + err);
}
}
}
//add a click handler for the rect/cell
cell.rect.addEventListener("click", cell.handleClick, false);
//(only seems to work the last time it is executed)
//save the cell object for later use
cells[i][j] = cell;
}
}
}
</script>
(我可以提供完整的页面源代码,但只有 HTML 个包含这些的元素。)
问题有两个:
只有最后一个
addEventListener
似乎有效。单击所有其他方块没有任何作用。单击最后一个方块 (svgTTTsqr22) 会 运行cell.handleClick
但会导致问题 2(如下)。 Chrome 开发人员工具 (F12) 显示所有<rect>
元素,但最后一个元素没有事件侦听器。当
cell.handleClick
执行 运行 时,它在第一行 (var svgNS = this.pSvg.namespaceURI;
) 上失败并出现类似“undefined object does没有名为 "namespaceURI" 的 属性 在 Devleoper Tools 中检查表明它失败了,因为this
没有设置为cell
对象,而是设置为 SVG<rect>
单击的元素。
所以我的问题是:
一个。我在这里做错了什么,
乙。 can/should 我是怎么做到的?
一些建议:
您可以考虑使用事件委托。如果你使用像 jQuery 或 Angular 或 React 这样的框架或库,它会自动为你进行事件委托。在单独的 DOM 元素上设置多个事件处理程序可能会影响性能。你可以做的是在包装元素上有一个 "click" 处理程序,并使用 event.target
属性 查看实际点击的元素。
svg.addEventListener("click", function (e) {
if (e.target.nodeName === "rect" && (/^svgTTTsqr/).test(e.target.id)) {
// Use a regexp on e.target.id to find your
// cell object in `cells`
}
});
正则表达式可能有点脏,所以也许您应该改用数据属性。
// Generating the HTML
brd.innerHTML += "<rect id='"+newId+"' data-i='" + i + "' data-j='" + j + "' "
// The event handler:
svg.addEventListener("click", function (e) {
if (e.target.nodeName === "rect" && (/^svgTTTsqr/).test(e.target.id)) {
var i = e.target.getAttribute("data-i");
var j = e.target.getAttribute("data-j");
var cell = cells[i][j];
cell.handleClick();
}
});
如果这样做,您还可以轻松地进行另一项性能调整,即首先生成整个 HTML 字符串,然后在一次操作中将其附加到 DOM,因为您不再必须将 HTML 插入 DOM 并在循环时添加事件侦听器。
关于你的问题,
1) 抱歉,帮不了你:( 需要设置一个可执行示例并四处寻找,阅读代码时想不出任何东西。我要去 post这个答案无论如何,希望上面解释的事件委托解决方案可以解决问题。
2) 被调用的原始函数显然将它们的 'this' 绑定到它们被调用的任何范围。调用者还可以显式设置 'this' 绑定到什么。解决方案是创建一个包装的新函数,以便 'this' 被强制成为你想要的任何东西。使用内置 function () {}.bind(cell)
它将 return 一个包装原始函数的新函数,并且在原始 this
中,无论上下文如何,函数 this
将始终设置为 cell
=43=]ed 由 bind
调用。
如上所述,"this" 的问题在于它绑定到一个上下文,而这并不总是您想要的上下文。这类问题有很多解决方案。从臭名昭著的 self=this
技巧到 .bind()
。对此也有很多答案,通常它可能是重复的。可以在这里找到一个很好的答案和一些后续阅读:
var self = this?
或此处:How to change the context of a function in javascript
或者在这里:http://ryanmorr.com/understanding-scope-and-context-in-javascript/
或此处:https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Operators/this
尽管您问题的真正答案非常具体。对于事件处理程序,"this" 问题有一个解决方案。您只需要实现一个 EventListener 接口。这听起来比实际更复杂。事实上这很容易。您的对象只需实现一个功能:.handleEvent
。当您将对象传递给 addEventListener() 函数时,会自动调用此函数。这样做的好处是,使用这种方法,"this" 的上下文将自动正确。无需破解或解决方法。知道一般情况下的解决方法当然很好,但是对于这种特定情况,.handleEvent
是解决方案。
这是一个完整的工作示例:
function getEl(s) { return document.getElementById(s); }
var svg; // get the TTT svg
// execute after HTML has rendered
window.onload = function () {
svg = getEl("svgTTT");
tttSetupSquares(svg);
//alert("click-squares are setup.");
}
var cells = new Array(3);
// setup the click squares
function tttSetupSquares(brd) {
for (var i = 0; i < 3; i++) {
cells[i] = new Array(3);
for (var j = 0; j < 3; j++) {
var x = 3 + (i * 100);
var y = 3 + (j * 100);
var rect= document.createElementNS("http://www.w3.org/2000/svg","rect")
rect.setAttribute("x",x);
rect.setAttribute("y",y);
rect.setAttribute("width",100);
rect.setAttribute("height",100);
rect.setAttribute("fill","grey")
brd.appendChild(rect)
var cell = {
col: i,
row: j,
pSvg: svg,
rect: rect,
handleEvent: function (event) {
try {
// this line fails because `this` is the target, not the cell
var svgNS = this.pSvg.namespaceURI;
var line = document.createElementNS(svgNS, 'line');
line.setAttribute("x1",this.rect.getAttribute("x"))
line.setAttribute("y1",this.rect.getAttribute("y"))
line.setAttribute("x2",this.rect.getAttribute("x")*1+this.rect.getAttribute("width")*1)
line.setAttribute("y2",this.rect.getAttribute("y")*1+this.rect.getAttribute("height")*1)
line.setAttribute("stroke","red")
this.pSvg.appendChild(line);
document.getElementById("out").innerHTML="rect("+this.col+","+this.row+") was clicked"
}
catch (err) {
alert("handlClick err: " + err);
}
}
}
//add a click handler for the rect/cell
cell.rect.addEventListener("click", cell, false);
//(only seems to work the last time it is executed)
//save the cell object for later use
cells[i][j] = cell;
}
}
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
id="svgTTT" width="150" height="150" viewBox="0 0 300 300" >
<rect width="3" height="300" x="99" fill="#008d46" />
<rect width="3" height="300" x="199" fill="#000000" />
<rect width="300" height="3" y="99" fill="#008d46" />
<rect width="300" height="3" y="199" fill="#d2232c" />
</svg>
<div id="out"></div>
对于 EventHandlers,这是正确的解决方案,其他一切都是 hack!
1.缺少事件处理程序
使用 innerHTML
改变元素的内部结构将导致其所有子元素被删除,并且元素的 DOM 子树将通过重新解析 HTML 来重建内容。通过删除子元素,所有以前注册的事件侦听器都将丢失,并且在从 HTML 重建 DOM 时不会自动恢复。要规避此行为,最好避免 innerHTML
,如果可能,请改用直接 DOM 操作。你可以使用这样的东西来插入你的 <rect>
s:
// Use DOM manipulation instead of innerHTML
var rect = document.createElementNS(svg.namespaceURI, 'rect');
rect.setAttributeNS(null, "id", newId);
rect.setAttributeNS(null, "fill", "#00DD00");
rect.setAttributeNS(null, "width", "93");
rect.setAttributeNS(null, "height", "93");
rect.setAttributeNS(null, "x", x);
rect.setAttributeNS(null, "y", y);
svg.appendChild(rect);
2。 this
事件处理程序中的上下文
每当事件侦听器被调用时,this
将绑定到触发事件的元素。但是,在您的代码中,您不需要 this
,因为所有信息都可以通过传递给函数 .tttSetupSquares()
.
brd
获得
handleClick: function (event) {
try {
var svgNS = brd.namespaceURI;
var line = document.createElementNS(svgNS, 'line');
brd.appendChild(line);
}
catch (err) {
alert("handlClick err: " + err);
}
}
有关工作示例,请参阅以下代码段:
function getEl(s) { return document.getElementById(s); }
var svg; // get the TTT svg
var cells = new Array(3);
// execute after HTML has rendered
!(function () {
svg = getEl("svgTTT");
tttSetupSquares(svg);
alert("click-squares are setup.");
}());
// setup the click squares
function tttSetupSquares(brd) {
for (var i = 0; i < 3; i++) {
cells[i] = new Array(3);
for (var j = 0; j < 3; j++) {
var x = 3 + (i * 100);
var y = 3 + (j * 100);
var newId = "svgTTTsqr" + i.toString() + j.toString();
// Use DOM manipulation instead of innerHTML
var rect = document.createElementNS(svg.namespaceURI, 'rect');
rect.setAttributeNS(null, "id", newId);
rect.setAttributeNS(null, "fill", "#00DD00");
rect.setAttributeNS(null, "width", "93");
rect.setAttributeNS(null, "height", "93");
rect.setAttributeNS(null, "x", x);
rect.setAttributeNS(null, "y", y);
svg.appendChild(rect);
//make a cell object to contain all of this
var cell = {
col: i,
row: j,
pSvg: brd,
rect: rect,
handleClick: function (event) {
try {
//console.log(this);
var svgNS = brd.namespaceURI;
var line = document.createElementNS(svgNS, 'line');
line.setAttributeNS(null, "x1", this.x.baseVal.value);
line.setAttributeNS(null, "y1", this.y.baseVal.value);
line.setAttributeNS(null, "x2", this.x.baseVal.value + this.width.baseVal.value);
line.setAttributeNS(null, "y2", this.y.baseVal.value + this.height.baseVal.value);
brd.appendChild(line);
}
catch (err) {
alert("handlClick err: " + err);
}
}
}
//add a click handler for the rect/cell
cell.rect.addEventListener("click", cell.handleClick, false);
//save the cell object for later use
cells[i][j] = cell;
}
}
}
line {
stroke: red;
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
id="svgTTT" width="150" height="150" viewBox="0 0 300 300" >
<rect width="3" height="300" x="99" fill="#008d46" />
<rect width="3" height="300" x="199" fill="#000000" />
<rect width="300" height="3" y="99" fill="#008d46" />
<rect width="300" height="3" y="199" fill="#d2232c" />
</svg>