我对这种类型的功能不是很熟悉(MutationObserver甚至更多)。 我以为可以通过设置setTimeout来保存,但是不,它在this._Resizing方法上循环运行,我不知道如何理解或解决此问题。
这个想法是即使窗口更改大小,也要在SVG上保持相同的显示比例,即使是通过脚本完成也是如此。首先更改窗口大小(大小为50%,然后单击按钮以切换大小100) / 200像素)
如果我使用JS对象,那么正是因为它是对象编程的原理之一,所以它能够被乘以它。
此处的代码仅用于说明我的问题,而此按钮仅用于说明它:这是示例的原理。
在我的真实界面中没有按钮,但是其他元素可以更改大小,并且可能会干扰不同元素SVG的剩余大小。
这是犯罪的对象:
const vBxEnum = Object.freeze({ "left": 0, "top": 1, "width": 2, "height": 3 });
class SVG_kit {
constructor(zID_SVG) {
this.$_SVG = document.getElementById(zID_SVG);
this._viewBox = this.$_SVG.getAttribute("viewBox").split(' ').map(v => +v);
this.svg_rect = this.$_SVG.getBoundingClientRect();
this._scale = this._viewBox[vBxEnum.width] / this.svg_rect.width;
// do same ratio for height
this._viewBox[vBxEnum.height] = this.svg_rect.height * this._scale;
this.$_SVG.setAttribute("viewBox", this._viewBox.join(' '));
this.TimeOutResize = 0;
this.count = 0; // just to see resize infinite loop in action !
window.onresize = e => this._Resizing();
let observer4Size = new MutationObserver(m => this._Resizing());
observer4Size.observe(this.$_SVG, { attributes: true });
}
_Resizing() {
this.TimeOutResize = setTimeout(function (thisObj) {
console.log('resiz', ++thisObj.count); // resize never stop !
thisObj.svg_rect = thisObj.$_SVG.getBoundingClientRect();
thisObj._viewBox[vBxEnum.width] = thisObj.svg_rect.width * thisObj._scale;
thisObj._viewBox[vBxEnum.height] = thisObj.svg_rect.height * thisObj._scale;
thisObj.$_SVG.setAttribute("viewBox", thisObj._viewBox.join(' '));
clearTimeout(thisObj.TimeOutResize);
}, 100, this);
}
} /// SVG_kit
var
svg_SZ = '100px',
svg_E1 = document.getElementById('First-SVG'),
Sz_Button = document.getElementById("Bt-ChgSize");
var First_SVG = new SVG_kit('First-SVG');
Sz_Button.onclick = function ()
{
svg_E1.style.width = svg_SZ;
svg_SZ = (svg_SZ === '100px') ? '200px' : '100px';
}
svg {
margin: 1em;
height: 200px;
width: 50%;
box-shadow: 0 0 1em #CCC;
background-color: #8ed1d6;
}
<button id='Bt-ChgSize'>change Size (100px / 200px)</button>
<svg id="First-SVG" viewBox="0 0 1820 480">
<circle fill="#F7941E" stroke="#231F20" stroke-width="10" cx="250" cy="250" r="200" opacity="0.6" />
</svg>
答案 0 :(得分:2)
您将用此代码陷入困境。
$.ajax({
url: "/api/Customers/UpdateCustomer",
type: "PUT",
data: { vm },
success: function () {
Location("customers/Index");
//button.parents("tr").remove();
}
});
观察者DOM元素及其所有子元素,以了解是否要移动/添加/删除元素或更改属性。
在初始化时,您正在使用一个容器来监视SVG容器,并检查其属性。进行任何更改时,您都会致电MutationObserver
。
然而,在Resizing()
内的这一行:
Resizing
您正在更改SVG容器的属性,该属性然后再次调用 thisObj.$_SVG.setAttribute("viewBox", thisObj._viewBox.join(' '));
,并重复该循环。
老实说,为此Resizing
既多余又不必要。您可以单独绑定一个MutationObserver
并从那里处理事件(您确实这样做了),但是,由于您确实想要一个,因此下面的代码可以满足您的要求:>
onResize
const vBxEnum = Object.freeze({ "left": 0, "top": 1, "width": 2, "height": 3 });
class SVG_kit {
constructor(zID_SVG) {
this.$_SVG = document.getElementById(zID_SVG);
this._viewBox = this.$_SVG.getAttribute("viewBox").split(' ').map(v => +v);
this.svg_rect = this.$_SVG.getBoundingClientRect();
this._scale = this._viewBox[vBxEnum.width] / this.svg_rect.width;
// do same ratio for height
this._viewBox[vBxEnum.height] = this.svg_rect.height * this._scale;
this.$_SVG.setAttribute("viewBox", this._viewBox.join(' '));
this.TimeOutResize = 0;
this.count = 0; // just to see resize infinite loop in action !
this._width = null;
window.onresize = e => this._Resizing();
let observer4Size = new MutationObserver(this._checkStyleChange.bind(this));
observer4Size.observe(this.$_SVG, { attributes: true });
}
_checkStyleChange(mutations) {
let callResizing = false;
var element = this.$_SVG;
var oldWidth = this._width;
mutations.forEach(function(mutation) {
if (mutation.target === element && mutation.attributeName === 'style') {
if (oldWidth !== element.style.width) {
oldWidth = element.style.width;
callResizing = true;
}
}
});
if (callResizing) this._Resizing();
}
_Resizing() {
console.log("Resizing");
let thisObj = this;
thisObj.svg_rect = thisObj.$_SVG.getBoundingClientRect();
thisObj._viewBox[vBxEnum.width] = thisObj.svg_rect.width * thisObj._scale;
thisObj._viewBox[vBxEnum.height] = thisObj.svg_rect.height * thisObj._scale;
thisObj.$_SVG.setAttribute("viewBox", thisObj._viewBox.join(' '));
clearTimeout(thisObj.TimeOutResize);
}
} /// SVG_kit
var
svg_SZ = '100px',
svg_E1 = document.getElementById('First-SVG'),
Sz_Button = document.getElementById("Bt-ChgSize");
var First_SVG = new SVG_kit('First-SVG');
Sz_Button.onclick = function ()
{
svg_E1.style.width = svg_SZ;
svg_SZ = (svg_SZ === '100px') ? '200px' : '100px';
// First_SVG._Resizing();
}
svg {
margin: 1em;
height: 200px;
width: 50%;
box-shadow: 0 0 1em #CCC;
background-color: #8ed1d6;
}